安排!假设你现在正坐在杭州某大厂的会议室里,对面的技术面面试官刚刚问完了复杂的分布式系统架构,你答得十分流畅。现在到了最后的智力题环节,他想考察一下你的计算机底层思维嗅觉。
这道题在互联网大厂的后端面试中出现频率极高,非常经典。
题目是这样的:
实验室里有 1000 瓶一模一样的水,其中有且仅有 1 瓶被污染了(有毒)。你手头上有 10 只小白鼠作为测试对象。
已知:小白鼠只要喝下哪怕微量的一滴毒水,24 小时后就会死亡;如果喝的是正常的水则完全没事。
问题: 如何在 24 小时内,用这 10 只小白鼠准确找出哪一瓶是毒水?
【面试官的满分参考答案】
这道题如果用常规的线性思维(比如分组喝)是解不开的,它的本质其实是二进制位运算(Bitwise Operation)思维。
第一步:给水瓶和老鼠编号
- 给 1000 瓶水贴上标签,从
0标到999。并将这些十进制数字转换成十位的二进制。- 例如:第 3 瓶是
0000000011,第 5 瓶是0000000101,第 999 瓶是1111100111。
- 例如:第 3 瓶是
- 给 10 只小白鼠排成一排,分别代表二进制的第 0 位到第 9 位。
第二步:喂水策略
- 只要某瓶水的二进制位上是
1,就给对应位置的老鼠喝一滴。 - 比如第 5 瓶(
...0101),它的第 0 位和第 2 位是1,那就给 0 号老鼠和 2 号老鼠各喂一滴。 - 第 999 瓶(
...1111100111),除了 3 号和 4 号老鼠不喝,其他老鼠都要喝一滴。 - 就这样按照规则把 1000 瓶水全部操作完。
第三步:24 小时后“验尸”读数
24 小时后,观察哪几只老鼠死了。
- 死掉的老鼠,把它们对应的二进制位记为
1,活着的记为0。 - 比如,如果最后是 0 号和 2 号老鼠死了,其他都活着,那么得到的二进制数就是
0000000101。 - 把这个二进制数转换成十进制,结果是 5!
- 结论: 第 5 瓶就是那瓶毒水。
【进阶:为什么面试官喜欢问这个?】
作为致力于深耕底层逻辑的后端开发,这道题考察的绝不是单纯的“脑筋急转弯”,而是你对数据状态压缩的敏感度。
在数学上,$2^{10} = 1024$。这意味着 10 个二进制位(即 10 只老鼠的不同生死组合)足以表示多达 1024 种独立状态,完美覆盖了 1000 瓶水。
这种思维在实际的 Java 后端高并发场景中极其重要。比如面对海量日活用户的签到统计、亿级数据的快速去重过滤时,我们常用到的 Redis Bitmap(位图) 或者 Bloom Filter(布隆过滤器),其最核心的底层设计思想正是基于这种二进制位的映射与状态压缩。如果在面试时,你答出解法后能顺口提一句它和 Redis Bitmap 底层思想的共性,面试官绝对会眼前一亮。
Comments NOTHING