当前位置: 首页 > news >正文

golang后端面试复习

网络

  1. TCP/IP的三次握手四次挥手

  2. 键入一个网址到完全呈现的流程

    • 1.当浏览器发起请求的时候,并不会先做查询,而是查看浏览器的 DNS 缓存和操作系统的 DNS 缓存有没有相应网址的映射,如果有,则调用,如果都没有,就会发起一个 DNS 查询,浏览器通过 IP 地址与 Web 服务器通信

    • 2.获取到ip地址后,浏览器就可以调用 socket 函数,发起TCP请求,通过三次握手建立连接

    • 3.客户端通过 TCP 套接字向 Web 服务器发送 HTTP 请求。

      • 一个请求报文由请求行、请求头、空行和请求数据 4 部分组成

      • HTTP请求一开始并没有先打到 web 应用上,而是先打到反向代理 Nginx(Nginx 是一个高性能的静态服务器, 很多访问量比较高的网站都会使用 Nginx 来负载均衡,可以把请求通过 Nginx 转换到动态服务器上,增大吞吐量)

      • Nginx 再将请求转发到 WSGI 服务器上(WSGI是 Web Server Gateway Interface 的缩写, 它是 web 框架与 Web 服务器之间的一种接口, 常用的 web 服务器软件有 uWSGI,Gunicorn等), WSGI 服务器接受并解析请求,再将请求发送给后端 web 应用。

    • 4.Web 服务器接受请求并返回 HTTP 响应,服务器将资源复本写到 TCP 套接字,由客户端读取。

      • 一个HTTP响应由状态行(包含版本号、状态代码、描述)、响应头部、空行和响应数据 4 部分组成。
    • 5.若没有其他数据传输,则通过 TCP 四次挥手释放连接

    • 6.客户端读取响应数据 HTML,根据 HTML 的语法对其进行格式化,并在浏览器窗口中显示。

在这里插入图片描述

  1. 端口不通,两个服务器怎么排查?
  2. 进程、协程、线程

数据库

  1. Mysql的索引有哪些(按类型分),隔离四个性,b+树和b树的区别
  2. sql注入和常见的网络攻击
  3. 缓存击穿、雪崩、穿透及其解决方案
`缓存穿透`定义:缓存穿透是指用户请求的数据既不在缓存中,也不存在于数据库中。每次请求都会直接访问数据库,导致缓存失效,数据库压力骤增。
解决方案:布隆过滤器:使用布隆过滤器存储所有可能存在的键,快速判断请求是否有效,避免无效请求直接访问数据库。缓存空值:当数据库查询结果为空时,将空值缓存起来,并设置较短的过期时间,减少重复查询。参数校验:对请求参数进行合法性校验,过滤掉明显无效的请求。`缓存击穿`
定义:缓存击穿发生在热点数据过期时,大量并发请求同时访问数据库,导致数据库负载过高。
解决方案:
加锁机制:使用分布式锁(如Redis锁)限制同一时刻只有一个请求访问数据库,其余请求等待锁释放。自动续期:在缓存即将过期时,通过定时任务刷新缓存,确保热点数据始终有效。缓存预热:在系统启动或高峰期前,将热点数据提前加载到缓存中,避免缓存失效。`缓存雪崩`定义:缓存雪崩是指大量缓存数据在同一时间失效,或缓存服务器宕机,导致所有请求直接涌向数据库,可能引发系统崩溃。
解决方案:随机过期时间:为缓存数据设置随机过期时间,避免大量缓存同时失效。高可用架构:使用Redis集群或哨兵模式,确保缓存服务的高可用性,避免单点故障。
  1. redis的批量操作(mget、lua脚本)
  2. redis的物种基本类型和应用场景
  3. mysql的慢查询优化检查
  4. 索引覆盖

消息中间件

kafka

1.kafka的消息顺序(partition)
2.

Go语言

  1. slice底层,go的类型分类和具体类型(引用和值类型):
