面试官:说说这段代码存在什么问题?

《Java开发手册》是阿里巴巴集团技术团队的经验总结,经历了多次不断实战的检验及不断完善,公开到业界后,众多社区开发者踊跃参与,共同打磨完善,系统化地整理成册。

手册的愿景是码出高效,编程高质量的程序。

字符串处理看似简单,却在面试中层出不穷。做出来关于字符串的题目简单,能够完全准确地写出来并不容易。

笔者有次面试时,面试官就问了这样一个问题,说说这段代码存在什么问题?

String str = "start";
for(int i=0; i<100; i++){
  str = str + "hello";
}

这个问题其实关于循环体内的字符串连接方式使用 StringBuilder的append方法进行拓展。

在《Java开发手册》就有提到,值得留意。

阿里原话:

【推荐】循环体内,字符串的连接方式,请使用 StringBuilder 的 append 方法进行扩展。

说明:因为反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费。

大概意思是用StringBuilder连接字符串性能要比 String + 的方式要好,因为占用内存资源更少。

要怎么才能更加直观的得知循环体内的字符串连接方式使用String+性能低呢?对此我们可以尝试用时间开销来对比。

    long begTime = System.currentTimeMillis();
    StringBuilder sb = new StringBuilder("start");
    for (int i = 0;i < 10000; i++){
        sb.append(i);
    }
    long endTime = System.currentTimeMillis();
    long time = endTime - begTime;
    System.out.println("StringBuilder消耗时间:" + time);


    String str = "start";    long begTime2 = System.currentTimeMillis();
    for (int i = 0;i < 10000; i++){
        str = str + i;
    }    long endTime2 = System.currentTimeMillis();
    long time2 = endTime2 - begTime2;
    System.out.println("String消耗时间:" + time2);

        

多次输出:

StringBuilder消耗时间:3

String消耗时间:404

StringBuilder消耗时间:2

String消耗时间:481

StringBuilder消耗时间:4

String消耗时间:507

在时间方面,String消耗的时间确实比StringBuilder多得多。

对比 String 与 StirngBuilder 的源码。

String源码

private final char value[];
// 本质是字符数组常量,所以不可变
public String() {
    this.value = "".value;
}

StringBuilder

   

 public StringBuilder() {
    // StringBuilder 类继承 AbstractStringBuilder 抽象类
    // 创建长度 16 的字符数组
    super(16);
}
// 字符串拼接
public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

AbstractStringBuilder

  AbstractStringBuilder(int capacity) {
    value = new char[capacity];
}

总结

字符串拼接,虽然字符串是不可变的,但还是可以通过新建字符串的方式来进行字符串的拼接。

常用的字符串拼接方式有以下几种方式

  • String+

  • concat

  • StringBuilder

  • StringBuffer

  • StringUtils.join

由于字符串拼接过程中会创建新的对象,所以如果要在一个循环体中进行字符串拼接,就要考虑效率问题和内存问题。

建议优先使用StringBuilder,但不是在循环体中进行字符串拼接的话,直接使用+就好了。

但要是在并发场景中进行字符串拼接的话,就要使用StringBuffer来代替StringBuilder。因为StringBuffer是线程安全的。

StringBuilder和StringBuffer有什么区别?具体分析请戳 这里

由于笔者水平有限,文中纰漏之处在所难免,权当抛砖引玉,不妥之处,请大家批评指正。

 

-END-

作者:洪生鹏  擅长java、Android、qt、小程序平台开发。技术交流、媒体合作、品牌宣传请添加微信: hsp-88ios

猜你喜欢

30岁以前找工作靠能力,30岁以后找工作靠人脉

更多惊喜,请长按二维码识别关注

你若喜欢,别忘了帮忙点【在看

### 软件测试面试常见问题及解答 #### 如何在技术不够合格的情况下给面试官留下良好印象? 即使技术水平不是特别高超,在面对面试时也可以通过展现积极的学习态度、团队合作精神以及解决问题的能力来赢得好感。例如,可以分享过往项目经验中的学习过程成长经历,强调持续改进的决心[^1]。 #### 面试过程中遇到不懂的问题应该如何处理? 当碰到不知道如何作答的技术难题时,可以通过反问的方式进一步澄清题目细节,这不仅能够争取思考时间,还能展示出良好的沟通能力;另外还可以尝试从已知的知识点出发,推测可能的答案方向,并诚实地表达当前理解有限但愿意深入研究的态度。 #### 对于仅部分掌握的技能应怎样描述? 针对那些有一定了解却并非精通的技术领域,建议采用具体实例说明实际应用情况,比如曾经参与过的项目或者解决过的小型问题等。这样既能体现对该项技能有一定的实践经验,又不至于夸大其词造成误导。同时也要表明继续深造的愿望,显示出开放性进取心。 #### 自我介绍的内容与时长控制 一份优秀的自我介绍应当简洁明了地概括个人背景、职业目标以及为什么适合应聘职位。通常情况下三分钟左右的时间是比较合适的长度,既能让对方充分了解到求职者的概况,也不会因为冗长而引起厌烦情绪。重点在于突出与所申请岗位相匹配的经历特长。 #### 测试人员的工作成果汇报 作为测试工程师,应该列举一些具体的案例证明自己为整个项目的质量保障做出了哪些实质性的努力。可以从发现并修复了多少严重缺陷、提高了多少百分比的产品稳定性等方面入手,用数据说话往往更具说服力。此外还可以说说自己是如何与其他部门协作完成任务的,以此反映自身的协调能力责任心。 #### 展现自身优势的方法 为了凸显自己的竞争力,可以从以下几个角度考虑:一是扎实的专业基础技术实力;二是高效的执行力严谨的工作作风;三是出色的交流技巧跨职能团队间的配合意识;四是快速适应变化环境的能力以及对新技术的好奇心探索欲。这些都是成为一名优秀测试员不可或缺的因素。 #### 向面试官提问环节的重要性 最后阶段向考官询问有关公司文化、未来发展方向等问题是非常必要的。一方面显示出了对公司内部运作的兴趣,另一方面也有助于判断这份工作是否真的适合自己长期发展。可以选择关注企业愿景使命、技术创新趋势或是员工培训机制等内容进行探讨。 ```python # 示例代码用于解释自动化脚本编写思路 def test_script_example(): try: # 执行登录操作前先初始化浏览器驱动程序 driver = webdriver.Chrome() # 访问指定网址 driver.get('http://example.com') # 定位用户名输入框并填写信息 username_field = driver.find_element(By.ID, 'username') username_field.send_keys('test_user') # 寻找密码栏并键入预设值 password_field = driver.find_element(By.NAME, 'password') password_field.send_keys('secure_password!') # 提交表单触发验证流程 submit_button = driver.find_element(By.CSS_SELECTOR, '.submit-button') submit_button.click() # 断言页面跳转成功与否 assert "Dashboard" in driver.title print("Login successful!") except Exception as e: print(f"An error occurred during login process: {e}") finally: # 清理资源关闭窗口 driver.quit() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值