Popular Go Backend Interview Problems and Solutions

I live in Tashkent, and when I was at university I started learning Python in order to write bots. Bots are Uzbek bread, everything is built on them. For example, no one makes applications for ordering food, everything is only in instant messengers. 





I learned the language from articles from the Internet - I just took the frame and added further, looked where things fell, constantly solved problems with leetcode. I wrote awful then, but what was, it was. I liked it, but the deeper I went, the more annoying the execution speed, concurrency limitations, and dynamic typing became.





Then I decided to try Go.






Go is simple, cool and in demand 

I was attracted by their idea of ​​lightweight competition and liked the fact that you did not need to understand the asynchronous zoo that was in python. At first I wrote something in Go for myself, watched how the language behaves. Then at work, we decided to try one simple project. We got good results - both in terms of development speed and execution speed.





, 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