Najlepsze pytania i odpowiedzi na rozmowę dla programisty Go/Golang

Rozmowy rekrutacyjne to stres zarówno dla pracodawcy, jak i dla kandydata. Jedyną rozsądną decyzją jest więc wcześniejsze przygotowanie się do spotkania — zwłaszcza że pytania zadawane na różnych poziomach doświadczenia powinny się różnić.

Niezależnie od tego, czy przygotowujesz się do prowadzenia rozmowy o Go, czy chcesz pokazać się jako programista na czasie — ta lista jest dla Ciebie. Dziś pomożemy Ci zebrać listę ciekawych pytań (po 10 na każdy poziom doświadczenia), które zadasz przyszłym programistom.

Te pytania i odpowiedzi przydadzą się obu stronom rozmowy rekrutacyjnej.

Pytania rekrutacyjne dla juniora Go/Golang

01

Czym jest język programowania Go?

Go to język programowania o otwartym źródle stworzony przez Google. Znany jest też jako Golang. Ten język jest przeznaczony przede wszystkim do programowania systemowego.

02

Dlaczego warto używać języka Go?

Ponieważ Go jest językiem o otwartym źródle, bardzo łatwo tworzy się w nim proste, niezawodne i wydajne oprogramowanie.

03

Kto jest uznawany za ojca języka Go?

Język Go stworzyli Robert Griesemer, Rob Pike i Ken Thompson. Powstał w Google Inc. w 2009 roku.

04

Czym są pakiety w programie w Go?

Programy w Go składają się z pakietów. Program uruchamia się w pakiecie main. Ten program używa pakietów o ścieżkach importu „fmt” i „math / rand”.

05

Czy Go wspiera programowanie ogólnego przeznaczenia?

Język Go wspiera programowanie uniwersalne.

06

Czy Go rozróżnia wielkość liter?

Tak! Go rozróżnia wielkość liter.

07

Czym jest literał łańcuchowy w Go?

Literały łańcuchowe określają stałą łańcuchową powstałą przez połączenie ciągu znaków.

Są dwa rodzaje literałów łańcuchowych:

  • Surowe literały łańcuchowe: wartością surowych literałów łańcuchowych jest ciąg znaków między odwrotnymi apostrofami. "Jego wartość podaje się jako literał łańcuchowy złożony z ciągłego znaku między cudzysłowami.
  • Interpretowane literały łańcuchowe: zapisywane w podwójnych cudzysłowach "". Wartość literału podaje się jako tekst między cudzysłowami i nie może on zawierać znaków nowej linii.

08

Czym jest obszar roboczy w Go?

Obszar roboczy zawiera kod w Go. To hierarchia katalogów z trzema katalogami w korzeniu.

  • Katalog „src” zawiera pliki źródłowe GO uporządkowane w pakiety.
  • Katalog „pkg” zawiera obiekty pakietów.
  • Katalog „bin” zawiera polecenia wykonywalne

09

Czym jest zmienna środowiskowa GOPATH w Go?

Zmienna środowiskowa GOPATH wskazuje lokalizację obszaru roboczego. Musisz ją ustawić, kiedy piszesz kod w Go.

10

Co jest nie tak z poniższym fragmentem kodu?

type Orange struct {  Quantity int }

func (o *Orange) Increase(n int) { o.Quantity += n }

func (o *Orange) Decrease(n int) { o.Quantity -= n }

func (o *Orange) String() string { return fmt.Sprintf("%v", o.Quantity) }

func main() { var orange Orange  orange.Increase(10)   orange.Decrease(5)  fmt.Println(orange) }

To podchwytliwe pytanie, bo można pomyśleć, że chodzi o błędne ustawienie pola Quantity — ale zostanie ono ustawione na 5, zgodnie z oczekiwaniami. Prawdziwy problem, który łatwo przeoczyć, polega na tym, że metoda String() implementująca interfejs fmt.Stringer() nie zostanie wywołana przy wypisywaniu obiektu orange funkcją fmt.Println(), ponieważ String() nie jest zdefiniowana dla wartości, a jedynie dla wskaźnika:

var orange Orange  orange.Increase(10)  orange.Decrease(5)  fmt.Println(orange)

// Output: {5}

orange := &Orange{}  orange.Increase(10)  orange.Decrease(5)  fmt.Println(orange)

// Output: 5

To subtelne pytanie, ale poprawka jest prosta. Musisz nadpisać metodę String() dla wartości zamiast dla wskaźnika — wtedy zadziała zarówno dla wskaźników, jak i dla wartości:

func (o Orange) String() string { return fmt.Sprintf("%v", o.Quantity) }

Pytania rekrutacyjne dla mida Go/Golang

01

Jakie są zalety / korzyści języka Go?

