跳到主要内容

golang面试题

第一篇:基础语法

  1. 数组和slice区别,slice扩容机制
  2. 说下Go的map底层实现
  3. map如何实现有序读取
map不能顺序读取,是因为他是无序的,想要有序读取,首先的解决的问题就是,把key变为有序,所以可以把key放入切片,对切片进行排序,遍历切片,通过key取值。
  1. 代码执行结果:
 s := make([]int, 5)
s = append(s, 1, 2, 3)
fmt.Println(s)
  1. 代码执行结果:
p1 := 1
p2 := &p1
*p2++
fmt.Println(p1)
fmt.Println(*p2)
  1. 代码执行结果:
a := [3]int{0, 1, 2}
s := a[1:2]

s[0] = 11
s = append(s, 12)
s = append(s, 13)
s[0] = 21

fmt.Println(a)
fmt.Println(s)
  1. 代码执行结果:
var a = [5]int{1, 2, 3, 4, 5}
var r [5]int
for i, v := range &a {
if i == 0 {
a[1] = 12
a[2] = 13
}
r[i] = v
}
fmt.Println("r = ", r)
fmt.Println("a = ", a)
  1. 切片的反转 s:= []int{1,2,3,5,4}
  2. 代码执行结果
const (
x = iota
_
y
z = "zzz"
k
p = iota
)

func main() {
fmt.Println(x,y,z,k,p)
}
  1. 代码执行结果
slice := []int{10, 11, 12, 13}
m := make(map[int]*int)

for key, val := range slice {
m[key] = &val
}
fmt.Println(m)

for k, v := range m {
fmt.Println(k, "->", *v)
}
  1. 代码执行结果
func test(x int) (func(), func()) {
return func() {
println(x)
x += 10
}, func() {
println(x)
}
}

func main() {
foo, bar := test(10)
foo()
bar()
}
  1. new()make() 的区别
  2. golang变量内存分配,什么时候分配在栈,何时分配在堆
  3. golang哪些类型是指传递,哪些是引用传递,区别是什么,分别的使用的场景
  4. 代码执行结果
package main

import "fmt"

func main() {
c := make(chan int)
for i := 0; i <= 10; i++ {
c <- i
}
go func() {
for item := range c {
fmt.Println(item)
}
}()
}
  1. 怎么安全的使用全局变量
  2. 闭包,把全局变量当作闭包函数的局部变量,返回一个函数,程序使用这个函数来安全的使用这种全局变量
  3. golang的接口原理,怎么用,接口的作用
  4. Golang的内存分配和内存管理
  5. context包的用途

第二篇:计算机网络&并发

  1. OSI七层模型
  2. DNS协议详细过程【or 向浏览器里面输入一个网址,过程是怎么样的?(DNS,TCP)】
  3. ip查mac地址是什么协议?(ARP)
  4. http和https的区别
  5. 细说下https实现过程【先非对称加密然后对称加密,ssl协议】
  6. TCP三次握手过程?
  7. TCP和UDP的区别?
  8. 为什么音视频传输使用UDP协议?
  9. TCP四次挥手后,为什么要time_wait 2MSL?等1MSL为啥不可以?
  10. 既然TCP有seq,Time_wait这个状态有啥用呢?没有行不行?
  11. TCP的特性(超时重传、滑动窗口、流量控制、拥塞控制)
  12. http keep-alive
client发出的HTTP请求头需要增加Connection:keep-alive字段 
Web-Server端要能识别Connection:keep-alive字段,并且在http的response里指定Connection:keep-alive字段,告诉client,我能提供keep-alive服务,并且"应允"client我暂时不会关闭socket连接
  1. 线程,协程,进程的区别?
  2. 互斥锁,读写锁应用什么场景
  3. 简单说一下GMP模型
  4. channel的作用,在Go里面有什么使用场景?
  5. channel关闭了去读去写会怎样?
  6. IO模型,同步阻塞,同步非阻塞,IO多路复用,异步
  7. IO多路复用简单介绍下,其中epoll和poll的区别
  8. goroutine泄露怎么排查
  9. 主协程如何等其余协程完再操作【使用channel进行通信,context,select 】

