【Golang后端基础面试题】

Golang后端基础面试题

  • [一. 基础面](#一. 基础面)
  • [二. 项目面(简单提问)](#二. 项目面(简单提问))

简介:主要面向准备开始面试找实习的学生或应届生,整体比较简单,主要供了解面试的基本情况,其中所有题都是阿良面试的原题,不过答案是阿良自己总结的,可供借鉴。

一. 基础面

  1. 平常怎么学习 Go

    学习 Go 语言可以通过以下方式:

    官方文档:阅读 Go的官方文档 和 Go by Example。

    书籍:阅读《The Go Programming Language》和《Go in Action》等书籍。

    实践项目:实际编写一些小项目或工作中的任务,用Go来解决问题。

    在线课程:参加如 Coursera、Udemy 上的 Go 语言课程。

    社区和论坛:参加Go相关的在线社区(如 Golang中国 和 Reddit),和其他开发者交流。

    此外自己也会写一些博客将自己的学习总结进行输出性学习

  2. 你了解切片吗?详细介绍一下?

    切片(slice)是 Go 中的一种数据结构。他是对数组的包装,即切片本身是一个结构体,这个结构体有有几个重要的字段即:指向底层数组的指针、长度和容量。
    (指向底层数组的指针:指向实际存储元素的数组的起始位置。
    长度(length):当前切片所包含的元素数量。
    容量(capacity):从切片的起始位置到底层数组末尾的元素数量。) (需要知道面试不问不说)

    这种设计使得切片在操作时非常高效,因为它允许基于同一个数组创建多个切片,不会因为切片操作而频繁地复制数组。他此外他在扩容和使用上也会有一些区别。

    a. 扩容机制:当切片容量不足时,Go会新创建一个比当前切片容量更大的数组(通常新的容量是旧的2倍),然后将原数组中的元素复制到新数组中,再将切片的底层数组指针指向新数组。

    切片是引用类型:因为切片结构包含一个指向底层数组的指针,以及切片的长度和容量信息。多个切片可以共享同一个底层数组,因此它是引用类型。

    b. 使用上:go的切片是一个引用类型的,在切片作为一个函数的参数进行函数调用时,会将这个切片的指针进行复制,在函数中对切片进行修改会影响到原本的切片。而数组是一个值类型,当数组作为一个函数的参数进行调用时,是将整个数组进行复制的,在函数中对数组是原数组的副本,因此在函数内对数组进行操作是不会影响原本的数组的。

  3. Go的slice和数组的区别

    定义:数组是固定长度的数据结构,而切片是基于数组构建的动态数据结构。

    长度和容量:数组的长度是固定的,而切片的长度和容量是可变的。

    赋值和传递:数组的赋值和传递是值拷贝,而切片是引用拷贝。

    性能:对于频繁需要改变长度的情况,使用切片更为灵活和高效。

  4. slice扩容是怎么扩的,新建底层数组?

    扩容时,Go 会:

创建一个新的、较大的底层数组。

将旧数组的数据复制到新数组中。

将切片的底层数组指针更新为新数组。

  1. Golang 里面的 map 了解过吗?

Golang 的 map 是哈希表实现的,无序的键值对集合。其主要特性有 O(1) 的插入和查找时间复杂度。语法比较简单,如 make(map[string]int) 创建一个字符串键和整数值的 map。

  1. 项目中并发 map?

在并发环境中使用 map 时,可以使用 sync.Map,它是 golang 标准库的并发安全 map 实现,或者手动使用互斥锁(mutex)进行保护。

  1. 介绍 Go 协程和 Channel 及常用场景

协程(Goroutines)

Go 的协程(goroutines)是轻量级的线程,可以通过 go 关键字启动。例子:

go func() {  
    fmt.Println("Hello from goroutine")  
}()  

通道(Channel)

通道是 goroutines 之间通讯的方式。可以通过 make(chan Type) 创建,使用 <- 操作符进行发送和接收。例子:

ch := make(chan int)  
go func() {  
    ch <- 42  
}()  
fmt.Println(<-ch)  

常用场景

并行任务处理。

任务调度。

goroutines 之间的数据共享与同步。

  1. 互斥锁,正常模式,饥饿模式?一句话形容。提高吞吐量。

互斥锁(Mutex):确保同一时间只有一个 goroutine 访问共享资源。

正常模式:默认模式,通过公平锁确保公平竞争。

饥饿模式:优先照顾等待时间长的 goroutine,以避免长期等待。

一句话形容:通过合适的锁模式和策略,提高系统并发吞吐量。

  1. MongoDB 相对于 MySQL 的优势?
    灵活的模式:MongoDB 是面向文档的 NoSQL 数据库,可以轻易处理各种格式的数据。
    水平扩展:MongoDB 支持分片存储,更容易水平扩展。
    嵌套文档结构:使得存储和查询嵌套结构数据更加方便。
    高可用性:支持复制集,实现高可用性和自动故障转移。 (简单了解)

  2. MySQL 的索引结构是什么?

    MySQL 的索引主要基于 B+ 树 实现,能够高效地支持范围查询和顺序访问。

  3. B树和 B+树的区别?(简单介绍)

    B树:每个节点既存储键也存储数据。

    B+树:所有数据都存储在叶子节点,内部节点只存储键。叶子节点通过指针相连,支持顺序遍历。

  4. MySQL 使用 B+树 相比于 B树 的优势在哪?

    更高的查询效率:因为所有的数据都在叶子节点,内节点只存储键,使得树的阶数更高,深度更小。

    顺序访问:叶子节点通过指针相连,非常适合范围查询。

    更少的 I/O 操作:密集的叶子节点存储更多数据,减少了磁盘 I/O 次数。

  5. MySQL 隔离级别?

    MySQL 支持四种事务隔离级别:

    读未提交(Read Uncommitted)。

    读已提交(Read Committed)。

    可重复读(Repeatable Read)。

    序列化(Serializable)。

  6. InnoDB 默认隔离级别?

    InnoDB 存储引擎的默认隔离级别是 可重复读(Repeatable Read)。

二. 项目面(简单提问)

  1. 多设备登录一个账号(使用 JWT 解决)

    为了实现多设备登录一个账号,我们可以使用 JWT(JSON Web Token)来进行身份认证,步骤如下:

    用户登录时,服务器生成一个 JWT 并返回给客户端。

    客户端保存 JWT(通常是在 local storage 或 cookies 中)。(回话管理)

    后续请求时,客户端将 JWT 附加到 HTTP 头部发送到服务器。

    服务器验证 JWT 的合法性,来识别用户身份。

    服务器维护一个全局的 JWT 黑名单,当用户注销或更换设备时,将旧的 JWT 加入黑名单并拒绝其后续请求。

  2. 超卖(悲观锁/乐观锁/Redis/Go基础)(先简单了解)

    超卖问题指在高并发环境下,库存被超量售出的现象。可以通过以下方式解决:

    悲观锁:通过数据库锁定库存记录,确保操作的原子性。

    乐观锁:使用版本号或时间戳机制,在更新时检查数据是否被其他事务修改。

    Redis:通过 Redis 的原子性操作(如 INCR 和 DECR),确保库存操作的原子性。

    Go基础:在代码层面使用互斥锁或通道,来保证并发安全。

  3. 遇到的问题

    这是一个需要你根据实际情况回答的问题。一般可以包含技术难题、项目管理问题、团队合作问题等方面。

  4. 了解一些校园情况

    这也是一个开放性问题,可以根据你的学习经历、校园生活、参与的社团活动或组织的相关经验进行分享。

相关推荐
Lizhihao_7 分钟前
JAVA-队列
java·开发语言
远望清一色25 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab
何曾参静谧33 分钟前
「Py」Python基础篇 之 Python都可以做哪些自动化?
开发语言·python·自动化
Prejudices37 分钟前
C++如何调用Python脚本
开发语言·c++·python
我狠狠地刷刷刷刷刷1 小时前
中文分词模拟器
开发语言·python·算法
wyh要好好学习1 小时前
C# WPF 记录DataGrid的表头顺序,下次打开界面时应用到表格中
开发语言·c#·wpf
AitTech1 小时前
C#实现:电脑系统信息的全面获取与监控
开发语言·c#
qing_0406031 小时前
C++——多态
开发语言·c++·多态
孙同学_1 小时前
【C++】—掌握STL vector 类:“Vector简介:动态数组的高效应用”
开发语言·c++
froginwe111 小时前
XML 编辑器:功能、选择与使用技巧
开发语言