Zalety / korzyści języka Go:

  • Go jest szybki i bardzo szybko się kompiluje.
  • Utrzymuje współbieżność na poziomie języka.
  • Ma odśmiecanie pamięci.
  • Obsługuje różne mechanizmy bezpieczeństwa i funkcje programowania równoległego w stylu CSP.
  • Łańcuchy znaków i mapy są wbudowane w język.
  • W tym języku funkcje są obiektami pierwszej klasy.

02

Jakie wsparcie jest wbudowane w Go?

Lista wbudowanego wsparcia w Go:

  • Kontenery: container / list, container / heap
  • Serwer WWW: net / http
  • Kryptografia: Crypto / md5, crypto / sha1
  • Kompresja: compression / gzip
  • Bazy danych: database / sql

03

Czym jest goroutine w języku Go?

Goroutine to funkcja, która zwykle działa współbieżnie z innymi funkcjami. Jeśli chcesz zatrzymać goroutine, przekazujesz do niej kanał sygnałowy, przez który wysyłasz wartość, gdy chcesz ją zatrzymać.

Goroutine regularnie odpytuje ten kanał i kończy działanie, gdy tylko wykryje sygnał.

Quit : = make (chan bool)  

go func ( ) {  

for  {  

select {  

case <- quit:  

return  

default  

// do other stuff  

}  

}  

}()  

// Do stuff  

// Quit goroutine  

Quit <- true  

04

Jak zapisać wiele linii w Go?

Żeby zapisać wiele łańcuchów w Go, trzeba użyć surowego literału łańcuchowego, w którym łańcuch jest ograniczony odwrotnymi apostrofami.

05

Jak używa się instrukcji break w języku Go?

Instrukcja break służy do zakończenia pętli for lub instrukcji switch i przeniesienia wykonania do instrukcji następującej bezpośrednio po pętli for lub switchu.

06

Jak używa się instrukcji continue w języku Go?

Instrukcja continue pozwala pominąć resztę ciała pętli i natychmiast ponownie sprawdzić warunek przed kolejnym przebiegiem.

07

Jak używa się instrukcji goto w języku Go?

Instrukcja goto służy do przekazania sterowania do instrukcji oznaczonej etykietą.

08

Wyjaśnij składnię pętli for.

Składnia pętli for w języku Go wygląda tak:

for [condition |  ( init; condition; increment ) | Range]  