type slice struct {array unsafe.Pointer // 指向底层数组的指针len   int            // 长度cap   int            // 容量
}`切片是对数组的抽象,底层包含了三个部分数组的指针,长度,容量。`
`go分为类型分为引用类型和值类型,切片就是引用类型,但他本身是一个结构体是一个值类型,只是包含了一个指向数组的指针。`
`这意味着函数间传递切片时,是传递了这个结构体的副本,在函数内部对这个切片的元素进行修改时,会影响到底层数组,而对切片进行扩容则不会影响原切片(因为容量和长度是值类型)`
  1. channel,有缓冲和无缓冲有什么特征,说一下并发控制和关闭,channel是否是线程安全
`channel创建无缓冲是同步通信,有缓冲是异步通信。即无缓冲时,发送端将会阻塞直到有接收端开始接收。而有缓冲时,发送端发送的数据将会存到缓冲区,而不会阻塞。`
`channel的并发控制一般使用select进行多路复用,同时可以监听多个select。
也可以使用for……range循环会在channel关闭后自动退出。
done(channel)则代表这个channel被关闭
close函数用于关闭一个channel。关闭channel表明不再有值会被发送到该channel上。关闭channel后,接收操作仍然可以继续,直到已经发送的数据都被接收完毕,之后接收操作会立即返回零值和一个表示channel已关闭的标志,监听到关闭标志则可以停止接收。`   // select会阻塞直到某个case可以执行select {case msg1 := <-ch1:fmt.Println(msg1)case msg2 := <-ch2:fmt.Println(msg2)case <-time.After(3 * time.Second):fmt.Println("timeout")}
`channel是线程安全的,多个协程可以通过channel进行通信而不会发生数据竞争`
`1.在使用channel时需要注意:由发送者关闭channel而不是在接受者关闭。
2.不可以重复关闭channel会导致panic
3.可以利用waitGroup协调多个goroutine,保证协程关闭`
  1. map的key可以有哪些类型布尔、字符串、数字、指针、通道都可以作为key值。以下类型不能作为map的key:切片(slice)、包含切片或函数的结构体或数组其他的map。如果使用接口类型作为key,那么实际存储的接口值必须是非nil且其动态类型是可比较的,否则会导致运行时panic。
  2. GC垃圾回收机制
Go 的 GC 是一个并发、三色标记清除(concurrent, tri-color mark-and-sweep)的收集器。
Go 的 GC 使用三色标记算法来追踪对象:白色对象:尚未被 GC 访问的对象(可能为垃圾)灰色对象:已被 GC 访问,但其引用的对象还未被检查黑色对象:已被 GC 访问,且其引用的对象也已被检查。GC的阶段:1.Mark准备(Mark Setup):STW阶段,开启写屏障,准备根对象。2.Marking:并发标记阶段,遍历所有可达对象。3.Mark终止:STW阶段,关闭写屏障,清理标记状态。4.Sweeping:并发清除阶段,回收不可达对象的内存Go 的 GC 会在以下情况下触发(Go 的 GC 是并发的,意味着它可以在程序运行的同时执行大部分工作,只有极短的 STW(Stop-The-World)暂停。):1.自动触发:当堆内存增长到一定比例时(由 GOGC 环境变量控制)2.手动触发:调用 runtime.GC() 函数3.定时触发:如果长时间没有 GC,会强制触发
  1. defer的执行顺序在函数执行完成之后再执行,可以用来关闭连接,多个defer会根据先定义后执行的顺序执行(类似栈的顺序)
  2. 协程调度 GMP模型:
GMP 分别代表:G:Goroutine,Go 语言中的轻量级线程,由 Go 运行时管理。M:Machine(或 Worker Thread),代表着操作系统线程,由操作系统调度。P:Processor,是一个逻辑处理器,它包含了运行 Goroutine 所需的资源,比如本地队列。调度过程
每个 M 都需要绑定一个 P 来执行 G。每个 P 维护一个本地 Goroutine 队列(Local Run Queue),同时还有一个全局 Goroutine 队列(Global Run Queue)用于平衡负载。当一个新的 G 被创建时,它会被优先放入当前 P 的本地队列。如果本地队列已满,则把本地队列的一半 G 移动到全局队列。当 M 执行完当前 G 后,它会尝试从绑定的 P 的本地队列获取 G。如果本地队列为空,则从全局队列获取,如果全局队列也为空,则从其他 P 的本地队列偷取一半(工作窃取,Work Stealing)。阻塞处理
如果 G 执行了阻塞操作(如系统调用),则 M 会被阻塞,此时 P 会和 M 解绑,并寻找空闲的 M 来执行其他 G。如果没有空闲 M,则会创建新的 M。当阻塞操作完成,G 会被重新放入全局队列,M 会尝试绑定一个 P 继续执行,如果没有可用的 P,则 M 会进入休眠状态。
  1. select和switch的区别,执行机制:switch当做if……else来使用,而select一般用于channel的监听相关的IO操作,如果 select 的多个分支都满足条件,则会随机的选取其中一个满足条件的分支执行
  2. 读写锁和mutex的区别读写锁可以多读1写,mutex锁是互斥锁,锁住了就不可以再使用资源了必须等锁释放
  3. map是线程安全吗?如何让map安全:不安全,可以使用sync包中map或map使用加读写锁,不然会读写冲突会导致panic,高并发场景下,可以使用map分片加锁的方式,有对应的开发引用项目可以使用
  4. sync.waitgroup是怎么用的配合addgroup使用,用来控制协程的并发
  5. 结构体可以比较吗?反射考点
Go 结构体有时候并不能直接比较,当其基本类型包含:slice、map、function 时,是不能比较的。若强行比较,就会导致出现例子中的直接报错的情况。反射比较方法 reflect.DeepEqual 常用于判定两个值是否深度一致,其规则如下:相同类型的值是深度相等的,不同类型的值永远不会深度相等。
当数组值(array)的对应元素深度相等时,数组值是深度相等的。
当结构体(struct)值如果其对应的字段(包括导出和未导出的字段)都是深度相等的,则该值是深度相等的。
当函数(func)值如果都是零,则是深度相等;否则就不是深度相等。
当接口(interface)值如果持有深度相等的具体值,则深度相等。
...

框架

  1. gin框架的优缺点

LINUX

  1. 查看服务满了的命令(查看进程和端口)
  2. 如何查看内存,查看磁盘余量
  3. 查看文件权限

数据结构

1.二叉树和红黑树的区别
2.

http://www.dtcms.com/a/389446.html

相关文章:

  • webpack学习笔记-entry
  • webpack学习之output
  • 应急响应靶机-WindowsServer2022-web2
  • Netty:网络编程基础
  • VulnHub打靶记录——AdmX_new
  • 筑牢安全防线,守护线上招标采购管理软件
  • TP8框架安全文件与文件夹权限相关设置
  • 练习:客户端从终端不断读取数据,通过UDP,发送给服务端,服务端输出
  • Android Studio报错 C Users User .gradle caches... (系统找不到指定的文件)
  • 微服务分页查询:MyBatis-Plus vs 自定义实现
  • Opera Neon:Opera 推出的AI智能代理浏览器
  • Java 基础知识整理:字面量、常量与变量的区别
  • 模型部署:(六)安卓端部署Yolov8分类项目全流程记录
  • android 查看apk签名信息
  • SQL提取国家名称与延伸词技巧
  • 通过 商业智能 BI 数据分析提升客流量和销售额
  • PostgreSQL 与 MySQL 谁的地位更高?——全方位对比分析
  • rust编写web服务08-配置管理与日志
  • 浏览器事件机制里,事件冒泡和事件捕获的具体区别是什么?在React的合成事件体系下有什么不同的?
  • 企业级实战:构建基于Qt、C++与YOLOv8的模块化工业视觉检测系统(基于QML)
  • 【Java】Ubuntu上发布Springboot 网站
  • 【入门级-算法-3、基础算法:贪心法】
  • Linux 网络
  • 【LVS入门宝典】探秘LVS透明性:客户端如何“看不见”后端服务器的魔法
  • 23届考研-C++面经(OD)
  • 运维安全06,服务安全
  • C++篇(9)list的模拟实现
  • Bugku-宽带信息泄露
  • LeetCode 845.数组中的最长山脉
  • 分布式存储与NFS:现代架构选型指南