ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

腾讯日常实习生存指南:从代码评审到需求对齐的工程实践

腾讯日常实习生存指南:从代码评审到需求对齐的工程实践 很多人问我日常实习值不值得去我的答案一直是值得但它和暑期实习完全是两套玩法。暑期实习有统一的培养节奏、有明确的转正窗口、有一整套为你准备好的课程和项目日常实习更像是直接插进一支正在打仗的队伍里没人有时间给你铺红毯你进来第二天就要开始认代码、认人、认流程。我在腾讯做过一段日常实习时间不长但密度极高前两周的信息量大概相当于在学校做一个学期的项目。这段经历真正改变我的不是我写了几千行代码而是我终于搞明白了一件在学校里永远学不到的事一个需求从被提出到上线中间到底要穿过多少层人和多少道流程以及在这条链路上一个实习生应该站在哪个位置才既有产出又不添乱。下面这些东西是我把那段经历拆开揉碎之后留下的记录适合准备投日常实习、刚入职还在迷茫期、或者已经实习到一半但感觉没做出什么东西的同学看。1. 日常实习这四个字的含金量藏在它的招聘逻辑里先把一个常见的认知误区掰过来日常实习不是低配版暑期实习它是另一种产品。暑期实习面向的是批量筛选和转正储备公司愿意为它设计培养体系日常实习面向的是团队的即时人手缺口本质是补位。这个定位听起来不够体面但恰恰是它的价值所在——你补的那个位往往是真实业务里正在推进、真的有人等着用的东西。1.1 日常实习和暑期实习的三处关键差异我把两边的差异整理成了一张表这张表是我入职前最想知道、但当时没人一次性讲清楚的东西维度日常实习暑期实习招聘节奏全年滚动缺人就招集中在固定时间段入职时间随到随走周期灵活统一批次时间固定培养设计基本靠导师带边做边学有课程、有集中培训、有统一项目任务来源团队真实待办优先级随业务波动相对固定的练手项目或切片需求考核方式导师和主管的主观评价为主有相对标准化的评价流程转正通道取决于团队是否有名额不确定性强通常有明确的转正比例和路径看完这张表你应该能感觉到日常实习的收益上限很高你能碰到真业务但确定性很低没人承诺你什么。所以从入职第一天起你就要有意识地把不确定性往确定性上推——具体怎么推后面几节会讲。1.2 入职前一定要问清楚的四个问题我在入职前只问了什么时候能来后来发现这是最没价值的一个问题。真正该问的是这四个而且要在拿到口头意向后、正式入职前问趁着对方还有耐心回答你团队在做什么方向我大概会被分到哪一块这个问题的意义在于让你提前判断自己的技能栈能不能接得住。如果对方说做后台服务而你只会写页面你就知道自己需要提前补什么。带我的导师是谁他之前带过人吗带过人的导师和不带人的导师体验差距非常大。前者知道该给你多大颗粒度的任务后者容易一上来就扔给你一个帮我看看这个模块有什么问题。对我这段实习的预期产出是什么问这句话不尴尬反而显得你靠谱。有明确预期的团队通常也有明确的评价标准。实习时长有没有硬性要求结束之后有没有推荐或转正的可能这不是功利这是对双方负责。有些团队确实没有名额早知道你就能早点规划。提醒一句这些问题不要一股脑塞给对方更不要在面试环节就问。合适的时机是确定录用、沟通入职时间的那一次对话语气放平把它当成确认信息而不是谈判。1.3 心态上的一个准备你大概率不是团队的重点这句话有点扎心但很真实。你入职的时候团队手上可能压着三四个正在赶的项目导师自己也有排期。你的事情在他的优先级列表里很可能排不进前三。这不是针对你这是常态。理解这一点之后你就不会因为导师半小时才回我消息而焦虑也不会把没人管我当成摸鱼的理由而是会主动去降低自己的沟通成本——把问题攒成一批问、把问题问具体、把我试过了什么一起带上。这一条看似是情商问题实际上是效率问题。2. 入职第一周我给自己定的唯一目标就是让代码跑起来很多人在第一周会急着表现想赶紧接需求写代码。我的建议恰好相反第一周不要追求产出追求打通链路。因为在一家成熟的工程团队里写代码本身只占整个工作量的很小一部分剩下的时间全花在环境、权限、工具、流程、沟通上。这些东西不通你写出来的代码根本发不出去。2.1 被严重低估的内部工具链适应成本我在学校做项目流程是装个编辑器、拉代码、跑起来、改、提交。在腾讯的第一周我才知道完整链路长这样申请开发机权限、申请代码仓库权限、配置内部账号、熟悉构建系统、跑通本地编译、接入日志平台、接入监控告警、了解发布流程和审批规则。这其中有一大半不是技术问题是流程问题而流程问题的特点是——它们串行依赖。我踩的第一个坑就在这里入职第一天导师让我先熟悉一下代码我就真的一整个下午在看代码没去提权限申请。结果第二天想动手跑项目的时候发现权限审批要走流程最快的当天下午才下来。白等了大半天。后来我总结出一条顺序实测有效第一天上午把所有需要申请的权限一次性提完包括开发机、代码仓库、构建平台、日志平台、发布系统。不要分批提一次提完。第一天下午在等权限的同时读项目的主流程代码重点看入口文件和核心链路不做深入。第二天权限到位后第一件事是把项目在本地或开发机上跑通哪怕只是一个空请求返回 200也算跑通。第二到第三天把代码仓库的目录结构画一遍搞清每个模块负责什么标出自己可能要碰的那一块。第三到第五天找一个最小的改动点从改代码到提交到发布完整走一遍全流程。这条链路上第 5 步是最有价值的。哪怕你改的只是加一行日志只要完整走通了写—审—合—发的全流程你就从外部人变成了内部人。2.2 第一个任务怎么挑宁小勿大宁熟勿生如果导师让你自己挑第一个任务别挑那个看起来最酷的。挑标准有三个验收标准明确最好是一句话能说清改成什么样算完成的任务。模糊的任务在实习初期是灾难因为你既没有判断力也没有话语权。改动面小但走完整流程比如修一个边界条件的 bug、补一个校验、加一个埋点。它能让你的代码真正上线而不是停在本地。和自己熟悉的技术栈沾边第一周不是证明你学习能力的时候是建立信任的时候。用自己熟的栈先交付一次比用陌生栈硬扛一周要划算得多。我在第一周接的是一个接口参数校验的补充改动不超过三十行但它走完了提交、评审、合并、发布的完整链条。更重要的是评审的时候同事指出了我三个问题全是关于边界和命名习惯的——这三个问题比我在学校写一千行代码学到的都多。2.3 读代码的笨办法反而是最快的面对一个几十万行的代码仓库我一开始的读法是打开一个文件从头看看了两天发现什么都没记住。后来换了个笨办法从入口往下画调用链路。具体做法是找到一个真实的请求比如某个前端页面调用的接口从路由层开始一层一层往下追每追一层就在笔记里画一个方框写上这个函数做了什么、关键参数是什么、有没有缓存、有没有异步。追到最底层数据访问就停。一条链路画完你基本上就理解了这套代码的组织方式再去看别的链路速度会快好几倍。这个方法听着土但它解决了读代码读不进去的核心原因你缺的不是阅读速度是上下文。3. 代码评审这一关暴露出我在学校养成的一堆坏习惯学校里的代码写完就完了跑通就行工程团队的代码写完才刚开始它要过评审要被别人一行一行读。我第一次提代码评审的时候被打了回来理由是改动粒度太大、动机不清、夹带了无关重构。当时我挺不服气后来把那条评论反复看了几遍才意识到人家说的全对。3.1 评审里的显性规则和隐性偏好显性规则一般团队文档里都写了要有单测、要过静态检查、commit message 要规范。隐性偏好没人写但踩一次就懂一次提交只做一件事。修 bug 就修 bug不要顺手把旁边的命名优化一下。夹带改动会让评审人无法判断风险边界。commit message 写动机不写动作。不要写修改了参数校验要写修复某接口在参数缺失时会抛异常的问题。前者描述你干了什么后者告诉别人为什么这么干。注释解释为什么代码本身解释做什么。我一开始喜欢给每一行都写注释其实那是噪音。改动越小越容易过。三百行的大改动可能挂三天三十行的小改动可能半小时就合了。这不是玄学是评审人的心理成本。3.2 被驳回的时候怎么回应才不掉分实习生被驳回是必然的关键在于你怎么接。我后来养成了一个回应模板实测下来效果不错先复述对方的顾虑。我理解你的意思是我这个改动把两件事混在一起了如果出问题不好回滚对吗——这句话的作用是确认你真的听懂了而不是急着辩解。区分必须改和可以讨论。有些意见是硬性规范直接改有些是风格偏好可以说明你的理由但语气要软。用日志或数据说话。如果对方怀疑你的方案有问题别说我觉得不会去把相关的日志、监控、调用量拉出来。改完回一句已按你的意见调整麻烦再看一眼。这句话很短但它让评审人知道该他动作了。我见过有人因为一条评审意见在群里争论半小时最后虽然赢了但在团队里的印象分掉了一大截。技术上的对错不是唯一变量协作体验也是。3.3 我贴在显示器边上的一张自检清单提代码评审之前我会对着这张表过一遍。这张表是我被驳回五次之后攒出来的检查项常见问题边界条件空值、空列表、超长字符串、负数有没有处理异常路径依赖调用失败有没有兜底日志里能不能定位并发场景同一个资源会不会被同时改有没有加锁或幂等兼容性老版本的调用方会不会被这次改动影响可观测性出问题的时候日志和监控能不能看出是哪一步挂了提交粒度一个提交里是不是塞了两件不相干的事命名变量名是不是能自己说明含义缩写别人看不看得懂这张表里的每一项我都真实翻过车。特别是兼容性那一项——我改了一个接口的返回结构本地和测试环境全过差点就上线了结果评审的时候同事问了一句现在有两个客户端在调这个接口老版本会不会解析失败我才意识到这个问题。这种事在学校的课程项目里永远不会发生因为你的代码只有一个调用方就是你自己。4. 需求对齐没做好是我实习期间最大的时间黑洞如果让我只保留一条给后来人的建议我会说把你所有返工的时间加起来至少有一半来自需求理解偏差。技术问题再难你能查资料、能问人、能试需求问题你连自己理解错了这件事都不知道直到做完才发现。4.1 把口头需求变成一页纸我遇到的大部分需求是这样传达的你帮我看下这个页面用户点提交的时候好像有问题你优化一下。——这句话里有价值的信息量接近于零。好像是必现还是偶现有问题是报错还是结果不对优化是修 bug 还是提升性能我的做法是接到这类口头需求后不直接动手先花十分钟写一页纸发回去确认。这一页纸包含四块现象我理解的问题是什么复现路径是什么比如用户在 xx 页面不填某字段直接提交接口返回失败但没有提示。期望改完之后应该是什么样子前端给出明确提示不再直接请求接口。范围我打算改哪几个文件、不动哪几个模块。不确定的地方我拿不准的点列出来请对方确认。这页纸发出去之后经常会出现一种情况对方看完说我其实不是这个意思。恭喜你省下了两天。就算对方说对就是这样你也拿到了一个可追溯的共识后面出问题的时候不至于各说各话。4.2 数据口径这件事一定要当场问死这个是踩过大坑的。我做了一个功能需要统计某个行为的次数我在实现里加了一个计数逻辑。开发、测试、上线一切顺利。上线三天后产品同学过来说你这个数据不对和后台看到的差很多。排查了半天才发现我们对次数的定义根本不一样我统计的是接口被调用的次数产品想要的是去重后的用户数。代码没写错口径错了。而这种错误在写代码的时候是完全看不出来的因为它不是技术问题。从此以后凡是需求里出现统计计数转化率日均这类词我一定会问三个问题分子是什么、分母是什么、要不要去重。这三个问题问出去只要一分钟答不上来的时候对方就会去查查完你们再对齐比上线之后返工便宜太多。4.3 联调为什么总是卡在最后一步联调是实习期间最容易产生无力感的环节因为它卡住的时候问题往往不在你这边。我的经验是把联调拆成几个前置动作联调前先自己用工具把接口打通确认自己的服务没问题再去拉对方。准备一份最简的请求样例包含完整的参数和期望返回发给对方不要截图要文本。约定一个明确的联调时间窗口而不是你有空的时候我们看下。联调过程中出现的问题当场记下来谁的问题、什么时候修、什么时候再对。还有一条经验是不要等到功能全做完才联调。哪怕只有一个字段通了先跑一次把链路上的坑早一点暴露出来。我做第一个跨团队需求的时候把所有逻辑写完了才去联调结果发现双方对字段类型的约定不一致一个用字符串一个用数字全部重做。如果早三天跑一次这三天就省下来了。5. 几个真实踩过的坑以及完整的排查链路这一节我尽量把过程写细因为结论你到处都能看到但怎么一步步找到结论才是能复用的东西。5.1 从本地能跑到测试环境报错的排查链路现象本地自测全过部署到测试环境之后某个功能直接报错。我的排查顺序是这样的一层一层排除先看报错本身。打开日志平台找到完整的错误堆栈看最内层的那一行是什么异常。这一步看起来废话但有相当一部分人卡在这儿的原因是只看了错误摘要没有点开堆栈。比对配置差异。确认测试环境和本地的配置项是否一致——数据库连接、开关项、外部依赖地址。很多本地能跑线上报错都是配置差异导致的尤其是某个开关在测试环境是关闭的。确认依赖版本。看构建产物里的依赖版本和本地是否一致。有一次我遇到的问题是某个库在测试环境是旧版本方法签名不同。确认数据差异。本地测试用的数据是我自己造的字段齐全测试环境的数据是历史遗留的某个字段可能是空。如果报错和空值有关基本就是这里。加日志验证假设。到这一步如果还没定位就在关键路径上加几行日志重新发一版看执行到哪一步断掉了。这次最后定位到的原因是第 4 条测试环境的一条历史数据里某个字段是空的而我的代码假设它一定有值。修复很简单但排查过程花了两个小时。这两个小时的收获是我从此写代码会把这个字段在线上一定会存在吗当成一个必答问题。5.2 一个看起来很简单的字段改动引发的连锁反应需求是给某个接口的返回里加一个字段。听起来是三分钟的事实际过程是这样的加字段本身五分钟。评审的时候被问到这个字段的计算会不会有性能开销去查了一下发现这个字段需要额外查一次库。于是改成批量查加了缓存。又发现调用方有两个其中一个老版本客户端如果遇到不认识的字段会解析失败。于是加了对老版本的兼容处理。上线前发现监控里这个接口的耗时涨了一点虽然不大但确实涨了。最后改成异步补全主流程不受影响。一个加字段的需求最后改了三个文件花了两天。这件事让我明白一个道理在生产环境里没有简单的改动。任何一个改动都要考虑性能、兼容、回滚、观测这四个维度。这不是流程繁琐这是对自己的改动负责。5.3 时间管理上的坑把忙当成有产出这是我实习中后期才意识到的问题。有一段时间我每天都很忙开会、查问题、看文档一天下来累得不行但周报上写不出东西。原因是我把大量时间花在了响应式工作上——谁找我我就去做哪里有问题我就去看看起来一刻不停实际上没有推进任何一个完整的目标。后来我做了两个调整。第一每天上午留出两个小时不看消息只做手头最需要连续思考的那件事第二每天下班前花十分钟写下今天推进了什么如果写不出来第二天就调整。第二件事看起来很简单但它是我那段实习里最有用的一个习惯。因为忙是一种感觉推进了什么是一个事实。6. 让你的产出被看见周报和复盘的写法很多同学觉得周报是形式主义随便写两句交差。我不这么看。周报是你和导师之间最低成本的同步渠道也是他给你写评价时最直接的参考材料。写得好的周报本身就是一种能力证明。6.1 周报里该有什么不该有什么不该有的情绪化的描述这周太累了需求变来变去很烦、没有信息量的进度继续开发中、把所有细碎的事都列上去。该有的大致是这四块本周推进以结果为单位不以动作为单位。不要写研究了 xx 模块要写完成了 xx 功能并在测试环境验证通过。遇到并解决的问题这一块很关键。你解决了什么问题说明了你具备什么能力。下周计划写具体的比如完成 xx 接口的联调和上线。需要协助有卡点就写别硬扛。写清楚卡在哪、你已经试过什么、需要谁帮什么。我第一周的周报写了三百字导师回了一句下次写清楚每个事项的状态。第二周我改成表格形式之后他回了个好。就这么简单。6.2 结束的时候怎么整理一份经得起追问的产出清单实习临近结束一定要给自己整理一份产出清单。这份清单有两个用途一个是给导师做评价参考另一个是给你自己后面写简历。整理方式我建议按事项 背景 我做了什么 结果 数据来写。举个具体的样子事项某接口参数校验缺失导致的失败率偏高。背景该接口日均调用量较大失败请求中有一部分是参数缺失引起的但返回信息对用户不友好。我做了什么补充了入参校验逻辑统一了错误码和提示文案补齐了对应的单测。结果上线后该接口因参数问题导致的失败请求明显下降。数据给出了具体的统计口径比如参数类失败占比从 x% 降到 y%统计周期为一周。注意最后一项。数据一定要写清口径和周期因为面试的时候大概率会被追问这个数怎么算的。如果你写的是下降了很多这种模糊表述追问一句就答不上来了如果你写的是参数类失败占比统计周期为一周口径是错误码归属该分类的请求数除以总请求数这个回答就是站得住的。一个容易被忽略的点整理产出的时候不要只写你独自完成的也要写你参与协作的部分。在团队里能把自己嵌进别人的工作流里、能让事情往前走本身就是很重要的能力。7. 收尾阶段交接、沟通以及一些回头看才明白的事实习的最后一周很多人会松掉觉得反正要走了。这段时间的表现恰恰是最容易被记住的。7.1 交接文档到底该写什么我写交接文档的时候参照的是一个很朴素的标准让一个完全不了解这个模块的人能照着它把环境跑起来并知道哪里可能有坑。具体包含我负责的模块是什么现在的状态是什么已完成 / 部分完成 / 待验证。关键代码在哪个目录核心链路怎么走。有哪些已知问题、有哪些我试过但没解决的思路。相关的配置项、开关、外部依赖。上线和回滚的方式。最后一项最容易漏。我见过有人交接完之后接手的人遇到问题想回滚都不知道该找谁审批。把这个写清楚是对团队的善意也是一种专业。7.2 和导师的那次一对一怎么聊实习结束前主动约导师聊一次。内容不用复杂大致三块这几个月我做了什么、你觉得我哪些地方还可以更好、后续如果想继续合作有什么路径。第二块是最有价值的因为这是在正式场合之外你能拿到的少有的真实反馈。我那次聊完之后拿到的反馈里有一条我记到现在他说我技术上的问题都能解决但习惯先把事情做完再汇报导致他有时候完全不知道进度。他的建议是遇到需要超过一天的活中途同步一次。这条建议跟技术一点关系都没有但它影响了我之后所有的工作方式。7.3 回头看我最后悔的两件事第一件是问题攒得太多才去问。我一开始怕打扰导师把问题憋着结果一个卡点卡了两天。后来我改成先自己试十五分钟试不出来立刻问但把试过什么一起说效率一下子提上来了。在团队里问问题不是不专业憋着不问浪费团队排期才是不专业。第二件是太晚才开始主动争取有挑战的任务。实习前两个月我一直在做边缘的小改动稳重但成长有限。后来我主动找导师说想接一个更完整的模块才真正接触到系统设计层面的东西。如果你也想争取合适的时机大概是入职一个半月左右那时候你已经有了一些交付记录说的话有人听。日常实习这段经历说到底给的不是一份简历上的一行字而是一套做事的方法怎么在信息不全的时候把问题问清楚怎么在没有人给你打分的时候判断自己有没有进步怎么在一个比自己大得多的系统里找到自己的位置。这些东西离开了那个环境依然有用。
返回列表