ARTICLE DETAIL

资讯详情

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

京东PHP笔试真题复盘:从语言基础到高并发架构的考点全解析

京东PHP笔试真题复盘:从语言基础到高并发架构的考点全解析 刚从某个技术群里翻到一份“京东2019春招PHP开发类试卷”的回忆版结合这些年我在电商、教育、SaaS行业写PHP的血泪经验干脆把这套题从头到尾拆一遍顺带聊聊京东这类大厂笔试到底在考什么。这篇文章不是给你背答案的而是帮你看懂出题人的心思——为什么这么问、想考你哪层能力、踩过哪些坑的人会在这里翻车。如果你是准备校招或跳槽的PHP工程师尤其是目标定在一线互联网公司的这篇复盘值得你花十分钟细看。就算你不面京东大厂PHP笔试的套路八九不离十语言基础、数据库、Linux、网络、算法、设计题换汤不换药看懂一套胜刷十套。1. 这套试卷的整体设计与考察逻辑1.1 大厂PHP笔试的考察范围分布先说一个很反直觉的事实京东的PHP试卷PHP语言本身的题目占比并不高。整份卷子更像是一张“后端工程师综合能力摸底卷”PHP只是载体。我当时花时间捋了一遍大概分这么几块PHP语言基础与面向对象大约占两到三成重点在数组函数、变量引用、魔术方法、设计模式这些数据库MySQL索引、事务隔离级别、SQL优化、分库分表占两成左右Linux与网络常用命令、TCP/UDP、Nginx配置与PHP-FPM运行机制占一两成高并发与缓存Redis使用场景、消息队列、缓存穿透击穿雪崩占一两成算法与系统设计手写代码题外加一个开放性的设计题。这个分布其实很能说明问题大厂要的不是只会写CRUD的码农而是能扛住大流量、能定位线上问题、能设计稳定架构的工程师。PHP语法考得再多写出来的代码在双十一流量面前崩了那等于白搭。所以整张卷子的底层逻辑就一句话基础扎实 工程经验 系统思维。1.2 出题人想通过题目筛选什么能力我这些年也面过不少候选人看到这套题的时候特别有共鸣。出题人设置的每个模块背后都有明确的目标语言基础题筛掉那些只会复制粘贴、不懂底层原理的“框架程序员”。比如考变量引用、考数组指针就是要看你是不是真的理解PHP的内存模型而不是只会用laravel写Model。数据库题筛掉那些建表不思考、查询全靠框架ORM的人。索引怎么建、SQL怎么优化一两道题就能看出来平时写代码有没有动脑子。Linux和网络题筛掉那些离开Windows和宝塔面板就寸步难行的人。生产环境都是Linux你不会排查端口、不会看慢日志出了问题就是事故。算法和设计题筛掉那些只会做增删改查、没有抽象能力和扩展意识的人。大厂的需求永远是变化的你写的代码能不能低成本扩展这决定你能走多远。想明白这一层你就知道复习的时候劲儿该往哪儿使了。2. PHP语言基础题深度复盘2.1 变量引用、传值与内存机制的坑这套卷子里有一类题几乎必考就是变量引用。题目通常长这样$a hello; $b $a; unset($b); echo $a; // 输出什么如果你答的是“报错”或者“空”那恭喜你掉坑里了。正确答案是输出hello。$b $a只是让$b成为$a的引用unset($b)只是断开了$b这个引用名并不会销毁变量$a本身。很多人以为unset引用变量会连坐其实是没搞懂引用的本质——它只是一个别名不是指针的拷贝。再看一个考内存的经典题$arr range(1, 100000); foreach ($arr as $k $v) { // do something }这题表面问的是foreach效率实际考的是PHP的写时复制Copy On Write机制。在PHP 5时代foreach里如果不用引用$arr并不会被真正复制只有发生写操作时才会复制。但如果你在循环里写$arr[$k] $v * 2那就会触发整体复制内存暴涨。PHP 7之后引入了哈希表优化和引用计数改进foreach 的行为变好了很多但原理依然值得理解。所以我建议准备笔试时把引用、unset、内存回收这三块绑在一起复习因为它们本质上是一个知识体系——PHP的变量容器和引用计数机制。面试官通常还会追一句“PHP的垃圾回收机制了解吗”这时候你把引用计数、循环引用、gc_collect_cycles()这几个关键词讲清楚基本就能过关。2.2 数组函数与字符串处理的笔试高频点京东这套卷子里数组和字符串相关的选择题大概有四五道不算多但都很刁。比较典型的有这么几类第一类是array_merge和的区别。这题我见到过无数次依然很多人分不清。$a [a 1, b 2]; $b [a 3, c 4]; var_dump(array_merge($a, $b)); // [a 3, b 2, c 4] var_dump($a $b); // [a 1, b 2, c 4]array_merge是后面的覆盖前面的同名键数值索引会重新编号是前面的优先后面的键如果已存在则被丢弃。这个区别在合并配置数组时特别容易踩坑比如你写了一个模块想把默认配置和用户自定义配置合并一不小心用错了运算符线上就会出现诡异的bug。第二类是字符串反转的变种题。反转一个字符串看起来简单但要求中文不乱码strrev就直接废了。常规做法是拆成UTF-8字节序列再反转或者用mb_*系列函数处理。京东这类大厂喜欢考这种题因为电商业务里面涉及大量中文商品名、用户昵称的处理编码问题没踩过坑的人写不出健壮的代码。第三类是数组指针类的问题。$arr [1, 2, 3]; next($arr); echo current($arr); // 2 reset($arr); echo current($arr); // 1这类题现在已经越来越少因为PHP 8里很多数组指针函数都标记为废弃了。但如果你的目标公司还在跑PHP 7的存量代码这类题还是可能出现在选择题里。复习时不需要花太多精力知道current/next/prev/reset/end这几个函数的行为就够了。2.3 面向对象、魔术方法与设计模式面向对象在京东的PHP试卷里占的分值不高题目却很有代表性。有一道题我印象很深大概是问__construct、__destruct、__get、__set、__call、__toString这些魔术方法的触发时机。表面看是记忆题实际上考察的是你写代码时的“魔法依赖程度”。我的建议是魔术方法能不用就不用尤其是__get和__set。它们虽然让属性访问变得很灵活但也让代码变得不可预测。你在框架里看别人代码一个$user-name怎么都找不到name属性最后发现是从数据库某个字段映射过来的这种代码维护起来特别痛苦。笔试里你能写对魔术方法的触发条件就够了但真正写工程代码时克制才是美德。设计模式方面京东这套卷子考过单例、工厂、观察者这几个最常用的。单例模式几乎是必背题因为PHP开发中数据库连接、Redis连接、日志对象都常用单例。但我要提醒一点别光背代码要理解单例的三种经典写法普通静态属性、静态变量、static匿名类的区别以及为什么单例要禁用clone和__wakeup。我曾经在面试别人的时候问过“单例模式能不能被继承之后还是单例”大部分人都答不上来。这不怪他们因为这问题确实偏。但如果你能主动聊到“单例在PHP-FPM模型下其实没什么跨请求意义因为每个请求结束进程就销毁了PHP的单例只能保证一个请求内的重复实例化开销”面试官会高看你一眼——因为你懂PHP的生命周期模型。3. Web安全与核心网络协议考点3.1 京东试卷里反复出现的Web安全问题电商业务是网络攻击的重灾区所以京东这套试卷里安全题占比不低。常见的是给你一段代码让你找出漏洞。最经典的莫过于SQL注入的变种题$id $_GET[id]; $sql SELECT * FROM user WHERE id $id;这题基本是送分题答出“未过滤用户输入存在SQL注入”只是及格。想拿高分你得接着说清楚为什么不能只靠addslashes()或mysql_real_escape_string()防御因为宽字节注入可以绕过转义PDO预处理才是正道。然后还要补充如果业务上必须用拼接SQL的场景比如动态表名、动态排序字段要把字段名做白名单校验。这样一套组合拳打下来面试官才会觉得你是真懂而不是背了面试题。XSS也是必考项。京东这类公司对XSS的重视程度极高因为用户昵称、商品评价、店铺公告这些场景全是富文本处理不好就是存储型XSS。笔试中你需要说清楚输出到HTML上下文要htmlspecialchars($str, ENT_QUOTES, UTF-8)输出到JavaScript上下文要JSON编码输出到URL要urlencode。上下文决定编码方式这句话是安全题的通用解。CSRF的题也出现过考的是防御手段。完整答案是验证Referer不可靠、加Token才是主流、使用SameSite Cookie属性辅助防护。京东这类大厂还会有内部统一的安全组件但笔试的时候你得先讲明白原理再提方案落地。3.2 会话管理与用户认证的实现细节PHP试卷里用户登录和Session管理相关的题几乎年年有。有一道经典题是这样的Session信息存在服务端如果搭建了多台服务器用户的Session怎么共享标准答案是方案选型Session存MySQL最不推荐、Session存Redis方案成熟、Session存Memcached适合读多写少但要注意丢数据风险。京东这题我猜是想考察分布式会话的落地方案以及你知不知道PHP里session_set_save_handler()这个函数可以自定义Session存储。更深一层你要理解为什么Session不能只存在单台服务器的本地文件里——因为Nginx负载均衡到不同机器用户请求一漂移就掉登录态了。密码存储也是安全题的重头戏。你要是还在笔试里写md5($password)基本就告别下一轮了。正确做法是用password_hash($password, PASSWORD_DEFAULT)生成哈希用password_verify($password, $hash)校验。我建议能多讲一步“在大厂规范里密码哈希至少要用bcrypt或argon2并且要加盐”这能显示你关注过实际的账户安全体系而不是只会用框架内置的Auth。3.3 TCP、HTTP与HTTPS的差异题网络协议这块京东的卷子出得比较实。选择题里有TCP三次握手和四次挥手的具体过程问哪些状态出现在客户端或服务端。还有HTTP请求方法的考察比如 POST 和 PUT 的区别、GET和POST的区别。这些基础题不难但你得答得够精确。GET和POST不只是“一个带参数一个不带参数”的区别本质是语义不同GET是安全且幂等的POST不是。浏览器缓存机制对GET友好对POST不友好。这能延伸出大文件上传为什么要用POST、RESTful接口设计里GET/PUT/DELETE都应该是幂等的这类工程判断。HTTPS的握手流程我也在试卷里见过。要答得完整需要说出客户端发起请求 → 服务端返回证书 → 客户端验证证书合法性并取出公钥 → 客户端生成随机对称密钥用公钥加密发给服务端 → 服务端用私钥解密得到对称密钥 → 之后双方用对称密钥通信。这里面关键的考点是“为什么HTTPS要混合使用非对称加密和对称加密”答案是性能与安全的折中。非对称加密安全性高但慢对称加密快但密钥配送困难混合方案解决了这个问题。4. 数据库与MySQL优化实战4.1 索引失效场景与慢查询分析数据库是京东这类电商大厂笔试中的绝对大户分值几乎和PHP语言基础持平。索引相关的题我建议你重点看因为这部分既考理论又考实战。有一道典型的选择题WHERE name LIKE %京东%会不会走索引答案是不会因为前导通配符会让索引失效。这类题我见过无数次但光记住结论远远不够你得能解释清楚索引底层用B树存储B树的最左前缀匹配原则决定了一个查询能利用索引MySQL的查询优化器才能决定是否使用索引。如果面试官甩给你一句“为什么前导通配符不走索引”你如果只会说“数据量少就不走”那就炸了。另一道我印象深刻的是联合索引相关题。假设表里有联合索引(user_id, order_status, create_time)问下面哪些查询会走索引SELECT * FROM orders WHERE user_id 123 AND order_status 1; SELECT * FROM orders WHERE user_id 123 ORDER BY create_time DESC; SELECT * FROM orders WHERE order_status 1 AND user_id 123; SELECT * FROM orders WHERE order_status 1 AND create_time 2019-01-01;这题考验的是你对最左前缀原则和查询优化器的理解。第一条和第三条都能命中索引因为MySQL优化器会调整WHERE条件的顺序看的是语义上的最左匹配。第二条也能受益因为user_id可以定位create_time在索引内有序可以直接利用索引排序避免filesort。第四条没用上user_id索引基本白搭。4.2 事务隔离级别与锁机制事务隔离级别的记忆口诀是“读未提交、读已提交、可重复读、串行化”但京东的题不会让你背口诀而是给你场景让你判断问题。最常见的场景题是有两个事务同时操作一行数据A事务先更新但未提交B事务去更新时会发生什么答案因隔离级别而异。在MySQL默认的REPEATABLE READ级别下B会阻塞等待A释放锁。这时候你得继续往下讲InnoDB的行锁是通过索引实现的如果更新条件没有走索引会发生什么——行锁会升级为表锁导致并发性能陡降。这是线上事故的经典成因一条没走索引的UPDATE把整张表的写锁全占了所有写请求全部堵住。关于间隙锁Gap Lock很多初级工程师完全没概念。间隙锁是InnoDB在REPEATABLE READ级别下为了解决幻读引入的机制。它在某个条件的索引范围内加的锁不仅锁命中的记录还锁记录之间的间隙。面试中你能主动讲出这个并说明幻读到底是怎么产生的面试官基本会给你加分。4.3 分库分表与读写分离的工程实践京东的业务量决定了试卷里一定会出现分库分表相关的问题。常见问法是单表数据量超过千万查询越来越慢怎么解决一般回答是一步步来。第一步先做SQL优化和索引优化冷热数据分离比如订单表只有3个月内的需要高频查询归档到历史库利用缓存扛读流量。第二步是读写分离主库负责写、从库负责读但要考虑主从延迟对业务的影响比如电商下单后用户立刻查订单刚下单的数据还没同步到从库用户会看到“订单不存在”。解决方案是“直连主库读”或者“延迟兜底”。第三步才是分库分表按用户ID或订单ID取模或者按时间分表分表之后还要注意跨分页查询、分布式ID、事务一致性问题。大厂笔试里你能把这三步说清楚并且说出每步的代价这题就稳了。我见过很多候选人一上来就要分库分表反而暴露了没经验——因为分库分表的成本和复杂度极高互联网公司能不分就尽量不分先靠缓存、索引、读写分离扛扛不住才分。5. Linux与Nginx/PHP-FPM的实战考点5.1 高频Linux命令大盘点京东这套卷子里的Linux题目难度适中不会考你冷门的awk脚本但常见命令和排查思路是必考的。我记得有道题是线上PHP出现502 Bad Gateway错误你用什么命令排查这题我在面别人的时候也爱问因为它的答案非常开放能看出候选人有没有真实的线上经验。理想的回答流程是先用top看CPU和内存情况如果是PHP-FPM进程CPU满再用ps -ef | grep php-fpm看进程数查/usr/local/php/var/log/php-fpm.log看有没有max_children报警再用netstat -an | grep 9000 | wc -l看PHP-FPM的连接数确认是不是请求堆积。如果怀疑Nginx层的问题再查Nginx的错误日志。这一套组合拳下来面试官基本可以确认你处理过线上故障。另外crontab也经常出现因为定时任务在电商后台里特别多比如结算、对账、优惠券过期扫描。有一道题问crontab里*/5 * * * *和5 * * * *的区别前者是每5分钟执行一次后者是每小时的第5分钟执行一次。如果你在笔试里答反了说明平时定时任务写得少。5.2 Nginx的FastCGI配置与PHP-FPM运行机制Nginx和PHP-FPM的搭配是PHP开发者的基本功京东试卷里出现的相关题也很有代表性。最经典的是请求从Nginx到PHP执行完返回整个过程是怎样的你需要完整说一下Nginx收到HTTP请求如果是静态文件直接返回如果是PHP文件则通过fastcgi_pass指令将请求转发给PHP-FPM监听的socket一般是127.0.0.1:9000或Unix socketPHP-FPM的worker进程解释执行PHP代码把结果返回给NginxNginx再包装成HTTP响应返回给客户端。这里面FastCGI是一个协议PHP-FPM是协议的具体实现它是个独立的进程管理器Nginx和它之间通过FastCGI协议通信。这个链路理解了你就明白为什么请求Nginx返回502、504时大概率是PHP-FPM挂了或执行超时。配置层面有一道题常考pm.max_children怎么设置说实话这题没有完美答案但你可以给出合理的分析思路要考虑服务器的CPU核心数和每个PHP进程平均占用的内存。一般来说每个PHP-CGI进程占用30MB到80MB内存如果机器内存是8GB留出2GB给系统和Nginx、MySQL那max_children可以设为(8GB - 2GB) / 50MB大约100到120之间。这比直接说“设成100”要专业得多。5.3 从试卷里的考点看线上问题的排查步骤大厂笔试很少直接考“某条命令的某个参数”而是考一个场景和排查思路。比如用户反馈下单接口特别慢你怎么排查我的排查路径一般是先看Nginx访问日志和后端响应时间确认是Nginx到PHP之间的网络问题还是PHP执行本身慢。然后看PHP-FPM的慢日志slowlog它会记录执行时间超过阈值的请求和堆栈如果发现卡在MySQL查询上就把对应SQL拿去看执行计划确认有没有走索引。如果卡在Redis上就看Redis的慢查询日志和内存是否满。如果都正常再看外部HTTP调用比如下单可能要调用支付接口第三方响应慢会拖垮整个接口。这套排查思路无论哪个大厂面试都吃香因为它的核心不是背命令而是“分层排查、逐层压缩问题范围”。京东的试卷考察的正是这种工程思维。6. 缓存、队列与高并发设计题6.1 Redis的缓存穿透、击穿与雪崩京东这套卷子里Redis相关的内容明显偏多这也符合电商场景。我印象最深的是一道简答题什么是缓存穿透如何解决缓存穿透是指查询一个不存在的数据缓存和数据库都没有请求直接打到数据库上。如果有人恶意构造大量不存在的ID数据库瞬间就会被压垮。解决方案有缓存空值并设置较短TTL、使用布隆过滤器在缓存前置过滤、接口入口参数校验拦截非法请求。其中布隆过滤器是面试加分项但你要理解它的本质——用少量内存判断一个元素“一定不在集合中”或“可能存在于集合中”有误判率需要设计好哈希函数数量和位图大小。缓存击穿和雪崩也要能区分。击穿是指某个热点key过期的瞬间大量请求同时打到数据库雪崩是指大量key同时过期导致数据库压力激增。针对击穿常用互斥锁只让一个请求去重建缓存、逻辑过期不过期但字段里带逻辑过期时间、热点key永不过期。针对雪崩可以给过期时间加随机值、多级缓存、熔断降级。京东的卷子特别喜欢考这三个词的区别因为它们表面上很像背后的解决方案完全不同。6.2 消息队列在电商场景中的应用队列相关的题在试卷里也有出现比如下单成功后需要给用户发短信、发优惠券、更新库存、生成订单快照如果同步执行用户要等很久怎么办标准设计是把这些非核心步骤丢进消息队列异步消费。消费者按顺序执行扣减库存、生成订单、发送通知。京东在业务中常用的消息中间件是RocketMQ和Kafka但笔试里一般不会限定具体产品重点看你对消息队列模型的理解。你需要说清楚为什么用消息队列而不是多线程因为多线程在同一台服务器上处理不了跨服务调用而且PHP默认不支持多线程。消息队列则天然支持异步、削峰填谷、系统解耦。假如秒杀瞬间来了10万请求数据库根本扛不住消息队列先把请求收下来后端按消费能力慢慢地处理这就是削峰。事务消息和消息幂等性也是加分项。比如下单和发消息要保证一致不能出现订单创建了但消息没发出去。对应的方案是本地消息表、事务消息或最终一致性。消费者这边要考虑消费失败重试消费成功后要记录偏移量避免重复消费导致发两次短信。这些细节说透了面试官会认为你有真实项目落地经验。6.3 秒杀场景等系统设计题的答题框架京东试卷的大题里有一类开放性的设计题特别典型比如设计一个秒杀系统。这种题没有标准答案但你写下的内容一定要有层次感我建议按这个框架答第一层限流。接入层用Nginx的limit_req模块做IP限流或用Redis Lua脚本做更细粒度的用户限流。第二层防超卖。不要在应用层用SELECT 库存 0再UPDATE的普通操作那会出现超卖。要用Redis的原子操作扣减库存或者用数据库的乐观锁UPDATE stock SET stock stock - 1 WHERE stock 0确保同时只有一个请求能扣减成功。第三层异步化。秒杀请求进来直接写消息队列马上返回“正在排队中”后台慢慢消费用户轮询结果或收到通知。第四层缓存。秒杀商品的库存信息提前预热到Redis避免一波流量把数据库打崩。第五层限流与降级。超过系统能力时直接返回失败让用户下次再试。这个框架能覆盖绝大多数系统设计题的答题思路不只是秒杀抽奖、优惠券抢购也适用。核心是让面试官看到你有分析高并发系统的完整思路而不是只盯着某一个技术点。7. 试卷里最容易丢分的几个地方7.1 代码规范与边界条件处理的隐形扣分点有一类丢分不体现在答案对错上而是体现在代码细节里。比如手写一个二分查找90%的人能写出主体逻辑但会忽略空数组判断、边界条件left right写错、中间值计算溢出。PHP里写$mid intdiv($left $right, 2)虽然一般不会溢出但养成防御性编程习惯总没错。还有一类是函数返回值类型不明确。题目要求返回int你写个return $result;而$result可能是字符串。PHP是弱类型语言笔试中看不出问题但面试官会问“如果输入的是非法值怎么办”。你提前加好参数类型声明、异常处理、默认值这些隐形加分项比奇技淫巧更能打动面试官。7.2 从答题习惯看候选人的工程素养我在做这套题复盘的时候发现一个很有意思的门道笔试不只是看你会不会还看你怎么写、怎么写注释、怎么组织答案。举个例子一道SQL优化题有的候选人只写一句“加索引”有的候选人会把建索引的SQL写出来并且标出索引字段的顺序、说明为什么这么建。后者明显更像一个负责任的后端工程师。还有手写代码题有些人上来就写写完也不检查有些人会先写一两行“这里假设输入非空”、“这里先参数校验”让面试官一眼看出你有生产级代码的习惯。笔试中暴露的答题习惯往往比正确答案本身更能反映你的水平。8. 针对这套试卷的复习建议8.1 语言基础别只背结论要写代码验证PHP 语言基础的复习没有捷径但有个很高效的方法把你不太确定的每一道选择题都写成代码实际跑一遍。比如$a $b和array_merge($a, $b)的区别你亲手跑一次记得比看十篇博客都牢。PHP命令行模式下php -r ...就能快速验证非常方便。对于魔术方法、面向对象、设计模式我的建议是别只准备理论。自己写一个简单的单例类、写一个带__call的代理类模拟property在框架里的实现方式。笔试中如果出一道“用PHP实现一个观察者模式”你能直接写出来比背一百个概念都强。8.2 数据库与缓存要结合业务场景复习数据库和缓存的题最怕的是脱离场景硬背理论。我建议你结合电商的典型场景来复习商品详情页缓存怎么做购物车怎么设计表结构订单状态流转用什么策略保证一致性每个场景背后都能引申出索引、事务、缓存、队列的知识点。如果你没有电商经验就自己设计一个简单的在线书店系统把商品、用户、订单、库存、优惠券五张表建好然后针对“下单减库存”这个操作把整个链路写一遍。写完之后把并发翻十倍思考哪里会出问题、怎么优化。这个过程走一遍比刷50道题实在。8.3 最后的查漏补缺清单临考前可以拿下面这个清单自查一遍。如果哪一项你答不清楚就说明有知识漏洞需要补PHP的垃圾回收机制和引用计数include和require的区别与加载路径规则和在PHP 7/8中的精度差异处理文件上传时如何防范恶意文件如何设计一个防止重复请求的接口幂等方案MySQL的隔离级别默认值和各自优缺点数据库层面如何实现乐观锁和悲观锁Nginx的平滑重载和日志切割方法Redis的数据类型和底层数据结构手写快排和二叉树的层序遍历。这套清单实际上也是我在带新人时反复强调的内容。说实话我当年自己面京东的时候也没答得很完美有些题事后回想觉得“应该再往深了说一点”。但正是那次面试让我意识到大厂考的不是你背了多少东西而是你能不能在一个具体问题面前给出有逻辑、有深度、有落地方案的思考过程。这套2019年的卷子放到今天依然有价值因为PHP的很多底层原理没有变MySQL、Nginx、Redis这些核心组件也没有变。变的只是公司对候选人的要求越来越高以前会把“用过Redis”当加分项现在已经是必备技能了。所以心态放平稳把这些基础原理吃透任何一家公司的PHP笔试对你来说都会变得相当友好。
返回列表