# 面试官:“项目这么问,把你水分挤干!”

作者:小傅哥
博客:https://bugstack.cn (opens new window)

沉淀、分享、成长,让自己和他人都能有所收获!😄

八股文整的挺好,算法也刷的够多,但问到项目就很拉胯。 这可能是现在大部分没有实际项目经验的校招生一直从事边角料开发的社招生所面临的问题。

当越来越多的人,想通过取巧的方式找到捷径来拿Offer。那么这条线就会被不断的拉齐,直到越来越多的人都成了八股和刷题高手后,招聘的方式也会改变。—— 面试官不在直接问八股,而是从项目中提问,反向映射出技术和算法问题。

刚你说峰值QPS3000,RT1.2s,但你简历里写这个项目双机房部署4台实例🤔? 面试官会通过一些实际场景来了解你是否做过项目,在项目中遇到什么样的问题,你是怎么解决的,使用了什么技术方案。而这样的提问必须是求职者真的做过这些,否则很难把背过的八股题和实际项目联系起来。

所以小傅哥以多年的编程经验和落地能力,通过一个实际项目来给大家讲解下都会遇到哪类面试问题,该如何回答。你可以把这当成一场模拟面试

# 一、简历:项目经验

这里以小傅哥的《Lottery 抽奖系统 - 基于领域驱动设计的四层架构实践》项目所体现到简历中的案例进行展示,如果想了解这个项目,也可以先看下视频介绍。

之所以选择这样一个项目开发,是抽奖营销活动类系统可以适应的场景更全面,例如;电商、出行、外卖、旅游、汽车等,在促活、留存、拉新上,都可以使用抽奖系统。因为抽奖系统是工具系统,可以挂到任何其他符合场景的系统上来讲解。而且抽奖系统的架构、设计、实现都较为复杂,有东西可以聊,属于尖刀队。类似 Java 中的 HashMap 随时可以拿出来刚以下。

所以抽奖系统不存在说:“你们组多少人都做抽奖”,因为所有场景,只要符合就会有抽奖和活动,如果一个公司的产品没有营销业务这条线,那么一种是场景不符合,另外一种是压根没这个体量。所以只要你把抽奖合理的放到一个系统下,串联好你的话术能自圆其说,之后你就可以用抽奖去面试了。


  • 项目名称:营销活动平台 – Lottery 微服务抽奖系统
  • 系统架构:以 DDD 领域驱动设计开发,微服务拆分的分布式系统架构
  • 核心技术:SpringBoot、Mybatis、Dubbo、MQ、MySQL、XDB-Router、ES、ZK
  • 项目描述:Lottery 抽奖系统,是营销活动平台中的一个重要微服务,用于满足C端人群拉新、促活、留存的系统。系统根据微服务的界限上下文,运用抽象、分治和 DDD 知识,拆解服务边界、凝练领域服务功能。以围绕抽奖服务,解耦功能流程,建设领域服务,包括:规则引擎、抽奖策略、活动玩法、奖品发放等。来满足业务产品快速迭代上线的诉求,减低研发持续投入成本,提升交付效率。
  • 我的职责
    • 构建以 DDD 分层结构的处理方式,搭建整个抽奖系统架构。
    • 运用设计原则和工厂、代理、模板、组合、策略等设计模式的综合使用,搭建和开发方便维护和易于迭代的系统工程。
    • 鉴于系统内有较多的规则策略过滤,包括:准入、人群、风控、A/BTest等诉求,以适合系统规模可快速开发和使用的方式,搭建去中心化的量化人群规则引擎组件,通过业务诉求对 Logic 的扩展和内置引擎执行器的使用,完成自由组合的人群过滤服务。降低共性功能重复开发所带来的成本问题,提供研发效率。
    • 应实际秒杀峰值场景 TPS 2000 ~ 3000 的诉求,开发统一路由组件,不仅可以满足差异化不同字段的分库和分表组合,以及 Redis 库存分片和秒杀滑动库存分块,开发统一路由 XDB-Router 的 SpringBoot Starter 技术组件。此套组件经历数次大促活动场景,支持横向扩展,可以满足业务规模的快速增长。

