golang基礎面試題30道[答題時間1h]

Q1. (0) For-loop

  1. 建立一個基於 for 的簡單的循環。使其循環 10 次,而且使用 fmt 包打印出計數 器的值。
  2. 用 goto 改寫 1 的循環。關鍵字 for 不可以使用。
  3. 再次改寫這個循環,使其遍歷一個 array,並將這個 array 打印到屏幕上。

Q2. (0) FizzBuzz

  1. 解決這個叫作 Fizz-Buzz[23] 的問題: 編寫一個程序,打印從 1 到 100 的數字。
    當是3的倍數就打印 「Fizz」 代替數字,當是5的倍數就打印 「Buzz」。
    當數字同時是3和5的倍數 時,打印 「FizzBuzz」。

Q3. (1) 字符串

  1. 創建一個 Go 程序打印下面的內容(到 100 個字符):
    A
    AA
    AAA
    AAAA
    AAAAA
    AAAAAA
    AAAAAAA
  2. 創建一個程序統計字符串裏的字符數量:
    asSASA ddd dsjkdsjs dk
    同時輸出這個字符串的字節數。
    提示: 看看 unicode/utf8 包。
  3. 擴展/修改上一個問題的程序,替換位置 4 開始的三個字符爲 「abc」。
  4. 編寫一個 Go 程序能夠逆轉字符串,例如 「foobar」 被打印成 「raboof」。

Q4. (1) 平均值

  1. 編寫計算一個類型是 float64 的 slice 的平均值的代碼。在稍候的練習 Q5 中 將會改寫爲函數。

Q5. (0) 平均值

  1. 編寫一個函數用於計算一個 float64 類型的 slice 的平均值。

Q6. (0) 整數順序

  1. 編寫函數,返回其(兩個)參數正確的(天然)數字順序:
    f(7,2) → 2,7
    f(2,7) → 2,7

Q7. (1) 做用域

  1. 下面的程序有什麼錯誤?
    package main
    import "fmt"
    func main() {
    for i := 0 ; i < 10 ; i++ {
        fmt.Printf("%v\n", i)
    }
    fmt.Printf("%v\n", i)
    }

Q8. (1) 棧

  1. 建立一個固定大小保存整數的棧。它無須超出限制的增加。定義 push 函數—— 將數據放入棧,和 pop 函數——從棧中取得內容。棧應當是後進先出(LIFO) 的。
  2. 更進一步。編寫一個 String 方法將棧轉化爲字符串形式的表達。能夠這樣的 方式打印整個棧:
    fmt.Printf("My stack %v\n", stack)
    棧能夠被輸出成這樣的形式:
    [0:m] [1:l] [2:k]

Q9. (1) 變參

  1. 編寫函數接受整數類型變參,而且每行打印一個數字。

Q10. (1) 斐波那契

  1. 斐波那契數列以:
    1, 1, 2, 3, 5, 8, 13, . . . 開始。
    或者用數學形式表達:
    x1 = 1; x2 =1; xn = xn−1 + xn−2 ∀n > 2。
    編寫一個接受 int 值的函數,並給出這個值獲得的斐波那契數列。

Q11. (1) map 函數

map() 函數是一個接受一個函數和一個列表做爲參數的函數。函數應用於列表中的每一個元素,而一個新的包含有計算結果的列表被返回。所以:

       map(f(),(a1, a2, . . . , an−1, an)) = (f(a1), f(a2), . . . , f(an−1), f(an))算法

  1. 編寫 Go 中的簡單的 map() 函數。它能工做於操做整數的函數就能夠了。
  2. 擴展代碼使其工做於字符串列表。

Q12. (0) 最小值和最大值

  1. 編寫一個函數,找到 int slice ([]int) 中的最大值。
  2. 編寫一個函數,找到 int slice ([]int) 中的最小值。

Q13. (1) 冒泡排序

  1. 編寫一個針對 int 類型的 slice 冒泡排序的函數。
    它在一個列表上重複步驟來排序,比較每一個相䩪的元素,而且順序錯誤的時候,交換它們。
    一遍一遍掃描列表,直到沒有交換爲止,這意 味着列表排序完成。
    算法得名於更小的元素就像 「泡泡」 同樣冒到列表的別端。小程序

    這裏有一個過程代碼做爲示例:
    procedure bubbleSort( A : list of sortable items )
    do
          swapped = false
          for each i in 1 to length(A) - 1 inclusive do:
                 if A[i-1] > A[i] then
                         swap( A[i-1], A[i] )
                         swapped = true
                 end if
           end for
    while swapped
    end procedure併發

Q14. (1) 函數返回一個函數

  1. 編寫一個函數返回另外一個函數,返回的函數的做用是對一個整數 +2。函數的名稱叫作 plusTwo。而後能夠像下面這樣使用:
          p := plusTwo()
          fmt.Printf("%v\n", p(2))
    應該打印 4
  2. 使 1 中的函數更加通用化,建立一個 plusX(x) 函數,返回一個函數用於對整 數加上 x。

