今日八股:LinkedList 中间操作更快?这句话的口径要分两层说

今日八股:LinkedList 中间操作更快?这句话的口径要分两层说

今天的练习

周二,三轮九问:上午 Java 集合(ArrayList vs LinkedList),下午前端三连(v-for key、== 与 ===、block/inline),收工前数据库和网络(DELETE vs TRUNCATE、事务、TCP vs UDP)。今天没有硬错误,但有两个值得记的点:一个是我自己的——事务题没按要求用银行转账举例;另一个是知识层面的——"LinkedList 中间操作更快"这句话里藏着一个查找开销的口径问题。

题目一:ArrayList 和 LinkedList,中间插删谁更快?

两者底层数据结构是什么?get(i) 复杂度?中间插入删除谁更快?实际开发为什么都用 ArrayList?

我的第一版回答:ArrayList 底层是 Object 数组,LinkedList 是双向链表(prev、item、next)。get(i) 对 ArrayList 是 O(1),LinkedList 是 O(n) 要遍历。中间操作 LinkedList 更快,因为 ArrayList 要移动后面所有元素,LinkedList 直接改指针。ArrayList 随机访问快、内存占用小、缓存友好、操作方便。

复盘

  • 第一问第三问全对。结构、复杂度、四个优势角度都标准。
  • 第二问藏着口径分歧:"改指针 O(1) 所以 LinkedList 快"是教科书答案,默认只考虑插删动作本身,成立。但较真的面试官会追问:按索引找到中间位置本身就要 O(n) 遍历,加起来还是 O(n),和 ArrayList 打平。真正的 O(1) 只发生在"已经站在那个节点上"(迭代器遍历到一半删除当前元素)。
  • 面试策略:先答标准口径,再主动补一句"不过按索引随机定位的话,查找本身 O(n),总量打平,只有迭代器场景才是真 O(1)",把追问提前堵死。

标准答案

ArrayList 底层动态数组,支持下标随机访问 O(1),扩容为原来的 1.5 倍。LinkedList 底层双向链表,头尾插删 O(1),随机访问 O(n)。中间插删:教科书口径 LinkedList 快(免搬移);严格口径两者都要先定位,同为 O(n)。实际开发首选 ArrayList:内存连续缓存友好、无节点额外开销、CPU 搬移(arraycopy)极快。

一句话记住

LinkedList 的 O(1) 只对"手已经摸到节点"的操作生效,按索引找它照样要爬。

题目二:v-for 为什么要加 :key,index 和唯一 id 有什么区别?

v-for 渲染列表为什么要加 :key?用 index 当 key 和用唯一 id 当 key 有什么区别?

我的第一版回答:diff 算法靠 key 标识节点身份,能精准判断节点是新增、删除还是移动,最大化复用 DOM。用 index 做 key,列表操作后 index 变化,会复用错误的 DOM;用唯一 id 就正确。不会对列表删除、排序、新增的话用 index 也可以。

复盘

  • 全对,连边界条件都答了。"不增不删不排序可以用 index"这句主动说出来很加分。
  • 具体化弹药:index 做 key 的 bug 别只说"复用错误 DOM",说状态错位——中间删一行,后面所有 key 前移,Vue 就地复用节点,组件内部状态(输入框已输入的文字、checkbox 勾选态)全部串位。举得出这个例子说明真踩过坑。

一句话记住

key 是节点的身份证,用 index 当身份证,队伍一动全乱套。

题目三:== 和 === 的区别

== 和 === 有什么区别?举一个 == 类型转换的例子。

我的第一版回答:== 是抽象相等,比较前先做类型转换再比值;=== 是严格相等,类型和值都必须相同,不转换。比如字符串 0 和数字 0 比较,会把字符串转成数字。

复盘

  • 全对。
  • 高频追问点:null == undefined 为 true,且这俩 == 其他任何值都是 false;NaN 谁都不等包括自己,判断要用 Number.isNaN()

一句话记住