# 二、模拟:面试问题

# 1. 数据质疑

面试官一定会通过简历的项目描述,首先对你所描述内容的一个质疑。因为毕竟面试官是不了解你的,所以会通过质疑的方式来判断这样一个项目是否能有因有果,承上启下,自圆其说。

# 1.1 这个营销系统是之前就有,你去接手了。还是你从0到1构建的

  • 题目:这个营销系统是之前就有,你去接手了。还是你从0到1构建的。
  • 解答:如果是公司的项目,有几种情况;
    1. 原来有一个抽奖系统,但设计实现上不好满足业务需求,代码维护成本越来越高。所以开始重新架构设计从0开始开发。
    2. 进入公司后,刚是公司开始准备在核心业务上做营销拉量的时候,所以从0开始搭建开发。这个过程中做了大量的技术调研和架构设计评审。
    3. 进入公司后是一个已经存在的项目,为了更好的支撑业务快速迭代,对系统进行重构。设计了新的模块;规则引擎、策略算法【可以多几种抽奖方式】。
  • 画外:几种不同方式的回答,也会牵扯到后续提问中的一些问题点。别回答回答着,前面说从0搭建的,后面解答不上来的问题,又说是其他同事之前遗留的。

# 1.2 线上是部署的机器数量和规格是什么样,几核几G的机器,部署了多少台?

  • 题目:线上是部署的机器数量和规格是什么样,几核几G的机器,部署了多少台?
  • 解答
    1. 这个回答到不难,但你所描述出的机器数量会牵扯到系统所能承载的峰值流量,比如;通过双机房部署了4台4核8G的服务器。
    2. 同时这里也可能提到服务器带宽问题,像互联网大厂中至少是千兆网卡,核心应用都在万兆网卡。以10M公网宽带举例,下载速度在1.25M/秒 = 1280KB/秒。如果一个网站加载是30KB,那么 1280/30 ≈ 42,也就是10M带宽能支撑42个并发在1秒打开。所以通过你提到的这些数据,面试官也是能粗略估计出应该能在多少流量。

# 1.3 简历上系统峰值QPS3000,RT1.2s,但你刚说是双机房部署了4台应用实例,这个数据准确吗?

  • 题目:简历上系统峰值QPS3000,RT1.2s,但你刚说是双机房部署了4台应用实例,这个数据准确吗?
  • 解答
    1. 这里有一个基本的公式,并发数 = QPS * RT【响应时间/秒】,那么 QPS 3000 * 1.2秒 = 3600个并发。4台应用实例 * 150【默认tomcat配置】 = 600 并发。虽然这是评估值,甚至 tomcat 也可以配置到 200个并发,但这个值仍与 3600 有较大差异,所以会被质疑。
    2. 这里还会牵扯到数据库的配置,数据库总连接数是多少,每台机器应用实例分配的连接数是多少。所有占用的连接数一定是小于总连接数的,否则连接池被打满,可能会出现几万毫秒的慢查询,直至拖垮数据库,让整个系统崩溃。
    3. 再举例个关于流量评估的场景【28法则】,可以根据这个评估自己的系统QPS;系统有1000万用户,那么每天来点击页面的占比20%,也就是200万用户访问。假设平均每个用户点击50次,那么总用有1亿的PV。一天24个小时,平均活跃时间段算在5个小时内【24*20%】,那么5个小时预计有8000万点击,也就是平均每秒4500个请求。4500是一个均值,按照电商类峰值的话,一般是3~4倍均值量,也就是5个小时每秒18000个请求【QPS=1.8万】
    4. 对于一个真实场景的系统来说,所有的评估数据都只能作为压测配置参考数据。因为接口的逻辑不同,所以也可能倒置并发数的高低。所以像各大互联网在大促前要进行接口的血脉梳理和服务器配置调整,并进行N轮压测和优化,这样才能拿到一个准确的数据。

# 2. 架构设计

