<p>StringBuilder 底层基于可变 char[] 数组和扩容机制(默认容量16,扩容公式为 oldCapacity * 2 + 2),无 synchronized,故单线程性能优于 StringBuffer;与 String 的本质区别在于 value 是否 final;编译期确定的字符串拼接、极简拼接场景下 String 更优;误用包括循环内频繁 new 实例,应复用并 clear()。</p>

Java 中 StringBuilder 是面试高频考点,大厂常从原理、性能、线程安全、使用场景四个维度考察。关键不是背 API,而是讲清“为什么用它”“什么时候不能用”“和 String、StringBuffer 本质区别在哪”。
StringBuilder 的底层原理怎么答?
核心是“可变字符数组 + 扩容机制”。默认容量 16,内部维护 char[] value;append() 等操作直接修改数组内容,不创建新对象。当容量不足时,按 oldCapacity * 2 + 2 扩容(JDK 17+),并用 Arrays.copyOf 复制旧数据。
- 强调“非 final 数组 + 没有 synchronized”,这是性能快的根源
- 对比 String:String 的 value 是 final char[],每次拼接都 new 新对象
- 可以提一句“扩容涉及数组复制,频繁扩容也影响性能,所以建议预估长度后用带初始容量的构造方法”
StringBuilder 和 StringBuffer 的区别必须说准
两者 API 几乎一致,但线程安全性是分水岭:
- StringBuffer 所有 public 修改方法(append、insert、delete)都加了 synchronized
- StringBuilder 没有任何同步,因此单线程下性能明显更高(实测通常快 2–3 倍)
- 结论明确:多线程环境选 StringBuffer(或更推荐用 StringJoiner / 并发集合),单线程一律用 StringBuilder
什么场景下 StringBuilder 反而不如 String?
不是所有拼接都适合 StringBuilder。要指出边界情况:
立即学习“Java免费学习笔记(深入)”;
- 编译期确定的字符串字面量拼接(如 "a" + "b" + "c")会被编译器优化为一个常量,直接进字符串池,比 StringBuilder 更轻量
- 极简拼接(比如只有 2–3 次、且长度很短),JVM JIT 可能优化掉 StringBuilder 开销,差异可忽略
- 误用场景:在循环里反复 new StringBuilder(如每次迭代都 new 一个),应改为外部声明、循环内 clear() 或 setLength(0)
手写代码题常见陷阱怎么避?
面试官常让现场写“反转字符串”或“删除指定字符”,重点看细节处理:
- 反转不要只写 reverse(),要会手动实现:用 two-pointer 在 char[] 上原地交换
- 删除字符避免边遍历边删(会导致索引错乱),推荐“双指针覆盖法”或先记位置再批量删除
- 注意 null 判断和空字符串处理,比如 append(null) 会写入字符串 "null",不是抛异常
- 如果题目要求线程安全,不能硬套 StringBuilder —— 要主动说明“这里用 StringBuffer 更合适”或改用其他方案
把原理吃透、把边界想全、把代码写稳,这类题就稳了。


















