Analysis of Golang interview

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Recently in many places to see the golang of the face of the test, see a lot of people on the golang of the face of fear, but also to review the basis, I put the process of solving the problem summed down.

Interview questions

1. Write out the following code output.

package mainimport (    "fmt")func main() {    defer_call()}func defer_call() {    defer func() { fmt.Println("打印前") }()    defer func() { fmt.Println("打印中") }()    defer func() { fmt.Println("打印后") }()    panic("触发异常")}

Test centers:Defer execution order
Answer:
Defer is last-in- first-out .
Panic need to wait for defer to end before passing upward. When the panic panic occurs, it will be executed in the first order followed by defer, and then panic will be executed.

打印后打印中打印前panic: 触发异常

2. What's wrong with the following code, explain why.

type student struct {    Name string    Age  int}func pase_student() {    m := make(map[string]*student)    stus := []student{        {Name: "zhou", Age: 24},        {Name: "li", Age: 23},        {Name: "wang", Age: 22},    }    for _, stu := range stus {        m[stu.Name] = &stu    }}

Test Centers:foreach
Answer:
This kind of writing is often encountered by beginners, very dangerous! Like the Java foreach, it's a way to use replicas. So m[stu. Name]=&stu actually consistently points to the same pointer, and ultimately the value of the pointer is a copy of the value of the last struct that was traversed. Just like you want to modify the properties of a slice element:

for _, stu := range stus {    stu.Age = stu.Age+10}

is also not feasible. You can try printing it out:

func pase_student() {    m := make(map[string]*student)    stus := []student{        {Name: "zhou", Age: 24},        {Name: "li", Age: 23},        {Name: "wang", Age: 22},    }    // 错误写法    for _, stu := range stus {        m[stu.Name] = &stu    }    for k,v:=range m{        println(k,"=>",v.Name)    }    // 正确    for i:=0;i<len(stus);i++  {        m[stus[i].Name] = &stus[i]    }    for k,v:=range m{        println(k,"=>",v.Name)    }}

3. The following code will output what, and explain why

func main() {    runtime.GOMAXPROCS(1)    wg := sync.WaitGroup{}    wg.Add(20)    for i := 0; i < 10; i++ {        go func() {            fmt.Println("A: ", i)            wg.Done()        }()    }    for i := 0; i < 10; i++ {        go func(i int) {            fmt.Println("B: ", i)            wg.Done()        }(i)    }    wg.Wait()}

Test Center:Random and closure of Go execution
Answer:
No one knows what the order of printing will be after execution, so it can only be said to be random numbers. However A: , all outputs are output B: from the 0~9 output (in a variable order). The first go func in I is a variable of the external for, and the address does not change. After the traversal is complete, the final i=10. Therefore, when go func executes, the value of I is always 10.

The second go func in I is a function parameter, and an external for in I is exactly two variables. The tail (i) will take place a copy of the value, and go func internally points to the value copy address.

4. What does the following code output?

type People struct{}func (p *People) ShowA() {    fmt.Println("showA")    p.ShowB()}func (p *People) ShowB() {    fmt.Println("showB")}type Teacher struct {    People}func (t *Teacher) ShowB() {    fmt.Println("teacher showB")}func main() {    t := Teacher{}    t.ShowA()}

Test Center:combination inheritance of Go
Answer:
This is a combination of golang patterns that enable the inheritance of OOP. The combined type people contains methods that have been upgraded to a method of the teacher of this combination type (must be an anonymous field), but their method (ShowA ()) is called without a change in the recipient. At this point the people type does not know what type of combination it will be, and of course it cannot invoke the function of the unknown combinatorial teacher type when calling the method.

showAshowB

5. Does the following code trigger an exception? Please explain in detail

func main() {    runtime.GOMAXPROCS(1)    int_chan := make(chan int, 1)    string_chan := make(chan string, 1)    int_chan <- 1    string_chan <- "hello"    select {    case value := <-int_chan:        fmt.Println(value)    case value := <-string_chan:        panic(value)    }}

Test Centers:Select Randomness
Answer:
Select randomly selects one of the available generic to send and receive operations. So the code is a Ken trigger exception, or it may not. A single Chan will block if it is not buffered. However, a combination of select can be performed between multiple Chan. There is a three-point principle:

    • As long as a case can return in select, it is executed immediately.
    • If more than one case can return at the same time, the pseudo-random method extracts any one execution.
    • If there is not a case to return, you can execute the "default" block.

6. What does the following code output?

func calc(index string, a, b int) int {    ret := a + b    fmt.Println(index, a, b, ret)    return ret}func main() {    a := 1    b := 2    defer calc("1", a, calc("10", a, b))    a = 0    defer calc("2", a, calc("20", a, b))    b = 1}

Test centers:Defer execution order
Answer:
This question is similar to the 1th question needs to notice that the defer execution order and the value pass Index:1 certainly is the last execution, but the index:1 's third parameter is a function, therefore the first call to the Calc ("Ten", the five) ==>10,1,2,3 executes Index:2, As before, you need to call Calc ("0,2") ==>20,0,2,2 execution to B=1, Index:2==>calc ("2", 0,2) ==>2,0,2,2 finally execute index:1==> Calc ("1", 1,3) ==>1,1,3,4

10 1 2 320 0 2 22 0 2 21 1 3 4

7. Please write down the following input:

func main() {    s := make([]int, 5)    s = append(s, 1, 2, 3)    fmt.Println(s)}

Test centers: Makedefaults and append
Answer:
Make initialization is the default value of Oh, here the default value is 0

[0 0 0 0 0 1 2 3]

Let's try it instead:

s := make([]int, 0)s = append(s, 1, 2, 3)fmt.Println(s)//[1 2 3]

8. What is the problem with the following code?

type UserAges struct {ages map[string]intsync.Mutex}func (ua *UserAges) Add(name string, age int) {ua.Lock()defer ua.Unlock()ua.ages[name] = age}func (ua *UserAges) Get(name string) int {if age, ok := ua.ages[name]; ok {return age}return -1}

Test centers:Map Thread Safety
Answer:
May appear fatal error: concurrent map read and map write . Modify it to see the effect

func (ua *UserAges) Get(name string) int {    ua.Lock()    defer ua.Unlock()    if age, ok := ua.ages[name]; ok {        return age    }    return -1}

9. What is the problem with the following iteration?

func (set *threadSafeSet) Iter() <-chan interface{} {ch := make(chan interface{})go func() {set.RLock()for elem := range set.s {ch <- elem}close(ch)set.RUnlock()}()return ch}

Test centers:Chan Cache Pool
Answer:
Seeing this problem, I also wonder where the intention of the subject is. Chan?sync. Rwmutex?go?chan cache pool? So I can only read one more time and start with the iteration. Since it is an iteration, the SET.S will be required to traverse it all at once. But Chan is cached, which means that this write is blocked. Let's get the code back to work and see how it works.

package mainimport (    "sync"    "fmt")//下面的迭代会有什么问题?type threadSafeSet struct {    sync.RWMutex    s []interface{}}func (set *threadSafeSet) Iter() <-chan interface{} {    // ch := make(chan interface{}) // 解除注释看看!    ch := make(chan interface{},len(set.s))    go func() {        set.RLock()        for elem,value := range set.s {            ch <- elem            println("Iter:",elem,value)        }        close(ch)        set.RUnlock()    }()    return ch}func main()  {    th:=threadSafeSet{        s:[]interface{}{"1","2"},    }    v:=<-th.Iter()    fmt.Sprintf("%s%v","ch",v)}

10. Can the following code be compiled in the past? Why?

package mainimport ("fmt")type People interface {Speak(string) string}type Stduent struct{}func (stu *Stduent) Speak(think string) (talk string) {if think == "bitch" {talk = "You are a good boy"} else {talk = "hi"}return}func main() {var peo People = Stduent{}think := "bitch"fmt.Println(peo.Speak(think))}

Test Center:Method Set of Golang
Answer:
Compilation does not pass! Did it wrong!? Shows you have some questions about the Golang method set. Bottom line: The method set of Golang only affects interface implementations and method expression conversions, regardless of how the method is invoked through an instance or pointer.

11. The following code prints out what content, say why.

package mainimport ("fmt")type People interface {Show()}type Student struct{}func (stu *Student) Show() {}func live() People {var stu *Studentreturn stu}func main() {if live() == nil {fmt.Println("AAAAAAA")} else {fmt.Println("BBBBBBB")}}

Test Center:interface Internal Structure
Answer:
It's a classic question! This test center is the interface internal structure that many people neglect. The interface in Go is divided into two kinds of interfaces that are empty, like this:

var in interface{}

Another such as the topic:

type People interface {    Show()}

Their underlying structure is as follows:

  type eface struct {//NULL interface _type *_type//Type Information data unsafe. Pointer//Pointer to data (special pointer type unsafe in the Go language.) Pointer similar to void* in C language)}type iface struct {//interface with Method tab *ITAB//Store type information and a collection of structure implementation methods data unsafe. Pointer//Pointer to data (special pointer type unsafe in the Go language.)       Pointer similar to void* in C language)}type _type struct {size UIntPtr//Type size ptrdata uintptr//prefix hold all pointers memory size hash UInt32//Data hash value Tflag Tflag align uint8//alignment fieldalign uint8//Alignment kind UIn when embedding structure T8//kind Some enumeration value kind equals 0 is an invalid ALG *typealg//function pointer array, all methods of type implementation Gcdata *byte str Nameoff ptrtoth    is Typeoff}type itab struct {Inter *interfacetype//interface type _type *_type//struct type link *itab bad Int32 inhash int32 fun [1]uintptr//Variable Size method collection}  

It can be seen that iface more than eface in the middle of a layer of itab structure. Itab stores _type information and []fun method set, from the above structure we can draw, because data points to nil does not mean that interface is nil, so the return value is not empty, here the fun (method set) defines the interface of the receive rule, During compilation, you need to verify that the interface results are implemented:

BBBBBBB
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.