# 2.1 为什么使用DDD,主要用于解决什么问题?

  • 题目:为什么使用DDD,主要用于解决什么问题?
  • 解答:从软件的复杂度和需求迭代次数来看,最开始的开发成本并不是最大的。因为在长周期迭代中,后期的维护成本才是最大的。那么对于这样的系统来说,更易维护就显得非常重要。而 DDD 恰好以领域为核心设计,分拆业务逻辑为独立的模块,在通过应用层编排的方式对外提供服务,这样更加容易扩展。

# 2.2 DDD架构和MVC架构有什么区别?

  • 题目:DDD架构和MVC架构有什么区别?
  • 解答
    • MVC:更偏向与数据建模实现,由数据调用驱动,所以也就引申出的DAO、PO、VO类会随着项目开发不断的膨胀,不易于迭代和维护。
    • DDD:以业务流程提炼领域模型为驱动,设计和实现模块开发,在一个领域中包含mode对象、仓储数据、服务实现,也更注重设计模式的使用,否则实现的DDD徒有其表更多的只是归类了 DAO、PO、VO 对象。

# 2.3 抽奖系统的核心域,支撑域和通用域分别对应哪些呢?

  • 题目:抽奖系统的核心域,支撑域和通用域分别对应哪些呢?
  • 解答
    1. 不同视角下其实解读为不同的域,其实也都可以【你这样列举也ok】。一般我们把主线流程成为核心领域,用于支撑主线流程的算作支撑领域或者核心子域。
    2. 那么我们现在以抽奖为整个路线看,需要有3个步骤;参与、执行、兑现。也就是对应的活动、抽奖、奖品。而规则引擎其实没有也能完成抽奖,并且规则引擎也可以适用于其他模块下,所以它可以被看做是通用域/核心子领域。

# 3. 技术深度

# 3.1 近期用抽奖项目去面试,老被问到有没有线上出现CPU或内存飙高等线上问题,让我说说具体的场景以及如何解决的。

  • 事故级别:P0
  • 事故判责:营销活动推广用户较多,影响范围较大,研发整改代码并做复盘。
  • 事故名称:秒杀方案独占竞态实现问题
  • 事故现象:线上监控突然报警,CPU占用高,拖垮整个服务。用户看到可以购买,但只要一点下单就活动太火爆,换个小手试试。造成了大量客诉,紧急下线活动排查。
  • 事故描述:这个一个商品活动秒杀的实现方案,最开始的设计是基于一个活动号ID进行锁定,秒杀时锁定这个ID,用户购买完后就进行释放。但在大量用户抢购时,出现了秒杀分布式锁后的业务逻辑处理中发生异常,释放锁失败。导致所有的用户都不能再拿到锁,也就造成了有商品但不能下单的问题。 事故处理:优化独占竞态为分段静态,将活动ID+库存编号作为动态锁标识。当前秒杀的用户如果发生锁失败那么后面的用户可以继续秒杀不受影响。而失败的锁会有worker进行补偿恢复,那么最终会避免超卖以及不能售卖。
  • 学习总结: 核心的技术实现需要经过大量的数据验证以及压测,否则各个场景下很难评估是否会有风险。当然这也不是唯一的实现方案,可以根据不同的场景有不同的实现处理。

# 3.2 假定新增加抽奖码是随机的6位数,也就是有1-999999这么多的抽签码,用户每次获取都是随机的抽奖码,最后统一开奖。怎么在你的系统中处理。

  1. 提供一个记录抽奖码数据库表,按照你目前的量还不需要分库分表。
  2. 生成的随机码记录到抽奖表,同时记录一个自增的数字,这样就能知道从1到n有多个随机抽奖码。
  3. 每个用户身上记录抽奖码,可以是一个也可以是多个,记录在自己身上。
  4. 抽奖开始时候,不用抽奖码,用的是1~n的范围,基于这些范围比如1-10000,从中随机去除10个,那么这个10个数字对应的码就是抽奖码,在用抽奖码匹配到个人身上,修改状态为中奖。

# 3.3 因为员工误删了redis已使用库存key,出现活动库存超卖怎么解决?

