面试被问 string 是基本类型还是引用类型,答完又追问为什么字符串拼接慢。写 C 的时候更直接,char 数组和 string 混着用,编译报错看不懂。
string 就是字符串,但每个语言的实现差别大得离谱,套同一套模型去理解一定出错。
几种典型实现
- C:根本没有 string 类型,用 char 数组加一个 0 字节结尾,strlen 靠从头扫到尾,漏了结尾就是越界
- C++:std::string 是个类,自己管堆内存,短字符串有 SSO 优化,不超过 15 个字节不分配
- Java、C#:不可变引用类型,每次拼接都生成新对象,循环里拼要用 StringBuilder
- Python3:str 是不可变的 Unicode 码点序列,len 数的是字符,不是字节
- JavaScript:原始类型,内部按 UTF-16 存,一个 emoji 的 length 会返回 2
- Go:只读的字节切片,不能改其中某个字节,拼接用 strings.Builder
三个容易翻车的点
编码是最常见的坑。Python2 里 str 是字节串,中文长度按字节算,和 Python3 完全两套逻辑,老代码迁移大多卡在这里。比较也有讲究,Java 里用双等号比的是引用地址,内容相等得用 equals,每年都有人栽。空值更隐蔽,数据库里 NULL 和空字符串不是一回事,拼 SQL、判空、长度校验都得分开写。
至于拼接慢,根子在不可变对象每次都要复制整段内存,复杂度是平方级。几十次拼接无所谓,循环上万次就明显了,换 StringBuilder 或者 join 立刻见效。
我的经验是:写业务代码不必纠结底层结构,但一定要清楚你用的语言里字符串可变不可变、长度按字节还是按字符算。这两点决定了你会不会写出乱码和截断。