Gopher coding in the interview

Source: Internet
Author: User

Since the beginning of the second half of April, several companies have been interviewed by Golang. Each interview, the focus will be different, some will directly to come over a question, and then solve the problem, the side tells their own ideas, and then the interviewer according to your ideas and communication with you, and some, let tell their recent projects, encountered difficulties, how to solve the problem of their own ideas, and coincidentally, such an interview , you need to demonstrate coding capabilities. This article on the recent interview encountered in each of the programming problems, divided into three steps: Description of the problem, the idea of solving problems, practical programming.

1 alternate printing of numbers and letters

1.1 Problem Description

Use two goroutine alternating print sequences, one to goroutinue print the numbers, and one goroutine to print the letters, with the final effect as follows 12ab34cd56ef78gh910ij.

1.2 Ideas for solving problems

The problem is simple to use channel to control the progress of the print. Using two channel , to control the print sequence of numbers and letters, digital printing after the completion of the letter channel printed by notification letters, the letter after the completion of printing to inform the digital printing, and then the cycle of work.

1.3 Actual Code

runtime.GOMAXPROCS(runtime.NumCPU())chan_n := make(chan bool)chan_c := make(chan bool, 1)done := make(chan struct{})go func() {  for i := 1; i < 11; i += 2 {    <-chan_c    fmt.Print(i)    fmt.Print(i + 1)    chan_n <- true  }}()go func() {  char_seq := []string{"A","B","C","D","E","F","G","H","I","J","K"}  for i := 0; i < 10; i += 2 {    <-chan_n    fmt.Print(char_seq[i])    fmt.Print(char_seq[i+1])    chan_c <- true  }  done <- struct{}{}}()chan_c <- true<-done

Code Execution Results:

12AB34CD56EF78GH910IJ

After reading the above code, is there some doubts, why chan_c need to cache, and chan_n do not need it?
When two printing goroutine infinite alternating run, no cache is OK, but it is obvious that the above example is not, print the number of the goroutine first exit, there is no way goroutine to read the chan_c content, and the printing of the letter goroutine will be blocked chan_c <- true , which leads to deadlock.

2 Random Draw

2.1 Problem Description

User random draw, the data structure is as follows:

// map中,key代表名称,value代表成交单数var users map[string]int64 = map[string]int64{  "a": 10,  "b": 6,  "c": 3,  "d": 12,  "f": 1,}

2.2 Solution Ideas

mapchoose random users from the, get this coding problem, a little confused, but carefully think, just focus on the user's interval, change the data structure that is solving. Turn map into array , think more simple, the original problem becomes from 0 to n-1 to choose a number, the number corresponding to the user is the winning user.

2.3 Actual Code

package mainimport (  "fmt"  "math/rand"  "time")func GetAwardUserName(users map[string]int64) (name string) {  sizeOfUsers := len(users)  award_index := rand.Intn(sizeOfUsers)  var index int  for u_name, _ := range users {    if index == award_index {      name = u_name      return    }    index += 1  }  return}func main() {  var users map[string]int64 = map[string]int64{    "a": 10,    "b": 6,    "c": 3,    "d": 12,    "e": 20,    "f": 1,  }  rand.Seed(time.Now().Unix())  award_stat := make(map[string]int64)  for i := 0; i < 1000; i += 1 {    name := GetAwardUserName(users)    if count, ok := award_stat[name]; ok {      award_stat[name] = count + 1    } else {      award_stat[name] = 1    }  }  for name, count := range award_stat {    fmt.Printf("user: %s, award count: %d\n", name, count)  }  return}

Code Execution Results:

user: f, award count: 178user: d, award count: 152user: b, award count: 159user: e, award count: 182user: c, award count: 170user: a, award count: 159

3 Weight Draw

3.1 Problem Description

The data structure is consistent with the above, only the problem changes, need more users of the singular to draw, the more users into a single, the higher the probability of winning, the structure is as follows:

// map中,key代表名称,value代表成交单数var users map[string]int64 = map[string]int64{  "a": 10,  "b": 6,  "c": 3,  "d": 12,  "f": 1,}

3.2 Solution Ideas

This problem is the extension of the previous question, add the number of orders into, as a weight to draw for the user. This problem and the above question so similar, can put the above problem, understand all the user weights are the same lottery, and this question is the weight of different lottery. To solve this problem, still is to think of the map conversion array, the weight of each user, from front to back stitching to the axis, the beginning of the line to the end of the instant winning interval, and randomly grumble to the user's interval, the user is the winning user.