Lottery 的设计把这事给办了;

  1. Lottery 采用的是滑块锁,按照库存编号自动成,如【key_1、key_2、key_3、key_4、...】这些key都被秒杀到的用户 setNx 加锁了。
  2. 如果key被删,则会从0开始计数 incr 但计数后,又会生成 key_1 加锁,可是这个key已经被加锁过,所以会告诉冲突。直到key incr 到当前为加锁的 key_n 时才能被正常购买。

# 4. 其他问题

# 4.1 把抽奖项目重新做一边,有哪些方面可以做的更好。

举例回答吧,因时因地,可能有很多答法。最重要的就是自圆其说,别挖完坑不填;

把抽奖项目重新做一边,有哪些方面可以做的更好:

  1. 其实在我们最开始承接项目做架构设计和工程实现时,就已经做了大量的调研、设计和评审。包括;工程的架构、需求的迭代、后续的维护以及整个系统的扩展性是否能满足业务未来3年的发展等,这些方面都做了很多的考虑。那么当然也不是说我们的系统服务已经完美了,它只是在当下情况下贴近真实情况的最佳方案,不过渡设计的同时也满足系统的发展。
  2. 但就业务的适合市场的发展对应到产品的更新迭代速度来说,后续我们在做抽奖系统的时候,会更希望把每个服务做成原子化的可编排领域服务,配合低代码平台进行拖拉配置的方式上线各类活动。因为目前我们的活动是越来越多的,但除了基础底层服务以外,也有不少的开发工作,希望把这部分重复工作,尽可能通过配置来实现,做成一些开放平台SDK自动化生成的方式来处理。

# 4.2 项目遇到最大的挑战是什么。

  1. 在工期压榨下,满足于当下快速上线还为做出符合未来预期的可持续性系统,是最大的挑战。
  2. 怎么与产品沟通、怎么和领导说明、怎么完成交付,这些在项目初期时候做了不小的沟通。才得以让目前的项目落地。我个人也在这里成长很多。

# 三、汇总:其他问题

综上像这样的实际项目问题,只有做过项目才可能回答的出来。如果满手都是学生管理系统、用户管理系统、图书管理系统等,那么可能还没到面试阶段就已经被Pass了。所以讲屁话是没有用的,只有硬核项目 + 时间投入 = 工作机会,即使这样的项目有些学习难度,那么也是值得花时间折腾的。

除了以上小傅哥列举的问题以外,其实还有很多整理出来的问题,这里截图给大家看下。面试问题地址:https://bugstack.cn/md/zsxq/material/interview.html

# 四、加入:实战项目

如果你手里确实没有什么像样的实战项目能摆到简历里给面试官看。那么我非常建议加入小傅哥的知识星球。因为在知识星球里,小傅哥提供了:《Lottery-抽奖系统》《API网关》《IM通信》《手写MyBatis》以及各类技术小册,这些项目学习完任何一个,都能和面试官聊到心花怒放,知道你是个有技术深度值得招聘进来的小伙。

🧧加入学习 (opens new window)

  1. 星球内的服务和实战项目都是小傅哥本人提供和原创,相信能够给大家带来超过该价格的价值 。举个例子,渐进式手把手带大家做进大厂才可能看得见的项目、有笔记有源码、有问题可以提,这比单独买一个课程或一套源码要值得多。其实都不到大城市一节补习班的钱,哪怕把我的课程时长换算成培训机构的课时,也是便宜的超级多
  2. 持续的内容创作 + 回答问题 + 知识星球的运营(简历批阅、就业指导、架构设计) 需要小傅哥每个早上6点-8点以及周末/假期持续维护。也希望加入星球的同学都是真的下定了决心想要进步,而不是像免费的交流群和社区一样 “闲聊扯淡”。
  3. 加入进来的同学能够利用好星球来坚持学习。如果这个星球真的帮助你达成了目标(比如晋升加了薪、跳槽诺了坑、校招进了厂),回过头来你会发现,这绝对是你 最值得的一笔投资 !(免费的东西往往不会珍惜,别问我为什么知道!)
  4. 星球仍将随着人数和项目的增加会每次提价,感谢理解!—— 但已付费的加入的用户,续费5折,相当于只续费小傅哥的服务和新项目费用,没有什么比这更爽的了!如果当年有人这样对我,我会买它个10年!