在这次面试过程中,我遇到了一些技术性问题,虽然有些难度,但也促使我深入思考了很多基础知识和工程实现的细节。在面试的过程中,我有一些收获,也发现了自己的一些不足,下面是我对各个面试环节的详细复盘。编辑
哔哩哔哩实习二面(zlx)
1. 大量的 TIME_WAIT
或 CLOSE_WAIT
出现怎么办?会有哪些影响(端口占用角度)?
在这个问题中,我首先讲解了 TIME_WAIT
和 CLOSE_WAIT
的定义,指出它们都是TCP连接的状态。TIME_WAIT
状态通常在连接关闭后进入,目的是确保所有数据都被传输并处理完。CLOSE_WAIT
状态则表示本地端收到了对方的关闭请求,但本地端尚未关闭连接。
如果大量的 TIME_WAIT
或 CLOSE_WAIT
状态占用端口,会导致系统资源的浪费,可能导致端口耗尽,从而影响新连接的建立。通常的解决方式包括:编辑
- 调整TCP连接的超时参数 :可以通过调整操作系统内核的
tcp_fin_timeout
等参数,减少TIME_WAIT
状态的持续时间。 - 复用端口 :在一些高并发场景下,可以使用
SO_REUSEADDR
或SO_REUSEPORT
,来复用端口。编辑
- 使用
keepalive
参数 :对于长时间运行的连接,可以考虑设置TCP_KEEPALIVE
参数,避免不必要的连接占用资源。
面试官似乎对我的回答比较认可,继续提了几个相关的问题,比如如何优化TCP连接管理,如何避免端口泄漏等。
蔚来实习一面(zlx)
八股问题:
-
git 合并冲突你喜欢用
merge
还是rebase
?我选择了
rebase
,因为它能够保留更加干净的历史记录,使得提交历史看起来更加线性。但在多人协作开发时,merge
可能更加安全,因为它保留了分支的历史。如果是自己的单独开发,rebase
能有效避免分支历史的杂乱。编辑
-
git 如何推送到多个版本上?
在这方面我回答了使用 git push
的 --all
参数或者在不同的远程仓库配置多个 push
目标来推送到多个版本。但我意识到,这个问题可能更多是在问如何进行版本发布管理,在这方面我可以进一步学习。
- Go 协程和 Java 线程的区别?
Go 协程是由Go runtime管理的轻量级线程,它们共享地址空间,启动和销毁成本低。相比之下,Java 线程是由操作系统管理的,通常启动和销毁的开销较大。Go 协程的调度是由Go运行时负责的,而Java线程则由操作系统调度。
- MySQL 查询优化:
在谈到查询优化时,我分享了常见的优化方法:
-
使用索引 :确保 WHERE 子句、JOIN 操作的字段上有索引。
-
避免全表扫描 :避免在大数据表上进行全表扫描,尤其是在查询中涉及
LIKE
和OR
时。 -
优化查询结构 :减少子查询,避免嵌套查询,使用
EXPLAIN
分析查询计划,找出瓶颈。 -
合理使用缓存:使用查询缓存和应用层缓存减少数据库的访问次数。
字节跳动二面(挂)
1. 自我介绍:
我简要介绍了自己的项目经验和技术栈,包括后端开发和数据库优化等方面,但面试官对于我如何调研后端技术更有前景的部分提了更多问题,这一块我的回答显得有些浅显,可能没有准确把握面试官的期望。
2. 一个记录用户登录登出的日志文件,如何从日志文件中得到一天最大同时在线人数?
我首先提到可以通过记录每个用户的登录登出时间来计算,并使用布隆过滤器来判断是否在线。布隆过滤器可以有效地减少空间消耗,但也会带来一定的误判率。面试官问得很深入,这个问题让我对如何在大数据量场景中进行优化有了更深的思考。
3. 计算机学习经历和难题:
我被问到最难的事情是什么,回答了四元数问题。在项目中,四元数用于导航系统和成像系统中,它们在三维空间中的旋转运算非常复杂。由于项目涉及到大量的四元数运算,如何高效计算是我面临的挑战之一。
4. 算法题:
我被问到了一道 SQL 查询的算法题,要求找出相同的人。这一题让我回想起了 SQL 查询优化中的一些技巧,如何设计高效的查询条件来提高性能。
小红书二面(挂)
1. 为什么选择 Gin 框架?与其他框架或 Go 的 net 包有什么优势?
在这一题中,我提到 Gin 是 Go 语言中一个高效的 Web 框架,它提供了更高效的路由匹配和中间件支持,适用于高并发场景。与 net/http
包相比,Gin 进一步封装了很多操作,简化了开发流程。
2. Goroutine 栈内存不够的情况下会扩充,什么情况下扩充,怎么监控?
我解释了 Goroutine 的栈内存会在需要时自动扩展,默认从 2KB 开始,扩展到更大时是由 Go 的运行时调度器负责管理的。我提到可以通过 GODEBUG
环境变量来监控和调试 Goroutine 的栈内存情况。
3. Golang 错误处理:
关于 Golang 的错误处理机制,我回答了 Go 的错误处理相对繁琐,因为每个函数都需要显式地返回错误,但也可以通过自定义错误类型和包来简化错误的判断和处理。
总结
面试过程中,我意识到自己对于一些基础概念理解得不够深入,特别是在分布式架构和高并发场景下的优化措施方面。在后续的学习中,我会更加注重对操作系统、数据库、网络协议等基础技术的深入理解,争取在以后的面试中能够更加自信地应对相关问题。同时,我也会多做一些项目实战,提升自己的技术积累和解决问题的能力。