【中小厂面试题】搜狐畅游 一面 java 后端最新面试题

目录

1. String、StringBuilder和StringBuffer的区别?

2. 你用过哪些集合?

3. HashMap和TreeMap有哪些区别?

4. Java里的反射机制简单说下

5. 你自己做的那些项目,有自己参与过部署之类的吗?

6. 有做过JVM的性能调优方面的参数设置吗?

7.  Java的乐观锁和悲观锁简单讲一下

8. 讲一下 Spring IOC 和 AOP

9. 数据库你用过哪些?

10. UNION和UNION ALL这两个关键字的区别和作用分别是什么?

11. EXISTS和IN的区别

12. 从前端页面到Java后台再到数据库,有一张表,表存在上百万条数据,从这三个层面,去做一个查询方面的优化,单表查询。

13. 我看你简历上写着前端会用vue,介绍一下生命周期

14. 聊天局


1. String、StringBuilder和StringBuffer的区别?

三者的区别如下:

  • String对象是不可变的,即一旦创建,其内容就不能被改变。每次对String进行修改操作(如拼接、替换等),都会生成一个新的String对象。由于String对象不可变,因此它是线程安全的,可以在多线程环境下安全使用,并且由于每次修改都会创建新的对象,String在频繁修改字符串的场景下性能较差。

  • StringBuilder可变的,它允许在不创建新对象的情况下修改字符串内容,它不是线程安全的,它的方法没有同步机制,因此在多线程环境下使用时需要注意线程安全问题,由于不需要创建新对象,StringBuilder在频繁修改字符串的场景下性能较好。

  • StringBuffer也是可变的,它允许在不创建新对象的情况下修改字符串内容,StringBuffer线程安全的,它的方法都是同步的,因此在多线程环境下可以安全使用,由于方法同步,StringBuffer在单线程环境下的性能略低于StringBuilder,但在多线程环境下性能更稳定。

总的来说, String适用于字符串不经常修改且在多线程环境下使用的场景,StringBuilder 适用于字符串经常修改且在单线程环境下使用的场景,StringBuffer 适用于字符串经常修改且在多线程环境下使用的场景。

例如,在单线程环境下进行大量字符串拼接操作时,使用StringBuilder可以获得更好的性能;而在多线程环境下进行字符串操作时,使用StringBuffer可以保证线程安全。

2. 你用过哪些集合?

  • 用过ArrayList,它是基于动态数组实现的列表,支持快速随机访问,适用于需要快速随机访问元素的场景。

  • 用过 HashSet,基于哈希表实现的集合,不允许重复元素,适用于需要快速查找且不允许重复元素的场景。

  • 用过HashMap,基于哈希表实现的映射,适用于需要快速查,不是线程安全的

  • 用过Hashtable,也是基于哈希表实现的映射,不允许使用null键和null值,线程安全。

  • 用过TreeMap,基于红黑树实现的映射,键按升序排列,适用于需要键按特定顺序排列的场景。

3. HashMap和TreeMap有哪些区别?

  • 数据结构:HashMap是基于哈希表实现的,通过键的哈希值来存储数据,因此它具有较快的查找速度。而TreeMap则是基于红黑树实现的,数据按照键的自然顺序或自定义顺序进行排序,因此它具有有序性。

  • 键的要求:HashMap的键不能是null,因为null值无法计算哈希值。而TreeMap的键可以是null,但只有一个null键,因为TreeMap需要键来进行排序。

  • 线程安全性:HashMap是非线程安全的,如果多个线程同时修改HashMap,可能会导致数据不一致。而TreeMap也是非线程安全的,原因与HashMap相同。

  • 性能:在插入、删除和查找操作中,HashMap通常具有更好的性能,因为它可以通过哈希值直接定位到数据所在的位置。而TreeMap由于需要维护数据的顺序,因此在插入和删除操作时可能需要更多的时间。

  • 适用场景:HashMap适用于需要快速查找、插入和删除数据的场景,特别是当键不需要排序时。而TreeMap适用于需要按键排序的场景,例如范围查找、中序遍历等。

4. Java里的反射机制简单说下

Java中的反射机制允许程序在运行时动态地获取类的信息,并且能够操作类的字段、方法和构造函数。简单来说,反射就是提供在运行时获取类信息以及动态调用类的方法的能力。

例子:

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        // 1. 动态加载类
        Class<?> clazz = Class.forName("com.example.User");

        // 2. 创建对象(无参构造)
        Object obj = clazz.getDeclaredConstructor().newInstance();

        // 3. 修改私有字段
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true); // 允许访问私有字段
        nameField.set(obj, "Alice");

        // 4. 调用私有方法
        Method greetMethod = clazz.getDeclaredMethod("greet");
        greetMethod.setAccessible(true);
        String result = (String) greetMethod.invoke(obj); // 输出 "Hello, Alice"
        System.out.println(result);
    }
}

class User {
    private String name;

    private String greet() {
        return"Hello, " + name;
    }
}

反射的几个特点:

  • 动态性:反射允许程序在运行时而不是编译时确定类的结构和行为。

  • 访问控制:即使是私有的成员(字段、方法或构造函数),也可以通过反射被访问和修改(尽管这样做通常不推荐,因为它破坏了封装性)。

  • 类型检查的灵活性:反射可以在运行时检查对象的类型,并执行相应的操作,而不需要在编译时知道具体的类型。

  • 类加载:反射可以动态地加载类,这意味着可以在程序运行过程中加载新的类或接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扫地僧009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值