Q15. (0) stack 包

  1. 參考 Q8 練習。在這個練習中將從那個代碼中創建一個獨立的包。爲 stack 的實現建立一個合適的包,Push、Pop 和 Stack 類型須要被導出。
  2. 爲這個包編寫一個單元測試,至少測試 Push 後 Pop 的工做狀況。

Q16. (2) 計算器

  1. 使用 stack 包建立逆波蘭計算器

Q17. (1) 指針運算

  1. 在正文的第 54 頁有這樣的文字: …這裏沒有指針運算,所以若是這樣寫:p++,它被解釋爲 (p)++: 首先解析引用而後增長值。 當像這樣增長一個值的時候,什麼類型能夠工做?
  2. 爲何它不能工做在全部類型上?

Q18. (2) 使用 interface 的 map 函數

  1. 使用練習 Q11 的答案,利用 interface 使其更加通用。讓它至少能同時工做於int 和 string。

Q19. (1) 指針

  1. 假設定義了下面的結構:
    type Person struct {
          name string
          age int
    }
    下面兩行之間的區別是什麼?
    var p1 Person p2 := new(Person)
  2. 下面兩個內存分配的區別是什麼?
    func Set(t *T) {
           x = t
    }

    func Set(t T) {
           x= &t
    }

Q20. (1) Linked List

  1. Make use of the package container/list to create a (doubly) linked list. Push the values 1, 2 and 4 to the list and then print it.
  2. Create your own linked list implementation. And perform the same actions as in question 1

Q21. (1) Cat

  1. 編寫一個程序,模仿 Unix 的 cat 程序。對於不知道這個程序的人來講,下面的調用顯示了文件 blah 的內容: % cat blah
  2. 使其支持 n 開關,用於輸出每行的行號。
  3. 上面問題中,1 提供的解決方案存在一個 Bug。你能定位並修復它嗎?

Q22. (2) 方法調用

  1. 假設有下面的程序。要注意的是包 container/vector 曾經是 Go 的一部分,可是 當內建的 append 出現後,就被移除了。然而,對於當前的問題這不重要。這個 包實現了有 push 和 pop 方法的棧結構。
    package main
    import "container/vector"
    func main() {
             k1 := vector.IntVector{ }
             k2 := &vector.IntVector{ }
             k3 := new(vector.IntVector)
             k1.Push(2)
             k2.Push(3)
             k3.Push(4)
    }
    k1,k2 和 k3 的類型是什麼?
  2. 當前,這個程序能夠編譯而且運行良好。在不一樣類型的變量上 Push 均可以工做。
    Push 的文檔這樣描述:
    func (p *IntVector) Push(x int) Push 增長 x 到向量的末尾。
    那麼接受者應當是 *IntVector 類型,爲何上面的代碼(Push 語句)能夠正確工做? above (the Push statements) work correct then?

Q23. (1) 接口和編譯

  1. 在第 72 頁的代碼 5.3 編譯正常——就像文中開始描述的那樣。可是當運行的時候,會獲得運行時錯誤,所以有些東西有錯誤。爲何代碼編譯沒有問題呢?

Q24. (1) 指針和反射

  1. 在第 「自省和反射」 節,第 76 頁的最後一段中,有這樣的描述:
    "右邊的代碼沒有問題,而且設置了成員變量 Name 爲 「Albert Einstein」。"

固然,這僅僅工做於調用 Set() 時傳遞一個指針參數。app

爲何是這樣的狀況?函數

Q25. (2) 接口和 max()

  1. 在練習 Q12 中建立了工做於一個整形 slice 上的最大函數。如今的問題是建立一個顯示最大數字的程序,同時工做於整數和浮點數。雖然在這裏會至關困難, 不過仍是讓程序儘量的通用吧。

Q26. (1) Channel

  1. 修改在練習 Q1 中建立的程序,換句話說,主體中調用的函數如今是一個goroutine 而且使用 channel 通信。
    不用擔憂 goroutine 是如何中止的。
  2. 在完成了問題 1 後,仍有一些待解決的問題。其中一個麻煩是 goroutine 在main.main() 結束的時候,沒有進行清理。
    更糟的是,因爲 main.main() 和main.shower() 的競爭關係,不是全部數字都被打印了。
    本應該打印到 9,可是有時只打印到 8。
    添加第二個退出 channel,能夠解決這兩個問題。
    試試吧。

Q27. (2) 斐波那契 II

  1. 這是相似的練習,第一個在第 34 頁的練習 10。完整的問題描述:
    斐波那契數列以:
    1, 1, 2, 3, 5, 8, 13, . . . 開頭。
    或用數學形式:
    x1 = 1; x2 = 1; xn = xn−1 + xn−2 ∀n > 2。
    編寫一個函數接收 int 值,並給出一樣數量的斐波那契數列。 可是如今有額外條件:必須使用 channel。

