面经汇总校招
中厂
多益网络
Java对象创建的方式,除了new?
- 使用反射(Reflection): 可以使用Class类的newInstance()方法或者Constructor类的newInstance()方法来创建对象。这种方式可以在运行时动态地创建对象,适用于需要根据类名或者构造函数参数来创建对象的情况。
- 使用clone()方法:通过实现Cloneable接口并重写clone()方法,可以创建对象的副本。使用clone()方法创建的对象是原始对象的浅拷贝,需要注意对象的成员变量是否需要深拷贝。
- 使用ObjectInputStream和ObjectOutputStream:通过序列化和反序列化来创建对象。将对象写入到流中,再从流中读取对象,可以实现对象的深拷贝。这种方式适用于需要在网络传输或者持久化存储中传递对象的情况。
- 使用工厂方法(Factory Method):通过定义工厂类和工厂方法来创建对象。工厂方法可以根据不同的条件或者参数来创建不同的对象,提供了更灵活的对象创建方式。
- 使用依赖注入框架(如Spring):通过依赖注入框架来管理对象的创建和生命周期。框架会根据配置文件或者注解来自动创建对象,将对象的创建过程交给框架来处理。
Java中字节流和字符流的区别?
Java中的字符流和字节流是用于处理输入和输出的两种不同的流。它们之间的主要区别在于处理的数据单位和数据类型。
- 字节流(Byte Stream)以字节(Byte)为单位进行读写操作。字节流主要用于处理二进制数据,如图像、音频、视频等文件。字节流在处理数据时不会对数据进行解析或编码,而是直接按照字节的方式进行读写。
- 相比于字节流,字符流提供了更高级的字符处理功能,如字符编码转换、字符缓冲等。它们适用于处理文本数据,能够更方便地读写文本文件中的内容,并且可以避免因字符集不匹配而导致的乱码问题。
Java实现线程让步?
在Java中,可以使用Thread类的静态方法yield()来实现线程的让步。调用yield()方法会让当前线程暂停执行,让出CPU资源给其他线程。调用yield()方法后,线程会从运行状态转换为就绪状态,然后等待调度器再次选择它执行。
JVM OOM问题的常见原因 以及 解决?
JVM(Java虚拟机)的OOM(OutOfMemoryError)问题是指在Java应用程序中出现内存不足的错误。这通常是由于应用程序请求的内存超过了JVM所能提供的限制,导致无法分配更多的内存空间。
常见原因:
- 内存泄漏:如果应用程序中存在内存泄漏,即对象被分配了内存空间但无法被垃圾回收器回收,随着时间的推移,内存占用逐渐增加,最终导致OOM。
- 大对象或者大量对象:如果应用程序创建了过多的大对象或者大量的对象,并且无法及时释放这些对象,那么内存使用就会迅速增加,超出JVM的限制。
- 错误的内存配置:如果JVM的内存配置不合理,例如设置的堆内存(Heap)过小,无法满足应用程序的需求,就会导致OOM问题。
- 递归调用导致栈溢出:如果应用程序中存在无限递归调用的情况,每次递归调用都会在栈上分配一些内存,当递归层数过多时,会导致栈溢出,进而引发OOM。
解决方案:
- 优化内存使用:检查代码中是否存在内存泄漏的情况,确保及时释放不再使用的对象,避免不必要的内存占用。
- 限制对象创建和存储:减少不必要的对象创建和存储,尤其是大对象或者大量对象,可以考虑使用对象池或者缓存来复用对象,减少内存开销。
- 调整JVM内存配置:根据应用程序的需求,合理配置JVM的内存大小,包括堆内存、栈内存等。可以通过调整JVM启动参数,如-Xmx、-Xms等来增加堆内存大小。
- 优化递归调用:检查代码中的递归调用是否存在无限递归的情况,确保递归调用的终止条件合理,避免栈溢出。
- 使用垃圾回收器:选择合适的垃圾回收器,根据应用程序的特点和需求进行调优,以提高内存回收的效率。
Redis中的bigKey该如何排查?
在Redis中,”bigKey”是指占用大量内存空间的键。当一个键的值非常大时,它可能会导致Redis的性能下降,甚至引发一些问题,如网络传输延迟、持久化备份缓慢等。
排查方式:
- 使用Redis命令MEMORY USAGE查看键的内存占用情况。例如,使用以下命令获取键名为”myKey”的内存占用情况:
- 使用Redis命令SCAN或KEYS遍历所有键,并查找内存占用较大的键。例如,使用以下命令遍历所有键,找到内存占用超过一定阈值的键:
- 使用Redis的性能分析工具,如RedisGears、RedisInsight等,来分析内存占用较大的键。这些工具可以提供可视化界面和更详细的分析结果,帮助快速定位bigKey问题。
什么是 MySQL当前读和快照读?
MySQL中的”当前读”(Current Read)和”快照读”(Snapshot Read)是指在事务隔离级别为可重复读(REPEATABLE READ)时,对于读取数据的方式的不同。
当前读(Current Read):当前读是指在可重复读隔离级别下,读取数据时直接读取数据库中最新的数据。当前读会对读取的数据加锁,防止其他事务对该数据进行修改。
快照读(Snapshot Read):快照读是指在可重复读隔离级别下,读取数据时读取的是事务开始时的一个快照(snapshot)数据。这意味着事务在执行期间不会看到其他事务对数据的修改。
在可重复读隔离级别下,MySQL默认使用快照读,即读取事务开始时的数据快照,而不会受到其他事务的修改影响。这样可以保证事务的一致性,避免脏读和不可重复读的问题。
但是,有时候需要读取最新的数据,而不是快照数据,这时可以使用当前读。当前读可以通过添加FOR UPDATE或LOCK IN SHARE MODE语句来实现。例如,使用SELECT … FOR UPDATE语句进行当前读:
经纬恒润
Java的基本数据类型有哪些?
整数类型(整数数值)
浮点类型(小数数值)
字符类型
布尔类型
String 是 Java语言中的基本数据类型吗?
不,String并不是Java语言中的基本数据类型。在Java中,String是一种引用数据类型,用于表示文本字符串。
在Java除不尽的情况如何解决? 比如1/3
在Java中,使用BigDecimal可以解决除不尽的问题。BigDecimal提供了高精度的十进制计算,可以处理小数点后的任意位数。
在Java中为什么 为什么正数最大值需要2^31-1?
在Java中,正数最大值为2^31-1,是因为Java中的整数类型(如int)采用的是补码表示法。补码是一种用于表示有符号整数的编码方式。
在补码表示法中,对于一个n位的二进制数,最高位(最左边的位)表示符号位,0表示正数,1表示负数。因此,对于一个32位的二进制数,最高位是符号位,剩下的31位表示数值部分。