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() 时传递一个指针参数。

为什么是这样的情况?

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 版本的程序来帮助上手(或者造成绝对的混乱)。

    !/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{$} }\]" ;
    }

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 实现的算法。

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

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

转载于:https://my.oschina.net/u/1377923/blog/1830136

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值