第三篇:框架

  1. gin框架
  2. Go-zero
  3. micro框架

第四篇:数据库

4.1 、MySQL

  1. mysql的不同索引类型
  2. mysql有几种日志,binlog什么情况可以产生,主要是干嘛用的
重做日志(redo log)
回滚日志(undo log)
二进制日志(binlog)
错误日志(errorlog)
慢查询日志(slow query log)
一般查询日志(general log)
中继日志(relay log)
  1. Mysql事务隔离级别
  2. MyISAM 和 InnoDB 的区别有哪些?
  3. 什么是覆盖索引?
  4. 我们一般选择什么样的字段来建立索引?
  5. 为什么索引结构默认使用B+Tree?
  6. MySQL主从复制流程和原理?
  7. 说下聚簇索引 & 非聚簇索引区别
  8. 了解Mysql的悲观锁和乐观锁吗?简单介绍一下。

4.2、redis

  1. 项目中redis使用了哪些数据结构?哪些场景下用了什么数据结构?怎么考虑的?
  2. Redis的主要使用场景
  3. 为什么redis是单线程的?
Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)
  1. Redis是单线程的,但Redis为什么这么快?
1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查 找和操作的时间复杂度都是O(1); 
2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;
3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
4、使用多路I/O复用模型,非阻塞IO;这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程
5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
  1. Redis每秒读写速率?
  2. Redis主从模式和集群模式的区别
  3. Redis分布式锁的底层原理是什么?
先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。如果在setnx之后执行expire之前进程 。意外crash或者要重启维护了,那会怎么样?set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令 来用的!
  1. redis的可持久化机制
  2. 什么是缓存雪崩?如何解决缓存雪崩?
  3. 说下缓存击穿,如何解决?
  4. 设置热点数据永不过期、更新缓存时,加全局锁,保证只有一个走数据库
  5. 项目中缓存同步怎么实现的?
我采用的是本地缓存同步(当前微服务的数据库数据与缓存数据同步,可以直接在数据库修改时加入对Redis的修改逻辑,保证数据一致) + 跨服务缓存同步策略(对于服务A调用了服务B,并对查询结果缓存。服务B数据库修改,可以通过rabbitmq通知服务A,服务A修改Redis缓存数据)。另外说了,其实可以使用Canal框架,用来伪装成MySQL的salve节点,监听MySQL的binLog是否变化,然后再去修改Redis缓存数据(但是在项目中没有使用到)
  1. redis的zeset的底层原理

4.3、消息队列

  1. Rabbitmq是如何确保消息的不丢失?
  2. Rabbitmq如何避免消息堆积问题?
  3. rabbitMQ消息不消费会怎样
默认情况下,消息是不会过期的,也就是我们平日里在消息发送时,如果不设置任何消息过期的相关参数,那么消息是不会过期的,即使消息没被消费掉,也会一直存储在队列中。
TTL(Time-To-Live),消息存活的时间,即消息的有效期。如果我们希望消息能够有一个存活时间,那么我们可以通过设置 TTL 来实现这一需求。如果消息的存活时间超过了 TTL 并且还没有被消息,此时消息就会变成死信,当消息队列设置过期时间的时候,那么消息过期了就会被删除

第五篇:数据结构与算法

  1. 常用的数据结构:线性结构、非线性结构,堆栈,数组,链表
  2. 链表的结构是什么样、指针是干嘛
  3. 简单说一下简单的排序算法?
  4. 冒泡排序和快速排序的时间复杂度是怎样的?
  5. 有一个整型的无序数组,如何快速找出第k大的数?
  6. 什么是单例模式,什么场景用到单例模式?

第六篇:综合篇

  1. 请你自我介绍一下你自己?
  2. 能不能接受996【万恶的资本家】,会不会排斥加班?
  3. 为什么离职?