大家好,我是二哥呀。
2018年4月,阿里巴巴联合蚂蚁金服对饿了么完成全资收购;2023年3月,阿里巴巴集团迎来史上最大组织变革,开启“1+6+N”改革,设立六大业务集团。饿了么被划分到本地生活集团。
阿里拆分后,不再如日中天,但好处就是可以多并发投递简历(🥲),不用等一个挂了再投另外一个。最近,饿了么也开奖了,星球里也有球友的定薪还不错。
我这里也整理了一些百度的薪资情况放在了《Java 面试指南》专栏中。
双非硕,Java 岗,开到了 24k*16,还有 6k 的搬家费,公积金按照 7 缴纳,是转正后的白菜 硕士 985,给到了 25k,后端开发岗,感觉有点拉,base 上海 硕士双非,aigc 算法,base 杭州,给了 28k,对于算法岗来说,真不多,不过有 5w 的签字费 硕士 985,后端开发,给了 24k,直接拒了 后端岗,给了 26k,算是 sp 吧,在杭州地区,比较心动的,很想去,因为听说饿了么比较 wlb
饿了么在 3 月份更换了新的 CEO,88 年的少壮派韩鎏,主打新三年“1+2”战略计划,1 就是外卖餐饮(核心业务),2 是即时零售(生鲜、日用百货、药品等)和即时物流(蜂鸟物流)。
我个人还是非常希望整个阿里系重振雄风的,因为阿里曾经是 Java 岗的集大成者,阿里发展的越好,学 Java 的小伙伴就会有更多的选择(😄)。
那接下来,我们就以 Java 面试指南中收录的阿里系面经同学 19 饿了么面试为例,来看看饿了么的面试都喜欢问哪些知识点和技术栈,好做到心中有数。冲冲冲。
1、二哥的 Linux 速查备忘手册.pdf 下载 2、三分恶面渣逆袭在线版:https://javabetter.cn/sidebar/sanfene/nixi.html
阿里系面经同学 19 饿了么面试
分布式锁用redis实现思路
Redis 实现分布式锁的本质,就是在 Redis 里面占一个“茅坑”,当别的客户端也来占坑时,发现已经有客户端蹲在那里了,就只好放弃或者稍后再试。
可以使用 Redis 的 SET 命令实现分布式锁。同时添加过期时间,以防止死锁的发生。
SET key value NX PX 30000
key
是锁名。value
是锁的持有者标识,可以使用 UUID 作为 value。NX
只在键不存在时设置。PX 30000
:设置键的过期时间为 30 秒(防止死锁)。
MQ异步秒杀下单怎么实现的
秒杀可以分为两个阶段,库存预扣减和异步处理下单。具体来说,党用户发起秒杀请求时,可以通过 lua 脚本+Redis 来完成第一阶段,MQ 主要负责第二阶段。
下单请求通过生产者写入消息队列,避免瞬时流量直接打到数据库,消费者从 MQ 拉取消息,再次校验库存,防止 Redis 和 MySQL 库存不一致,然后使用乐观锁进行库存扣减,最后写入订单表,记录用户秒杀成功的状态。
redis内存淘汰机制 延伸到LRU LFU
当 Redis 的内存使用达到最大值时,它会根据配置的内存淘汰策略来决定如何处理新的请求。
常见的策略有:
noeviction:默认策略,不进行任何数据淘汰,直接返回错误信息。 allkeys-lru:从所有键中,使用 LRU 算法淘汰最近最少使用的键。 allkeys-lfu:从所有键中,使用 LFU 算法淘汰最少使用的键。 volatile-lru:从设置了过期时间的键中淘汰最近最少使用的键。 volatile-ttl:从设置了过期时间的键中淘汰即将过期的键。
LRU 和 LFU 的区别是什么?
LRU(Least Recently Used):基于时间维度,淘汰最近最少访问的键。适合访问具有时间特性的场景。
LFU(Least Frequently Used):基于次数维度,淘汰访问频率最低的键。更适合长期热点数据场景。
存储引擎介绍
MySQL 支持多种存储引擎,常见的有 MyISAM、InnoDB、MEMORY 等。
索引为什么用B+树不用B树
B+ 树相比 B 树有 2 个显著优势:
首先,B+ 树的非叶子节点不存储数据,能包含更多的键值指针,因此在相同节点容量下,B+ 树的层级更少,树的高度更低。较少的树层级意味着查找路径更短,磁盘 I/O 次数更少。
其次,B+ 树的叶子节点通过链表相连,非常适合范围查询,如 ORDER BY 和 BETWEEN。
只需要找到符合条件的第一个叶子节点,顺序扫描后续的叶子节点就可以了。相比之下,B 树的每次范围查询都需要回溯到父节点,查询效率较低。
时间复杂度深究 b+树 快速排序...
树的高度 h 为:
其中 N 是数据总量,m 是阶数。每层需要做一次二分查找,复杂度为 。
总复杂度为:
了解快排吗?
快速排序是一种基于分治法的高效排序算法。其核心思想是:
选择一个基准值。 将数组分为两部分,左边小于基准值,右边大于或等于基准值。 对左右两部分递归排序,最终合并。
跳表了解吗 为什么不用跳表
跳表是一种有序的数据结构,它通过在每个节点中维持多个指向其它节点的指针,从而达到快速访问节点的目的。
为什么用 B+树不用跳表呢?
跳表基于链表,节点分布不连续,会频繁触发随机磁盘访问,性能较差。 跳表需要逐节点遍历链表,范围查询性能不如 B+ 树。
MySQL锁
按锁粒度划分的话,MySQL 的锁有:
表锁:开销小,加锁快;锁定力度大,发生锁冲突概率高,并发度最低;不会出现死锁。 行锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高。 页锁:开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般。
查询如何优化
我在进行 SQL 优化的时候,主要通过以下几个方面进行优化:
怎么分析慢查询
首先,找到那些比较慢的 SQL,可以通过启用慢查询日志,记录那些超过指定执行时间的查询。
也可以使用 show processlist;
命令查看当前正在执行的 SQL 语句,找出执行时间较长的 SQL。
或者在业务基建中加入对慢 SQL 的监控,常见的方案有字节码插桩、连接池扩展、ORM 框架扩展。
然后,使用 EXPLAIN 查看查询执行计划,判断查询是否使用了索引,是否有全表扫描等。
EXPLAIN SELECT * FROM your_table WHERE conditions;
最后,根据分析结果,通过添加或优化索引、调整查询语句或者增加内存缓冲区来优化 SQL。
场景题:设计一个外卖超时的任务
延迟支付订单的场景可以采用消息队列的延迟任务方案。即在用户下单时,将订单放入一个延迟队列中,延迟 15 分钟检查支付状态,超时未支付则取消订单。这种方式可以在高并发下有效降低系统负担,减少数据库轮询压力,并通过消息队列的自动调度机制确保订单准时处理。同时,这个设计可以通过消息的幂等性、分布式部署等手段提升系统的可靠性和扩展性。
ending
一个人可以走得很快,但一群人才能走得更远。二哥的编程星球已经有 6600 多名球友加入了,如果你也需要一个良好的学习环境,戳链接 🔗 加入我们吧。这是一个 编程学习指南 + Java 项目实战 + LeetCode 刷题 + 简历精修 的私密圈子,你可以阅读星球专栏、向二哥提问、帮你制定学习计划、和球友一起打卡成长。
两个置顶帖「球友必看」和「知识图谱」里已经沉淀了非常多优质的学习资源,相信能帮助你走的更快、更稳、更远。
欢迎点击左下角阅读原文了解二哥的编程星球,这可能是你学习求职路上最有含金量的一次点击。
最后,把二哥的座右铭送给大家:没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。共勉 💪。