说实话我很少把相亲当项目复盘但那次实在值得记下来。一位女生在餐厅里打开手机对我说“给你一道LeetCode题不能搜题解十五分钟先讲思路再写代码能跑就直接发我。”我当场愣了一下不是因为被考而是那一刻她的表情特别像测试用例跑挂了之后还坚持要你来修修复的QA。如果你有被突然丢一道算法题的经历或者你本身就是那种喜欢用题目判断别人的人这篇文对你应该有点用。我会尽量把当时的思路、题目的解法、背后的心态以及我后来反思出的几条经验都讲清楚。1. 相亲遇到编程题现场到底发生了什么1.1 从“聊到哪了”切换到“需求评审”的那一刻那天我们本来聊得还挺好。聊到工作节奏时她问了一句“你平时真的会自己写算法吗还是说上班只需要CRUD”我顺口说自己偶尔会刷题保持手感。她立刻来了一句“那正好我给你出一道LeetCode题。”听到这句话我心里咯噔一下。倒不是因为怕题而是这个场景太像早年去大厂面试。她出的是一道经典二分查找题大家习惯叫它“爱吃香蕉的狒狒”。大意是一堆香蕉piles每个小时吃掉一“把”食堂阿姨要求必须在h小时内全部吃完问最小的每小时进食速度是多少。我大概用一分钟把模型盘了一下吃香蕉速度speed最低是1最高就是最大那一堆的数量因为再快没有意义反正一堆一次最多也就吃一“把”。那么答案就落在一个区间里典型的二分查找。关键检查函数是给定speed算出每个pile需要的小时数总和小于等于h就说明可行。因为一堆香蕉如果吃不完一整份下一轮还是要回来吃所以每堆耗时就是向上取整。我顺手写了个简化版def minEatingSpeed(piles, h): def ok(speed): hours 0 for p in piles: hours (p speed - 1) // speed return hours h left, right 1, max(piles) while left right: mid (left right) // 2 if ok(mid): right mid else: left mid 1 return left她看完代码之后问“你没用库函数手写这个边界条件有没有想过left和right会不会死循环”我说left right 除以二取整mid不会等于right所以不会死循环关键是当ok(mid)成立时我保留mid本身因为mid可能是答案。她点点头没有继续追问。1.2 她不是在考答案而是在看我怎么处理“坏味道”这个题本身不难但我后来回看当时的细节发现她整个“面试官”上身的过程中真正在观察的是几个点。第一面对突然提问我会不会先抱怨“这跟相亲有什么关系”。程序员在突发需求下的第一反应往往比代码能力更说明问题。第二我能不能把思路拆开讲而不是直接甩代码。第三我有没有主动问边界条件和输入范围。第四我写错的时候是急着遮丑还是承认然后修正。她后来承认那题选的就是LeetCode经典题因为网上能搜到很多题解但能当场讲清楚时间复杂度和边界判断的人说明是真的啃过。她还补了一句“很多人刷了三百多题但问一句‘为什么用二分’就答不上来。”这让我想起软件测试里的一个道理测试用例通过不代表模块没问题只能说明这一组条件下它没出问题。一个人会背答案、能默写题解和她跟我讲得清“为什么”根本不是一回事。1.3 一场没有死循环的“对线”最后变成了什么我后来没急着问“我这算过还是不过”而是反过来问她“你平时刷题吗”她说她不是程序员但带过的实习生需要过算法筛所以她也跟着看过题。这句话让气氛一下子松下来了。本来我以为她是要用LeetCode测试我后来才明白她更像给我一个机会让我展示自己处在压力下是不是一个能好好沟通的人。那种感觉就像产品经理突然塞过来一个临时需求共享软件工程师伸手欢迎你喜欢它我们在零断言的互信里把整个逻辑走通。那天到最后我们都没再聊算法而是聊到了为什么程序员准备面试时要把知识结构掰开揉碎。这次经历让我想到一个更现实的问题许多程序员已经把刷题练成了条件反射但一到真正需要解释思路的场合就卡壳。这不是算法功底不够是表达训练太少。2. 用LeetCode做“隐形测试”的人到底在测什么2.1 单次测试永远是小样本别把结果当结论先泼一盆冷水如果一个人靠一道题去判断另一个人那这次测试大概率是偏差很大的。一道题只能证明对方在某个时间点、某类问题上熟悉或不熟悉。它没法测量职业素养也没法测量责任心。我见过不少工程师单独拎一题出来都答得不错但项目里遇到模糊需求根本不会拆解。反过来有些看着很慢的同事让他处理线上问题他能一步一步推理到根因。LeetCode更像一把尺子而且是一把只量宽度的尺子。你拿尺子量高度测量结果自然不准确。所以如果你是提问方你至少要设计一组能覆盖不同维度的东西来测。算法题可以看思维习惯但要判断一个人能不能一起做项目还得看他对需求的理解、对错误的反应、对时间的估算对别人观点的接纳。这些都不是一道题能暴露出来的。那她到底有没有资格考我我觉得完全有。任何人都有权用自己的方式去了解另一个人只要方式不至于伤害对方自尊。但我也提醒自己出题人如果只能靠LeetCode来测试相亲对象说明她其实也在依赖一个现成的题库来回避困难的对话。2.2 面试是双向的测试同样需要有来有回回想我自己的面试经历很多候选人在被问算法题时都会小心翼翼地把话说满生怕露馅。这种状态本质上是“防御型沟通”。它会让沟通变得特别累你在猜对方想听的答案而不是真的在讨论问题。更好的做法是把输入输出、数据范围、极端条件一次性讲清楚。这很像测试工程师的工作习惯。我认识的一位资深测试朋友常说测试不是拿着你最喜欢的用例去验证系统有多好而是拿着尽量极端的输入去把它搞挂。这种心态放在沟通里同样成立如果你能坦然接受被质疑再修正自己的结论比答对题目更加分。我在那次相亲里做对了一个动作我先问她输入的规模大概是多大如果h小于piles长度那题根本无解。这个问题看起来简单却展示了一种工程习惯。她没有觉得我事多反而说“这就是我在代码评审里想看到的东西”。2.3 被测试的时候别急着证明自己先识别对方的需求后来我琢磨出一个很实用的经验无论是相亲对象突然丢来一道LeetCode题还是面试官在电话里让你原地手写代码你的第一个任务不是答题而是判断对方到底想要什么。如果对方想要的是“快速解决眼前的问题”那你要尽快给出可行的通解。如果对方想验收的是“你的思路习惯”那你就要主动把时间复杂度和边界条件都讲出来。如果对方只是想看你是否能把一个复杂概念讲得让外行人听懂那你就不该花时间秀高级数据结构而该用最朴素的语言拆解过程。这三种需求对应完全不同的回答策略。很多擅长刷题的人栽在面试里多半因为他们只准备了一个叫“标准答案”的东西却不能根据对方的语气和题库选择自我调整。说到底程序员面对的不是机器是人。机器只认输出人还要看你输出的方式。3. 别让“刷题惯性”变成新时代八股文3.1 初级程序员最大的危险是只会“解题”不会“解决问题”最近网上总在讨论AI能否取代初级程序员。说实话如果一名程序员的工作就是“别人把需求描述清楚我照模板写代码”那确实非常危险。AI已经能把很多模板化代码写得又快又完整错漏还少。如果你只做这些事你能提供的增量就很有限。但换一个角度工作里最不缺的就是需求模糊。用户说自己想要一个“快点儿的系统”你说“我加几个索引就快了”还是在动手之前问他哪个页面慢、并发有多高、数据量有多大、有没有要求强一致性后者才是真正的工程判断。算法题训练的是单一问题下的一种理想化推演能力。可真实的系统像一个老城区下面埋着无数根旧管道你以为问题的答案在算法上其实在一堆错误的配置里。这就是为什么我坚持一个观点LeetCode可以帮你敲开大门但能不能混得久看的是你有没有办法把“模糊业务”翻译成“可验证的技术方案”。我也会用AI辅助解决问题比如让它帮我补全测试用例、生成某个工具的调用示例但我一定自己读一遍输出再往上接。因为AI能生成一个表面正确的东西也可能生成一个边界条件完全没考虑、错误处理被吃掉的东西。你要能看懂它为什么错才能防止线上事故。这不只是程序员的职业底线也是测试人看待“新工具”的基本警惕工具可以做很多事但验收责任仍然在人。3.2 我自测程序员核心功底的三个方法如果你也想检验自己是不是真的具备工程能力而不只是刷题熟练我建议你拿三把尺子量一量。第一能不能把一个运行中的项目从头讲清楚。大到系统依赖什么服务小到一条慢SQL为什么慢你能不能讲到外行听懂一半。第二能不能在接手别人的代码后不吐槽老代码烂而是写出一点让后来人更容易理解的注释和测试。第三能不能在“AI给了一段代码”之后立刻指出其中至少一个潜在边界问题。这三个问题一道LeetCode题是考不出来的。有位老前辈打过比方解题像游泳比赛工程像在海里救人。游泳比赛有固定泳道、有裁判员你游得快就是厉害。海上救人有浪流有陌生人的恐慌有时你甚至要判断该不该直接跳下去。会游泳是基础但只会游标准泳道的人第一次见到海浪时反而容易慌。3.3 复盘那道“吃香蕉”题它确实让我重新看算法既然题目都出现在这段经历了我就多聊一句那题的精髓。很多人一上来会写一个循环从1试到max(piles)找到第一个满足条件的speed最坏情况要O(max(piles) * len(piles))。如果piles里最大那堆是10的9次方级必然超时。把单次尝试转换成二分查找之后时间复杂度变成O(len(piles) * log(max(piles)))。这就是很多算法题的本质先发现答案单调变化再用有序搜索的方式减少尝试次数。吃香蕉速度越大总耗时越短寻找最小的满足值就是在“[1, max(piles)]”这段降序区间里二分。这种思考方式在真实系统里很常见比如排查一个磁盘占用峰值你不会一分钟一分钟地看而是先翻日志、再按天缩小范围最后精确到秒。那次以后我给自己定了个规矩每做完一道题必须用“场景化”方式讲一遍给周围的人听讲不出来的就是没有真懂。后来我面试也喜欢加一轮追问“如果输入是小数怎么办如果是空数组呢”这其实就是在考察对方有没有主动扩展边界条件的习惯。4. 程序员被测试后应该有怎样一套后续动作4.1 那次相亲的结果我没必要掩饰是的这题最后她没有给我“通过”或者“不通过”而是笑着说“还行再看”。我们后来又约了一次专门聊各自的工作她把她的项目管理心得讲给我听我把做代码评审时的“狠话”标准讲给她听。但最终没走到一起原因跟技术完全无关。为什么我还是要写这篇文因为那次被“测试”的经历给了我一个很真实的角度很多程序员朋友抱怨别人不理解自己可一旦有人真的愿意用一个具体题目来接近我们的世界我们有些人反而会冷冰冰地觉得对方冒犯。这不对。我们应该把“测试”当成一种沟通入口而不是一场防备战。对方愿意花时间了解你在做什么这本身就值得尊重。即便她的方式有一点像线上面试你也可以把气氛拽回到平等对话的轨道上做法就是认真答完题之后反问几个同样有含金量的问题。4.2 给程序员的两条避坑建议第一别在没有需求确认的情况下直接埋头写代码。哪怕是相亲现场丢来一道题也先问一句“你希望我用简单方式解还是专业方式解”这道题可以有暴力解、二分查找解甚至贪心策略根本行不通。先对齐验收标准再动手是程序员防止返工的关键习惯也是被测试者缓冲压力的方式。第二不要把“能背出多少题解”等同于“技术核心竞争力”。我见过太多人和网上那份Java八股文较劲却拿不出一份自己负责过的复盘报告。你背过一百个面试题不如认认真真理解一个小系统的业务闭环并能说出它在什么情况下会挂。AI越来越擅长填空人要做的是给这个空定义边界。反过来说如果有一天你要像她一样“测试”别人也请选择一种有建设性的方式。不要只丢一个标准题然后等人默写。可以试着丢一段有很多毛病的小代码问对方“能找到几个潜在问题”或者丢一个业务场景问他会怎么拆解。这才会让高手有空间展示也让新手不至于被一道题堵死所有表现机会。4.3 从相亲场景引出的测试设计思考说到测试那晚我其实还想到过一层软件开发里有单元测试、集成测试、端到端测试却不能靠单一用例覆盖整个系统。人和人的了解也一样。用一道题去认识一个人相当于只用具体的输入输出判断整个模块覆盖面太窄。要了解一个人至少要经历几次意见不同、几次合作赶工甚至一次共同面对外部压力。所以如果你真有耐心去了解程序员我建议你让他讲一次自己线上修复故障的经历比背题有意义得多。你会很快看到他会不会第一反应甩锅给上游服务会不会主动提供止损方案会不会事后补充监控报警会不会冷静地把经验总结成团队文档。这些才是程序员在真实世界的“高可用性”指标。结尾处再讲个实在的经验。我自己后来再做LeetCode题已经戒掉了“AC之后马上看题解”的习惯而是先写完再问问自己“这题如果放到真实系统里是出于什么原因才需要这么做”当你能把一道算法题讲成一个带业务的故事它就不再是考试包袱。就像那次相亲真正有用的不是我把二分写得多么干净而是我们聊完之后都对“程序员的判断力”有了更具体的理解。如果你也想给身边人解释程序员到底在忙什么不妨反过来给他们做一次“人工测试”让非程序员朋友先根据直觉判断一个需求该不该做然后你再告诉他开发为什么要先问边界。那道LeetCode题只是开胃菜我们的“菜谱”从来都比代码要宽。