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 文件的内容。

    格式编辑挺繁琐的,后续再回给出参考答案

相关文章
相关标签/搜索