京东面试题解析:String与StringBuilder的区别、装箱拆箱、重载与重写总结

127 阅读5分钟

京东的面试通常侧重于考察应聘者的Java基础知识、数据结构与算法的理解以及对常见技术问题的处理能力。以下将对一些常见面试题进行解析。

1. String、StringBuilder、StringBuffer的区别​编辑

StringStringBuilderStringBuffer都用于表示字符序列,但它们在性能、线程安全等方面有显著区别。

​编辑

  • String
    - 不可变:一旦创建,内容不能被修改。每次修改都会生成新的String对象。
    - 线程安全:由于不可变性,多个线程访问时不会出现问题。
    - 性能差:由于每次修改都会创建新的对象,性能开销较大。

  • StringBuilder
    - 可变:字符串内容是可以修改的,直接操作底层的字符数组。
    - 非线程安全:适合单线程环境,性能较好。
    - 性能优于String:尤其是在字符串频繁修改的场景中,效率高。

  • StringBuffer
    - 可变:与StringBuilder一样,内容可以修改。
    - 线程安全:使用了同步机制,适合多线程环境。
    - 性能略差于StringBuilder:由于线程同步的开销,性能上不如StringBuilder。​编辑

总结

  • 使用String时不可变特性带来的安全性,但性能差;
  • StringBuilder适合单线程,性能较好;
  • StringBuffer适合多线程,但性能相对较低。

2. String不可变的优点

String是不可变的,意味着一旦创建,它的内容不能被修改。这种设计有以下优点:

  • 安全性:由于不可变性,多个线程在操作同一String对象时,不会发生数据不一致的情况。
  • 共享性:多个相同内容的String对象可以共享内存(String池),减少内存开销。
  • Hashcode缓存:由于String对象内容不变,其hashCode可以缓存起来,不需要每次计算,提高性能。
  • 不易被篡改:不可变特性使得String更加安全,不容易被无意或恶意地修改。

3. 装箱和拆箱的区别​编辑

  • 装箱:将基本数据类型转换为对应的包装类对象。例如,将int转为Integer
    java   int num = 10;   Integer boxed = Integer.valueOf(num); // 装箱  

  • 拆箱:将包装类对象转换为基本数据类型。例如,将Integer转为int
    java   Integer boxed = 10;   int num = boxed.intValue(); // 拆箱  

在Java中,装箱和拆箱是自动发生的,这种自动装箱和拆箱使得基本类型和包装类之间的转换非常方便。

4. Integer和int有哪些不同

  • int:基本数据类型,存储的是实际的数值。速度快,占用的内存小。
  • Integer:包装类,存储的是int类型的对象引用。由于是对象,具有更多功能(如equalshashCode等方法),但性能比int稍差。​编辑

不同点

  • int是基本类型,而Integer是对象。
  • int更节省内存,性能更好。
  • Integer提供了更多的功能,适用于需要对象的场景(如泛型集合、需要引用的地方等)。

5. 重载和重写的区别

​编辑

  • 重载(Overloading)
    - 在同一个类中,方法名相同,但参数列表不同(参数的数量或类型不同)。
    - 重载发生在编译时,由编译器根据方法签名来选择合适的方法。

  例子
java   public class Example {       public void display(int a) { System.out.println(a); }       public void display(String a) { System.out.println(a); }   }  

  • 重写(Overriding)
    - 子类重新定义父类中的方法,方法名、返回类型和参数列表完全相同。
    - 重写发生在运行时,Java通过动态绑定来调用子类的方法。​编辑

  例子
```java
class Parent {
public void show() { System.out.println("Parent"); }
}

  class Child extends Parent {
@Override
public void show() { System.out.println("Child"); }
}
```

6. 接口和抽象类的区别

  • 接口(Interface)
    - 可以包含抽象方法、默认方法和静态方法,但不能包含实例字段。
    - 不能实例化,只能通过实现接口的类来使用。
    - 类可以实现多个接口(多继承)。​编辑

  • 抽象类(Abstract Class)
    - 可以包含抽象方法和非抽象方法(方法可以有实现)。
    - 可以包含实例字段。
    - 类只能继承一个抽象类(单继承)。

总结

  • 接口适合定义一组行为(多个实现类共享相同接口),而抽象类更适合提供一些通用的功能实现。
  • 接口支持多继承,抽象类支持单继承。

7. ArrayList和LinkedList的区别

  • ArrayList
    - 底层是动态数组,支持快速随机访问。​编辑
    - 插入和删除元素时需要移动数组中的元素,性能较差。
    - 查询元素的时间复杂度是O(1),插入和删除的时间复杂度是O(n)(在最坏情况下)。

  • LinkedList
    - 底层是双向链表,每个元素都包含指向前后元素的引用。
    - 插入和删除操作不需要移动元素,性能较好,尤其是频繁插入和删除时。
    - 查询元素的时间复杂度是O(n),插入和删除的时间复杂度是O(1)。

总结

  • ArrayList适用于查询频繁、插入删除较少的场景。
  • LinkedList适用于插入删除频繁的场景。

8. HashTable和HashMap的区别

  • HashTable
    - 线程安全:通过synchronized保证线程安全。
    - 性能差:由于同步开销,性能较差。
    - 不允许null键和值

  • HashMap
    - 非线程安全:在多线程环境下可能会出现数据不一致的情况。
    - 性能较好:没有同步开销,适合单线程环境或在外部通过其他方式保证同步。
    - 允许null键和值

总结

  • HashMap适用于单线程环境或外部同步的场景,性能优于HashTable
  • HashTable适用于需要线程安全的场景,但性能差,通常推荐使用ConcurrentHashMap

结语

京东的面试不仅会考察对基础知识的掌握,还会通过技术细节来评估编码能力、思维方式及解决问题的能力。在准备面试时,除了掌握Java相关的知识,还需要多做项目实践,积累问题解决的经验。