Problemas y soluciones populares de las entrevistas de back-end

Vivo en Tashkent, y cuando estaba en la universidad comencé a aprender Python para escribir bots. Los bots son pan uzbeko, todo se basa en ellos. Por ejemplo, nadie hace solicitudes para pedir comida, todo es solo en mensajería instantánea. 





Aprendí el idioma de artículos de Internet; simplemente tomé el marco y agregué más, miré dónde caían las cosas, resolví constantemente problemas con leetcode. Entonces escribí horriblemente, pero lo que fue, fue. Me encantó, pero cuanto más profundo fui, más molestas se volvieron la velocidad de ejecución, las limitaciones de concurrencia y la escritura dinámica.





Entonces decidí probar Go.






Go es simple, genial y muy solicitado 

Me atrajo su idea de la competencia liviana y me gustó el hecho de que no era necesario comprender el zoológico asincrónico que estaba en Python. Al principio escribí algo en Go para mí, observé cómo se comportaba el idioma. Luego, en el trabajo, decidimos probar un proyecto simple. Obtuvimos buenos resultados, tanto en términos de velocidad de desarrollo como de ejecución.





, Go , , — , , , , . , Go , , , .





: « — ». , . - , .





- . , — .





. , . , . , , — , 15 « -».





, . , , , .





, . , Go , — , .





, , — . , , . , , .






. ,

leetcode . 





, , . .





( , ) — . , . , .









package main

import (
	"fmt"
)

//        .
//   ,    
func intersection(a, b []int) []int {
	counter := make(map[int]int)
	var result []int

	for _, elem := range a {
		if _, ok := counter[elem]; !ok {
			counter[elem] = 1
		} else {
			counter[elem] += 1
		}
	}
	for _, elem := range b {
		if count, ok := counter[elem]; ok && count > 0 {
			counter[elem] -= 1	
			result = append(result, elem)
		}
	}
	return result
}

func main() {

	a := []int{23, 3, 1, 2}
	b := []int{6, 2, 4, 23}
	// [2, 23]
	fmt.Printf("%v\n", intersection(a, b))
	a = []int{1, 1, 1}
	b = []int{1, 1, 1, 1}
	// [1, 1, 1]
	fmt.Printf("%v\n", intersection(a, b))
}

      
      



, , Go. . , .





N .









package main

import (
	"fmt"
	"math/rand"
	"time"
)

func randNumsGenerator(n int) <-chan int {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))

	out := make(chan int)
	go func() {
		for i := 0; i < n; i++ {
			out <- r.Intn(n)
		}
		close(out)
	}()
	return out
}

func main() {
	for num := range randNumsGenerator(10) {
		fmt.Println(num)
	}
}
      
      



N

n chan int. , .





, :





for num := range joinChannels(a, b, c) {







       fmt.Println(num)







}







, , , , . 





, . , , .





, . , wait group. 









package main

import (
	"fmt"
	"sync"
)

func joinChannels(chs ...<-chan int) <-chan int {
	mergedCh := make(chan int)

	go func() {
		wg := &sync.WaitGroup{}

		wg.Add(len(chs))

		for _, ch := range chs {
			go func(ch <-chan int, wg *sync.WaitGroup) {
				defer wg.Done()
				for id := range ch {
					mergedCh <- id
				}
			}(ch, wg)
		}

		wg.Wait()
		close(mergedCh)
	}()

	return mergedCh
}

func main() {

	a := make(chan int)
	b := make(chan int)
	c := make(chan int)

	go func() {
		for _, num := range []int{1, 2, 3} {
			a <- num
		}
		close(a)
	}()

	go func() {
		for _, num := range []int{20, 10, 30} {
			b <- num
		}
		close(b)
	}()

	go func() {
		for _, num := range []int{300, 200, 100} {
			c <- num
		}
		close(c)
	}()

	for num := range joinChannels(a, b, c) {
		fmt.Println(num)
	}

}
      
      



. . , , - (, ) . 





, https://blog.golang.org/pipelines.





— . . . — , .









package main

import (
	"fmt"
)

func main() {
	naturals := make(chan int)
	squares := make(chan int)

	go func() {
		for x := 0; x <= 10; x++ {
			naturals <- x
		}
		close(naturals)
	}()

	go func() {
		for x := range naturals {
			squares <- x * x
		}
		close(squares)
	}()

	for x := range squares {
		fmt.Println(x)
	}
}
      
      



WorkerPool

, . 





— , . . , , .









package main

import (
	"fmt"
)

func worker(id int, f func(int) int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        results <- f(j)
    }
}

func main() {

    const numJobs = 5
    jobs := make(chan int, numJobs)
    results := make(chan int, numJobs)

    multiplier := func(x int) int {
	return x * 10
    }

    for w := 1; w <= 3; w++ {
        go worker(w,  multiplier, jobs, results)
    }

    for j := 1; j <= numJobs; j++ {
        jobs <- j
    }
    close(jobs)

    for i := 1; i <= numJobs; i++ {
        fmt.Println(<-results)
    }
}
      
      



waitGroup

. , .





, . . . , — . 









package main

import (
	"fmt"
)

type sema chan struct{}

func New(n int) sema {
	return make(sema, n)
}

func (s sema) Inc(k int) {
	for i := 0; i < k; i++ {
		s <- struct{}{}
	}
}

func (s sema) Dec(k int) {
	for i := 0; i < k; i++ {
		<-s
	}
}

func main() {
	numbers := []int{1, 2, 3, 4, 5}
	n := len(numbers)

	sem := New(n)

	for _, num := range numbers {
		go func(n int) {
			fmt.Println(n)
			sem.Inc(1)
		}(num)
	}

	sem.Dec(n)

}
      
      







, — Rebrain — Go. , .






Go

, , Go . — , . — , , . 





, , . 





Go — , , , .





Go . ( «» — Go), , , , , . — Java C#. , , , , , .





++. , , ++ . , — .





Go . — , , . - - , .






@alisher_m, Rebrain. , . , , .








All Articles