第一层:发现问题
面试官追问 :"如果需求变更为国际号码格式 +1 123-456-7890
,你要修改多少处代码?"
小瓜顿时语塞,意识到问题:
- 硬编码陷阱:涉及7处索引修改
- 魔法数字:3/3/4分段规则没有明确表达
- 维护噩梦:格式与代码高度耦合
第二层:初级优化
小瓜改进:"可以用模板字符串提升可读性!"
javascript
// 解法二:模板字符串法
function getPhoneNumber(arr) {
return `(${arr[0]}${arr[1]}${arr[2]}) ${arr[3]}${arr[4]}${arr[5]}-${arr[6]}${arr[7]}${arr[8]}${arr[9]}`;
}
改进点 | 优势 | 遗留问题 |
---|---|---|
消除+ 拼接 |
代码更简洁 | 索引仍然硬编码 |
直观展示格式 | 结构一目了然 | 分段规则未抽象 |
第三层:中级优化
面试官提示:"如果格式需要动态调整呢?"
javascript
// 解法三:模板替换法
function getPhoneNumber(arr) {
let format = '(xxx) xxx-xxxx';
arr.forEach(num => {
format = format.replace('x', num);
});
return format;
}
技术亮点:
- 格式与逻辑分离
- 支持动态模板(如
xx-xxxx-xxxx
) - 代码自解释性强
第四层:高级优化
面试官追问:"如何处理非数字输入?"
javascript
// 解法四:防御性编程版
function getPhoneNumber(arr) {
// 输入校验
if (!Array.isArray(arr)) throw new TypeError("需要数组输入");
const digits = arr.map(n => {
const num = Number(n);
if (isNaN(num)) throw new Error("包含非数字");
return num % 10; // 确保0-9
});
// 格式抽象
const segments = [3, 3, 4];
let phone = '';
let index = 0;
segments.forEach((length, i) => {
phone += (i === 0) ? '(' : (i === 1) ? ') ' : '-';
phone += digits.slice(index, index + length).join('');
index += length;
});
return phone;
}
面试考点全景图
-
基础能力
- 数组操作(slice/indexOf)
- 字符串拼接(
+
/模板字符串)
-
代码质量
- 避免硬编码
- 关注可维护性
-
工程思维
- 防御性编程
- 需求变更应对
-
性能意识
- 时间复杂度分析
- 内存管理
终极建议
- 新手必做:先写出能跑的代码
- 进阶要求:添加输入校验
- 高手标配:支持格式配置化
- 专家境界:提供单元测试套件
javascript
// 测试用例
test('基础功能', () => {
expect(getPhoneNumber([1,2,3,4,5,6,7,8,9,0]))
.toBe('(123) 456-7890');
});
test('异常输入', () => {
expect(() => getPhoneNumber([1,2,3])).toThrow();
});
通过这道经典面试题,我们看到的不仅是代码的演进,更是工程师思维的成长轨迹。记住:代码质量决定职业高度,防御性编程体现工程素养。下次面试时,希望你能用这四层解法惊艳面试官!