3.3 Actual Code

Package Mainimport ("FMT" "Math/rand" "Time") Func Getawardusername (Users Map[string]int64) (name string) {type A_use R struct {Name string Offset int64 Num Int64} A_user_arr: = make ([]*a_user, 0) var sum_num int64 for N Ame, num: = Range users {a_user: = &a_user{name:name, Offset:sum_num, Num:num,} A_u Ser_arr = Append (A_user_arr, a_user) sum_num + = num} award_num: = Rand. Int63n (sum_num) for index, _: = Range A_user_arr {a_user: = A_user_arr[index] If a_user. Offset+a_user. Num > Award_num {name = A_user. Name return}} Return}func main () {var users map[string]int64 = map[string]int64{"A": Ten, "B": 5, " C ":" D ": +," E ": Ten," F ": +," Rand ". Seed (time. Now (). Unix ()) Award_stat: = Make (Map[string]int64) for I: = 0; I < 10000;    i + = 1 {name: = Getawardusername (Users) if count, OK: = Award_stat[name]; OK {Award_stat[name] = count + 1 } else {Award_Stat[name] = 1}} for Name, count: = Range Award_stat {fmt. Printf ("User:%s, award count:%d\n", Name, Count)} return}

Code Execution Results:

user: c, award count: 1667user: f, award count: 3310user: e, award count: 1099user: d, award count: 2276user: b, award count: 549user: a, award count: 1099

Thank you for your comments, let me benefit, the above code does have too many slots, thanks to the slot, code corrections are as follows:

func GetAwardUserName(users map[string]int64) (name string) {  var sum_num int64  for _, num := range users {    sum_num += num  }  award_num := rand.Int63n(sum_num)  var offset_num int64  for _name, num := range a_user_arr {    offset_num += num    if award_num < offset_num {      name = _name      return    }  }  return}

Since the Golang is always thought map for range to be reentrant, the reality is that the order of the two rounds traversed is key actually randomized, and the code example is as follows:

n_map := make(map[int]bool)for i := 1; i <= 10; i++ {  n_map[i] = true}for num, _ := range n_map {  fmt.Print(num)}fmt.Print("\n")for num, _ := range n_map {  fmt.Print(num)}
9125710346846810325791

Because map of the non-reentrant nature map and for range pseudo-randomness, the code is modified as follows:

func GetAwardUserName(users map[string]int64) (name string) {  var sum_num int64  name_arr := make([]string, len(users))  for u_name, num := range users {    sum_num += num    name_arr = append(name_arr, u_name)  }  award_num := rand.Int63n(sum_num)  var offset_num int64  for _, u_name := range name_arr {    offset_num += users[u_name]    if award_num < offset_num {      name = u_name      return    }  }  return}

The above code, for multiple calls will have a performance problem, each time to recalculate sum_num and create name_arr , using closures re-implementation, the code is as follows:

func GetAwardGenerator(users map[string]int64) (generator func() string) {  var sum_num int64  name_arr := make([]string, len(users))  for u_name, num := range users {    sum_num += num    name_arr = append(name_arr, u_name)  }  generator = func() string {    award_num := rand.Int63n(sum_num)    var offset_num int64    for _, u_name := range name_arr {      offset_num += users[u_name]      if award_num < offset_num {        return u_name      }    }    // 缺省返回,正常情况下,不会运行到此处    return name_arr[0]  }  return}

The above code uses the closure to avoid multiple draws frequently initialized, but the complexity of each draw, O(n) it is clear that there is still room for optimization, you can use the binary search to reduce complexity O(log n) , the code is as follows:

func GetAwardGenerator(users map[string]int64) (generator func() string) {  var sum_num int64  name_arr := make([]string, len(users))  offset_arr := make([]int64, len(users))  var index int  for u_name, num := range users {    name_arr[index] = u_name    offset_arr[index] = sum_num    sum_num += num    index += 1  }  generator = func() string {    award_num := rand.Int63n(sum_num)    return name_arr[binary_search(offset_arr, award_num)]  }  return}func binary_search(nums []int64, target int64) int {  start, end := 0, len(nums)-1  for start <= end {    mid := start + (end-start)/2    if nums[mid] > target {      end = mid - 1    } else if nums[mid] < target {      if mid+1 == len(nums) { // 最后一名中奖        return mid      }      if nums[mid+1] > target {        return mid      }      start = mid + 1    } else {      return mid    }  }  return -1}
Image

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.