Q28. (2) 進程

  1. 編寫一個程序,列出全部正在運行的進程,並打印每一個進程執行的子進程個數。 輸出應當相似:
    Pid 0 has 2 children: [1 2]
    Pid 490 has 2 children: [1199 26524]
    Pid 1824 has 1 child: [7293]
    • 爲了獲取進程列表,須要獲得 ps -e -opid,ppid,comm 的輸出。
    輸出類 似:
    PID PPID COMMAND
    9024 9023 zsh
    19560 9024 ps
    • 若是父進程有一個子進程, 就打印 child, 若是多於一個, 就打印 children;
    • 進程列表要按照數字排序,這樣就以 pid 0 開始,依次展現。
    這裏有一個 Perl 版本的程序來幫助上手(或者形成絕對的混亂)。oop

    !/usr/bin/perl -l

    my (%child, $pid, $parent) ;
    my @ps=`ps -e -opid,ppid,comm` ; # Capture the output from `ps`
    foreach ([@ps][1..$#ps]) { # Discard the header line
    ($pid, $parent, undef) = split ; # Split the line,discard 'comm'
    push @{$child{$parent} }, $pid ; # Save the child PIDs on a list
    }單元測試

    # Walk through the sorted PPIDs測試

    foreach (sort { $a <=> $b } keys %child) {
    print "Pid ", $, " has ", @{$child{$} }+0, " child", @{$child{$} } == 1 ? ": " : "ren: ", "\[@{$child{$} }\]" ;
    }ui

Q29. (0) 單詞和字母統計

  1. 編寫一個從標準輸入中讀取文本的小程序,並進行下面的操做:
  2. 計算字符數量(包括空格);
  3. 計算單詞數量;
  4. 計算行數。 換句話說,實現一個 wc(1)(參閱本地的手冊頁面),然而只須要從標準輸入讀 取。

Q30. (0) Uniq

  1. 編寫一個 Go 程序模仿 Unix 命令 uniq 的功能。程序應當像下面這樣運行,提供一個下面這樣的列表:
    'a' 'b' 'a' 'a' 'a' 'c' 'd' 'e' 'f' 'g'
    它將打印出沒有後續重複的項目:
    'a' 'b' 'a' 'c' 'd' 'e' 'f'
    下面列出的 是 Perl 實現的算法。spa

    /# !/usr/bin/perl
    my @a = qw/a b a a a c d e f g/ ;
    print my $first = shift @a ;
    foreach (@a) {
    if ($first ne $) { print ; $first = $ ; }
    }

附加題:

Q31. (2) Quine Quine 是一個打印本身的程序。

  1. 用 Go 編寫一個 Quine 程序。

Q32. (1) Echo 服務

  1. 編寫一個簡單的 echo 服務。使其監聽於本地的 TCP 端口 8053 上。它應當能夠讀取一行(以換行符結尾),將這行原樣返回而後關閉鏈接。
  2. 讓這個服務能夠併發,這樣每一個請求均可以在獨立的 goroutine 中進行處理。

Q33. (2) 數字遊戲

• 從列表中隨機選擇六個數字:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100
數字能夠屢次被選中;
• 從 1 . . . 1000 中選擇一個隨機數 i;
• 嘗試用先前的六個數字(或者其中的幾個)配合運算符 +,−,∗ 和 /,計算出 i;

例如,選擇了數字:1,6,7,8,8 和 75。而且 i 爲 977。
能夠用許多方法來實現,其 中一種:
((((1 ∗ 6) ∗ 8) + 75) ∗ 8) − 7 = 977
或者
(8 ∗ (75 + (8 ∗ 6))) − (7/1) = 977

  1. 實現像這樣的數字遊戲。使其打印像上面那樣格式的結果(也就是說,輸出應 當是帶有括號的中序表達式)
  2. 計算所有可能解,而且所有顯示出來(或者僅顯示有多少個)。在上面的例子 中,有 544 種方法。

Q34. (1) *Finger 守護進程

  1. 編寫一個 finger 守護進程,能夠工做於 finger(1) 命令。 來自 Debian 的包描述: Fingerd 是一個基於 RFC 1196 [28] 的簡單的守護進程,它爲許多站點提供了 「finger」 程序的接口。這個程序支持返回一個友好的、面向用戶的系統或用戶當前ⱥ況的詳細報告。 最基本的只須要支持用戶名參數。若是用戶有 .plan 文件,則顯示該文件內容。 所以程序須要可以提供:
    • 用戶存在嗎?
    • 若是用戶存在,顯示 .plan 文件的內容。

    格式編輯挺繁瑣的,後續再回給出參考答案

相關文章
相關標籤/搜索