{  

   statement(s);  

09

Napisz składnię tworzenia funkcji w języku Go?

Składnia tworzenia funkcji w Go wygląda tak:

func function_name( [parameter list] ) [return_types]  

{  

   body of the function  

}  

10

Wyjaśnij deklarację zmiennej o typie statycznym w języku Go?

Deklaracja zmiennej o typie statycznym służy temu, żeby kompilator miał jedną zmienną o danym typie i nazwie i nie musiał znać wszystkich szczegółów tej zmiennej do dalszego przetwarzania. Deklaracja zmiennej ma znaczenie tylko na etapie kompilacji — kompilator potrzebuje faktycznej deklaracji w momencie linkowania programu.

Pytania rekrutacyjne dla seniora Go/Golang

01

Jak zamienić dwie wartości miejscami? Podaj przykłady.

Dwie wartości zamienia się miejscami tak prosto:

a, b = b, a

Żeby zamienić miejscami trzy wartości, piszemy:

a, b, c = b, c, a

Operacja zamiany w Go jest wolna od efektów ubocznych. Przypisywane wartości są gwarantowanie zapisywane w zmiennych tymczasowych, zanim zacznie się właściwe przypisanie, więc kolejność przypisań nie ma znaczenia. Wynik operacji: a: = 1; b: = 2; a, b, a = b, a, b to nadal a = 2 i b = 1, bez ryzyka zmiany wartości a na nowo przypisaną. W wielu implementacjach algorytmów warto na tym polegać.

Na przykład funkcja, która odwraca slice liczb całkowitych:

func reverse(s []int) {

        for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {

                s[i], s[j] = s[j], s[i]

        }

}

func main() {

a := []int{1, 2, 3}

reverse(a)

fmt.Println(a)

// Output: [3 2 1]

}

02

Jak skopiować slice, mapę i interfejs?

Slice kopiujesz wbudowaną funkcją copy ():

a := []int{1, 2}; b := []int{3, 4}; check := a;  copy(a, b); fmt.Println(a, b, check)

// Output: [3 4] [3 4] [3 4]

Tutaj zmienna check służy do przechowania referencji do pierwotnego opisu slice'a, żeby upewnić się, że rzeczywiście został skopiowany.

W kolejnym przykładzie operacja nie kopiuje natomiast zawartości slice'a, a jedynie jego opis:

a := []int{1, 2}; b := []int{3, 4}; check := a;  a = b; fmt.Println(a, b, check)

// Output: [3 4] [3 4] [1 2]

Mapę kopiujesz, przechodząc po jej kluczach. Tak, niestety to najprostszy sposób na skopiowanie mapy w Go:

a := map[string]bool{"A": true, "B": true};  b := make(map[string]bool)

for key, value := range a { b[key] = value }

W poniższym przykładzie kopiowany jest tylko opis mapy:

a := map[string]bool{"A": true, "B": true}; b := map[string]bool{"C": true, "D": true}; check := a

a = b; fmt.Println(a, b, check)

// Output: map[C:true D:true] map[C:true D:true] map[A:true B:true]

Go nie ma wbudowanego mechanizmu kopiowania interfejsu. Nie, funkcja reflect.DeepCopy() nie istnieje.

03

Jak porównać dwie struktury? A dwa interfejsy? Podaj przykłady.

Dwie struktury możesz porównać operatorem ==, tak jak inne proste typy. Upewnij się tylko, że nie zawierają slice'ów, map ani funkcji — w takim wypadku kod się nie skompiluje.

type Foo struct { A int

B string

C interface{} }

a := Foo{A: 1, B: "one", C: "two"}

b := Foo{A: 1, B: "one", C: "two"}

println(a == b)

// Output: true

type Bar struct { A []int }

a := Bar{A: []int{1}}; b := Bar{A: []int{1}}

println(a == b)

// Output: invalid operation: a == b (struct containing []int cannot be compared)

Dwa interfejsy możesz porównać operatorem ==, jeśli typy pod spodem są „proste” i identyczne. W przeciwnym razie kod wywoła panikę w czasie działania:

var a interface{};  var b interface{}

a = 10;  b = 10

println(a == b)

// Output: true

a = []int{1};  b = []int{2}

println(a == b)

// Output: panic: runtime error: comparing uncomparable type []int

Zarówno struktury, jak i interfejsy zawierające mapy i slice'y (ale nie funkcje) można porównywać funkcją reflect.DeepEqual():

var a interface{}; var b interface{}

a = []int{1}; b = []int{1}

println(reflect.DeepEqual(a, b))

// Output: true

a = map[string]string{"A": "B"}

b = map[string]string{"A": "B"}

println(reflect.DeepEqual(a, b))

// Output: true

temp := func() {}; a = temp; b = temp

println(reflect.DeepEqual(a, b))

// Output: false

Pakiet bytes ma przydatne funkcje pomocnicze do porównywania slice'ów bajtów: bytes.Equal(), bytes.Compare() i bytes.EqualFold(). Ta ostatnia służy do porównywania tekstu bez rozróżniania wielkości liter i jest znacznie szybsza niż reflection.DeepEqual().

04

Czym jest składnia w języku Go?

Składnię języka GO opisuje się w rozszerzonej notacji Backusa-Naura (EBNF):

  1. Production = production_name "=" [Expression]
  2. Expression = Alternative {"l" Alternative}
  3. Alternative = Term {Term}
  4. Term = Production_name l token [token "?"] L Group l Option l Repeat
  5. Group = "(" "Expression") "
  6. Option = "[" Expression ""] "
  7. Repetition = "{" Expression "}"

05

Czym są interfejsy w Go?

W Go interfejsy są sposobem na zdefiniowanie zachowania obiektu. Interfejs tworzy się słowem „type”, po którym następuje nazwa i słowo kluczowe interface. Interfejs definiują dwie rzeczy.

  1. Zestaw metod.
  2. Nazywany również typem.

06

Czym jest asercja typu w Go? Co robi?

Asercja typu bierze wartość interfejsu i pobiera z niej wartość wskazanego, jawnego typu.

Konwersja typów służy w Golangu do zamiany typów różniących się od siebie.

07

Jakie metody są w języku Go?

W języku Go istnieje kilka różnych rodzajów funkcji zwanych metodami. W składni deklaracji metody „getter” oznacza kontener funkcji. Ten odbiornik pozwala wywołać funkcję za pomocą operatora „.”.

08

Jak sprawdzić typ zmiennej w czasie działania programu w języku Go?

Język Go ma specjalny rodzaj instrukcji switch do sprawdzania typu zmiennej w czasie działania programu. Nazywa się go type switch.

09

Czy zaleca się używanie zmiennych globalnych w programie korzystającym z goroutine?

Zmienne globalne nie są zalecane, ponieważ może do nich sięgać wiele goroutine (wątków) jednocześnie, co łatwo prowadzi do nieoczekiwanych zachowań i przypadkowych wyników.

10

Co wiesz o programowaniu modularnym?

Programowanie modularne to sposób podziału programu na podprogramy (moduły / funkcje) dla maksymalnej wydajności.

Definiowanie bardziej ogólnych funkcji ułatwia ich ponowne wykorzystanie — tak jak w przypadku wbudowanych funkcji bibliotecznych.

home-05
Rekrutujesz programistów Go/Golang?
Mamy ludzi, których szukasz!
Skontaktuj się
Szukasz sprawdzonych programistów Go do swojego zespołu?

W naszej sieci talentów są setki sprawdzonych w boju ekspertów od tworzenia oprogramowania.

Jesteś programistą Go/Golang i szukasz świetnych projektów? Dołącz jako specjalista