== 先转换再比,=== 类型值都得一样;NaN 谁都不认,null 只跟 undefined 好 partnership(==)。

题目四:block / inline / inline-block

块级元素和行内元素的区别?inline-block 是什么?各举常见标签。

我的第一版回答:block 独占一行、可设宽高、默认撑满父容器(div、p、h1、section)。inline 不独占一行、宽高由内容撑开、设宽高无效、上下 margin 无效(span、a、strong、label)。inline-block 对外行内(可并排)对内块级(可设宽高)(input、img、button、textarea)。

复盘

  • 全对。"对外行内对内块级"这句总结很标准。
  • 实战彩蛋:img 是行内元素,两张图并排有几像素缝隙(基线对齐 + 空白符),实际用 flex 或 display:block 干掉。被问"行内元素还有什么坑"这就是答案。

一句话记住

block 占一行能设宽高,inline 排一行宽高无效,inline-block 排一行还能设宽高。

题目五:DELETE 和 TRUNCATE 的区别

两者都能删表数据,有什么区别?什么场景用哪个?

我的第一版回答:DELETE 是 DML,可按 where 删指定数据,能事务回滚,不影响 id 自增;TRUNCATE 是 DDL,只能全表清空。DELETE 用于按条件删(如删 3 个月前日志)、需要事务回滚;TRUNCATE 用于确定清空整张表、追求速度(清临时表、测试数据重置)。

复盘

  • 全对。DML/DDL、where、回滚、自增、场景全齐。
  • 反向细节补上:TRUNCATE 会把 AUTO_INCREMENT 计数器重置回 1(DELETE 不影响自增的反面),且不触发 DELETE 触发器,被外键引用的表 TRUNCATE 直接报错。

一句话记住

DELETE 慢工出细活可回滚,TRUNCATE 一刀切还把计数器归零。

题目六:什么是事务?为什么需要?

什么是事务?为什么需要事务?用银行转账的例子说明。

我的第一版回答:事务是一组数据库操作组成的不可分割的工作单位,要么全部成功提交,要么全部失败回滚,不存在中间状态。如果两句更新同时执行,前一句成功后一句失败,会造成数据不同步。

复盘

  • 定义对,但审题翻车:题目点名要用银行转账举例,我用了自己的"两句更新"例子。内容没错,但面试答非所问会扣印象分,先按题目要求的场景答。
  • 标准举例:A 转 B 100 块 = 扣 A + 加 B 两条 UPDATE 包在一个事务里,第二条失败整体回滚,钱不会凭空消失。
  • 预告:问"为什么需要"答原子性够用,但被问 ACID 时别只记得原子性,隔离性、持久性、一致性都要能展开。

一句话记住

面试让举例就用题目给的例子,别自作主张换场景。

题目七:TCP 和 UDP 的区别

TCP 和 UDP 有什么区别?各举一个典型应用场景。

我的第一版回答:TCP 可靠不丢包,建立要三次握手,开销大速度慢;UDP 直接发、快、会丢包。TCP 用于 HTTP/HTTPS 这类不能丢数据的场景,UDP 用于直播、游戏这种要求快、丢几帧没关系的场景。

复盘

  • 全对。对比维度和场景都标准。
  • 亮点知识:HTTP/3 就是跑在 UDP 上的(QUIC 协议),在 UDP 上自己实现了可靠传输——面试聊到这层就是加分项。TCP 可靠的机制点名就够:确认应答 + 超时重传 + 滑动窗口。

一句话记住

TCP 先握手再送达一条不丢,UDP 抬手就扔快但可能丢。

面试官要什么例子就举什么例子——知识点再对,答非所问也是白搭。

今天九问零硬错误,唯一的问题是事务题没按题目要求举例,这是审题习惯不是知识漏洞。连续四天练习,基础轮快成舒适区了,明天开始 Java 上 B+ 树和 HashMap,前端上 Proxy 响应式原理,往深水区再走一步。

← 返回文章列表