1. 这轮面试给我的整体感受
这周我集中面了一批应届生。五个人的简历放在一起,几乎像同一个模板里印出来的:页面上写着三个全栈作品,技术栈从Vue到Spring Boot一路排下去,最后都写着熟悉Redis、MySQL、Nginx。薪资预期也整齐划一,每个人开口都是15K。
我不是嫌应届生要价高。一线城市校招,15K这个数字并不离谱。离谱的是,当我按惯例在面试前把对方GitHub仓库打开之后,几个人提交记录给到我的信息量和简历上的“精通”形成了巨大的反差。横竖看了几遍,我在屏幕前沉默了很久。
这篇文章不打算吐槽谁。我更想聊聊,作为一个每天和代码、上线、线上事故打交道的人,我是怎么从GitHub提交记录里判断一个应届生项目真实度的。如果你正准备秋招,或者也在带新人和筛简历,这篇东西应该能给你一些具体可落地的参考,而不是“多写点项目”这种空话。
1.1 面试前半段:大家都讲得很流畅
先说结论:如果光听自我介绍,这五个人里至少有三个是可以直接“过关”的。他们讲项目的状态很熟练,前端页面用了什么组件、后端用了什么框架、数据库大概几张表,都能顺下来。讲到项目难点的时候,也能说出“并发问题”“缓存穿透”“优化查询”这些词。
但“能讲”和“做过”是两码事。我面试有个习惯:允许候选人提前把仓库链接发给我,面试时要求对方共享屏幕,从提交记录开始讲这个项目,而不是从功能开始讲。这一招在应届生面试里几乎屡试不爽。因为背功能清单和背实现逻辑,是完全不同的两条思路。前者可以照着简历念,后者必须真正经历过才答得出来。
1.2 五个人的GitHub给我留下的第一印象
先不说个别细节,看整体。五个人的仓库有一个共性:提交次数少。少到什么程度?三个全栈项目加起来,平均每个仓库只有六七个commit。而且这些commit的message大部分是“update”“fix”“init”,没有针对功能模块的描述,更看不到重构和修复的记录。时间上,项目主要的提交集中在两三天内完成。
我一开始还以为他们是把代码用压缩包上传的。点开commit一看,好家伙,基本都是最后一个大commit塞进整个项目文件。这种提交记录放在一个“用了三个月业余时间完成的个人项目”背景里,是说不通的。真正写过程序的人都清楚,一个还能正常跑起来的前后端项目,哪怕只是个人练习,至少需要几十次有效提交,才能完成从接口调试到样式调整,再到改bug的过程。提交记录不会撒谎,它把一个项目真实的“走路过程”完整留了下来。
2. 五个“全栈项目”的共同套路
2.1 清一色的“三件套”选型
五个人的项目品类惊人地一致:一个是电商系统,一个是博客或内容管理,一个是校园类的管理后台。说白了,就是网上开源教程最常拿来做demo的三类选题。技术选型也一样:前端Vue或React二选一,后端Java Spring Boot或Node.js二选一,数据库用MySQL,缓存堆一个Redis,再配一个Nginx反向代理的配置。
这些技术栈本身没问题,但问题在于,当五个人的项目结构、页面视觉、甚至代码目录都以差不多的方式出现时,它们很难让我相信是各自独立从需求出发做出来的。我不能说他们抄同一个模板,但你我都清楚,市面上大量“全栈实战教程”就是这样的流水线产品。跟着教程复制一遍,和真正从零开始解决一个真实问题,差别巨大。
2.2 三个关键词:照搬、堆叠、不可追溯
先说“照搬”。有一个同学的仓库里,我在项目的根目录看到一份保留着原始作者个人注释的代码文件,里面还有原作者的整理日期。这不等于对方完全没有写代码,但它说明项目在搬运环节出了纰漏,连原作者痕迹都没清理干净。
再说“堆叠”。简历上技术栈列得很满,但我看代码时发现,很多依赖根本没有实际用处。一个简单的博客项目,前端引了三套UI框架,后端同时配置了两种ORM,业务代码里却一个都没用到。这种为了显得会而强行堆技术栈的做法,在真实团队里会被第一时间打回。
最后说“不可追溯”。如果一个人真的从需求分析、建表、接口、联调、部署一路走下来,他一定能在任何一个细节处回答你的为什么。但这五个人里,能讲清“为什么这样建表”“为什么这个接口这样设计”的,一个手都数不满。
2.3 为什么“全栈”标签越来越有水分
不是全栈有水分,而是“全栈”正在被滥用。过去讲全栈,指的是一个人能独立负责一个功能从后端到前端再到上线的完整链路。现在的很多简历,把“全栈”当成了一个装饰词。这种趋势下,最吃亏的其实是真正认真做项目的那批应届生。他们项目数量可能没有那么多,技术栈也没有那么密,但GitHub上的提交记录是连续、真实的。如果只看简历摘要,这类人反而容易被淹没在“三个全栈项目”的噪声里。
所以,我现在看应届生,越来越看重一卷代码背后的开发过程,而不是简历上那几个技术名词。这也是后面我要重点展开的部分:GitHub提交记录的检查方法论,真的不是装模作样看两眼就完事。
3. 现场扒GitHub提交记录,我在看什么
3.1 六个最常用的观察维度
如果说简历是候选人想让你看到的一面,那么提交记录就是候选人无意间留下的脚印。我通常从六个维度去读这些脚印,你可以把这个当成一个checklist用。
| 观察维度 | 看什么 | 对应能力 |
|---|---|---|
| 提交频率 | 平均多久提交一次,是否连续稳定 | 开发习惯、项目真实时长 |
| 提交信息 | message是否有语义,能否看出功能模块和改动意图 | 工程规范意识 |
| 提交时间 | 分散在几周,还是集中在某几天 | 项目是否真的“历经打磨” |
| diff规模 | 每次提交涉及多少文件、多少行 | 对任务切分的理解 |
| 文件构成 | 是否包含测试、文档、配置文件 | 完整工程素养 |
| 分支与协作 | 是否有branch、PR、issue痕迹 | 团队协作认知 |
注意,单一维度的异常不能下结论。比如提交信息写得烂,可能只是习惯差;但如果六个维度里同时出现四五个异常信号,那照搬项目的可能性就非常大了。
3.2 两个一眼就能抓出来的露馅信号
第一个信号:一次性把整个项目推上来。我在一个仓库里看到仅有四条commit,最后一条是“final”,里面一次性增加了九百多个文件、两万多行代码。这基本可以确定,开发者是把整个项目目录复制进去后统一提交的,开发过程完全没有留下阶段性记录。
第二个信号:代码里有不属于候选人的作者痕迹。例如某个Java文件里的包路径还写着别人的域名,某个页面的footer还留着别的项目链接,或者README里保留了原作者的介绍。这类残留基本就是从别处直接拿来的。
我常用的命令其实很简单,不需要太高端的工具:
# 查看提交历史和分支图 git log --oneline --graph --all --decorate # 查看每次提交涉及的文件和规模 git log --stat # 查看某个提交具体改了什么 git show --stat <commit-id> # 按作者统计提交情况 git shortlog -sn --all在GitHub网页端,直接点进仓库的Commits页面,右上角的贡献图也能快速看出时间分布。如果整片绿色只有同一天的几个点,那剩下的确实不用多看了。
3.3 看懂diff,而不是只看commit数量
看commit数量只是第一步,真正要看的是diff。提交记录里藏着开发时的思维过程。比如同样是实现一个列表页,真实过程通常是先搭页面骨架,再联调接口,然后处理各种边界情况,再回头调整样式。对应的commit信息可能是“feat: 添加列表页基础结构”“feat: 对接列表接口”“fix: 处理空数据状态”。
反过来,如果一条commit就把页面、接口、路由、组件全部写完,而且注释里什么都有,那更像是立刻复制进来的一次性行为。还有一个细节:我会特别留意候选人是否提交过删除代码或重构代码的记录。比如“refactor: 抽取公共请求方法”,这一条意味着这人真的在迭代自己的代码。应届生哪怕只是重构了一小块,我都觉得含金量比多做两个demo高。
4. 面试对话中暴露的三个盲区
看完整提交记录,我并不会当场拆穿谁。我把观察到的信息转成问题,放到面试对话里去验证。结果,五个人的回答帮我把他们的盲区确认得非常清楚。
4.1 盲区一:只会罗列功能,讲不出设计决策
我问过一个问题:“你这个项目的订单表为什么要把状态单独拆一张表,而不是直接放个字段?”支支吾吾半天,最后回答“教程里就这么写的”。我其实不期待应届生做出非常精巧的架构设计。我想听的是他遇到真实问题后的权衡。比如“当时发现放一个字段里查起来慢,所以拆了”,哪怕这个理由不完美,也证明他真碰过数据。
全栈不只是会调接口,而是能对一个数据模型的前因后果负责。那些能把“多表关联”“索引”“事务”挂在嘴上的人,一旦被追问到具体业务场景,很容易露馅。因为真实项目里的每个设计,背后都是踩坑踩出来的。
4.2 盲区二:写代码能跑,但看不到工程闭环
第二个盲区更致命:他们理解里的“会了”,上限是代码在自己的电脑上能跑。当我追问“这个项目部署在哪,线上地址给我看看”时,五个人里三个都沉默了。有一个人反问我:“部署?我没做过,就是把后端在本地跑起来就行了吧?”
听到这个回答的时候,我在屏幕那头沉默的时间比看commit记录还久。全栈项目如果连一次线上部署都没有,那它本质上只完成了一半。真正的全栈,要看到用户访问、日志报错、环境问题、域名解析这一整条链路。哪怕只是部署在免费的服务器上,哪怕访问量只有自己一个人,经历过的和没经历过的,聊起来完全是两种状态。
4.3 盲区三:工程工具基础薄弱
我还让候选人做了十分钟的小代码任务,不考算法,只考日常开发。比如:假设本地分支的代码跑不起来,怎么定位是哪个服务的报错?有两个人告诉我“不清楚,平时都是直接问同学”。顺带一提,git冲突怎么解,也有三个人说不利索。
这不是大词,而是全栈工程师的基本生存技能。一旦进入真实团队,每天面对的第一件事不是写新功能,而是处理已有代码和协作流程。如果连本地起服务、看日志、解冲突都要人带着走,那距离独立交付项目还有很长一段路。
5. 一个让我重新沉默的例外
在五个候选人里,有一个人情况不一样。我把他的仓库放在最后讲,是因为他让我思考了很久“到底什么才是全栈应届生该有的样子”。
5.1 一份不完美但真实的提交历史
这位同学的GitHub点进去,三个仓库,其中一个项目贡献图是连续的大片绿色,时间跨度两个多月,一共有一百三十多次commit。提交信息写得不算多高级,但每一条都有明确内容:“add order query api”“fix payment callback bug”“refactor cart component”“update readme with deploy steps”。我翻了几个commit的diff,能看到早期提交的代码确实粗糙,好几处业务逻辑直接写在handler里,但后来有一次重构,把逻辑抽到了service层。
他的项目选题也很小:给宿舍楼同学用的物品借用小程序。功能就三四个页面,后台一张订单表一张物品表,没什么高并发,也没用什么炫技架构。但他把这个事情做完整了,包括部署到免费服务器上,README里还写着“已知问题:物品详情页在弱网环境下加载慢,后续考虑做缩略图缓存”。
5.2 一个真实项目需要的完整闭环
我当时问他:“你项目里最烦的一个bug是什么?”他讲了一个图标在部分机型上加载不出来的问题,说排查了很久,最后发现是接口返回图片URL用的协议和线上环境不一致,加了个统一处理才解决。这种回答比任何技术名词都有效,因为它说明他不只是对着教程敲代码,而是真的遇到过一个线上问题,然后经历了定位、分析、解决的完整过程。
这个过程会写进他的直觉里。带过新人的人会明白,这种 debug 直觉恰恰是校招里最稀缺的。很多人缺的不是智商,不是代码量,而是面对一个未知错误时,愿意一步一步查下去的习惯。
5.3 表演型项目与真实项目的对照
我把两种项目放在一起对比,方便你看得更清楚:
| 对比维度 | 表演型项目 | 真实项目 |
|---|---|---|
| 提交历史 | 几次集中提交 | 持续几十次以上提交 |
| 代码变化 | 一次成型 | 有重构、删除、修正记录 |
| 技术栈 | 堆了很多但没实际作用 | 轻量且够用 |
| 部署情况 | 本地运行 | 有线上地址和访问记录 |
| 问题记录 | 无 | README或issue里有已知问题 |
| 表达焦点 | 功能清单 | 设计取舍与排查过程 |
我想强调的是,真实项目不是说代码必须写得漂亮,而是它的节奏是真实的。长得慢、长得乱,但每一步都有迹可循。这种实力积累的速度,比简历上堆出来的三个全栈要快得多。
6. 应届生与面试官双向避坑清单
看完这轮面试,我复盘了两件事:应届生应该怎么经营自己的项目经历,面试官又该怎么快速分辨项目真假。这里直接给清单。
6.1 应届生:让GitHub提交记录替你说话
如果你正在准备校招,下面几条我建议尽早做起来。
- 从你写第一行功能代码开始,就在项目目录里跑
git init,让整个开发周期留下记录。代码烂没关系,提交信息乱一点也没关系,最怕的是没有过程。 - commit message写有信息量的描述。“add notice module”比“update”强得多,“fix user auth token expired issue”比“fix bug”强得多。面试官从这些信息里能看到你拆解任务的能力。
- 把你遇到的坑和你的权衡写进README或issue。哪怕只是写几句“因为xx原因我决定用xx方案,虽然它有xx缺点”,都已经是一份很好的思考档案。
- 想办法把项目部署上线。免费云虚拟机、一个解析过来的域名,把Nginx和端口、环境变量都经历一遍。能讲清部署链路的人,在应届生里已经是少数。
- 项目控制在两个以内,把一个做透,好过堆五个离开本地就跑不了的demo。
6.2 面试官:如何在有限时间内做背景核实
我的固定动作是:面试前十五分钟先看候选人的提交图、提交信息和依赖清单。面试中优先从仓库里的一个具体commit开头问,比如“这个refactor的commit,当时是遇到什么问题想重构的?”这比重问“你项目里用了什么技术”有价值得多。
然后给对方一个在线小任务:让候选人共享屏幕,在项目里改一个小逻辑,或者本地起一个接口,观察他调试时的手势。答不答得出来不重要,重要的是看他在不熟悉问题面前的第一反应——是尝试打印日志、拆解定位,还是手足无措。
6.3 我自己踩过的坑
早年我面人还比较看简历上的技术栈覆盖,招过一个技术名词讲得头头是道的应届生,进来后发现连给项目加个字段都要动半天,线上出问题更是完全找不到北。从那之后,我养成了只看开发轨迹的习惯。
复盘那次经历,我最大的教训是:简历是期望值管理,GitHub是证据链管理。面试官需要判断的不是候选人知道什么,而是能交付什么。能交付的人,不一定拥有最全的技术名词,但一定有最扎实的动手过程。
最后分享一个我现在很坚持的标准:候选人只要在任何一个项目里展现过一次完整的闭环,从定需求、写代码、发现问题、处理修复,到部署上线,我都会多给一点耐心。因为这个人已经证明,他具备独立成长到更高水平的能力。而那些只把项目当表演道具的人,哪怕包装得再亮眼,我也只能选择沉默。