整理21道 Java面试挑战题

整理21道 Java挑战面试题

1. 为什么HashMap中String、Integer这样的包装类适合作为Key

1、String和Integer等这些类都被final修饰,具有不变性;也保证了key的不变性,并且内部重写了equals和hashCode方法,不容易出现hash计算错误
2、String和Integer保证了hash值得不可变性和准确性,有效减少了hash碰撞
3、String和Integer一定重写了equals和hashCode方法

2. ConcurrentHashMap和Hashtable的区别?

HashTable是阻塞模式的,总是能获取最新的更新,好处是当线程A大量更新数据,期间线程B调用get,线程B就会被阻塞,直到线程A更新完毕,坏处是所有调用都要排除,效率比较低
ConcurrentHashMap是非阻塞模式,在更新时会局部锁住某部分数据,但不会把整个表都锁住,同步读取操作则是完全非阻塞的,好处是在保证合理的同步前提下,效率高,坏处就是读取时不能保证反映最近的更新,线程A更新了Map中的数据,期间线程B只能读取到线程A已经更新完成的数据

3. Array 和 ArrayList 有什么区别?什么时候该用 Array 而不是 ArrayList 呢?

Array可以容纳基本类型和对象,而ArrayList只能容纳对象
Array指定大小后不可变,而ArrayList大小是可变的
Array没有提供ArrayList那么多功能,比如addAll,removeAll和iterator等

4. HashSet是如何保证数据不可重复的?

1、底层由HashMap实现
2、值存放于HashMap的key上
3、HashMap的value统一为PRESENT(存在的,可以为null)

5. ArrayList集合加入1万条数据集合内部会如何处理,应该怎么提高效率?

因为ArrayList的底层是数组实现的,并且数据的默认值是10,如如果插入1万条数据,要不断的扩容,浪费时间,所以我们调用ArrayList的指定容量的构造器方法ArrayList(int size)就可以实现不扩容,提高了性能。

6. 什么情况下需要序列化?

所谓的对象流就是将对象内容进行流化,可以对流化后的对象进行读写操作,也可以将流化后的对象传输于网络之间,一般程序在运行时产生对象,这些对象随着程序的停止运行而消失,但如果我们想把某些对象保存下来,在程序终止运行后,这些对象仍然存在,可以在程序再次运行时读取到这些值,这种情况下就要用到对象的序列化

7. Thread 类中的start() 和 run() 方法有什么区别?

start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码
run()方法当作普通方法的方式调用,程序还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码

8. HashMap的put方法的具体流程?

HashMap在put方法中,它使用hashCode()和equals()方法,当我们通过传递key-value对调用put方法时,HashMap计算Key的 HashCode哈希算法来找出存储key-value对的索引。如果索引为空,则直接插入到对应的数组中,否则判断是否为红黑树,如果是则红黑树插入,否则遍历链表,若长度超过8,则将链表转为红黑树,转成功之后,再插入键值。

9. 自定义异常类时,可以继承的类是?

自定义异常可以自己控制在何处报异常,可继承的有编译时异常Exception和运行时异常runtimeException

编译时异常:必须立即处理的异常,如果不处理,程序就不能通过编译
运行时异常:java编译器不会检查它,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用Throws抛出它,也会编译通过,但运行时会报错

10. 请将ATM提款机终端系统用面向对象的思想设计出来。

成员属性:操作按钮容器,余额,用户名,卡号,输入密码,单次取钱上线,插卡状态,用户是否有效
操作

  • 欢迎页面
  • 选择菜单
  • 是否插卡
  • 输入密码
  • 存钱方法
  • 余额加存款
  • 取钱方法
  • 取钱是否高于上线
  • 余额减存款
  • 查看余额方法
  • 退出
  • 生成订单号
  • 操作日志信息持久化存储
  • 是否打印发票方法
11. Person p = new Person()在内存中做了哪些事情?

1、加载Person.class文件到方法区,同时加载Person类中的static属性
2、在main方法所在的栈区分配引用 p
3、在java堆中开辟空间存放Person类,但是不进行初始化操作
4、默认初始化数据
5、将引用p指向java新开辟的Person类地址

12. 以下代码的执行效果是,为什么?
public class Test {
    public static void main(String[] args) {
        Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
        System.out.println(f1 == f2);	//
        System.out.println(f3 == f4);	//
    }
}

Integer封装类中 -128-127范围 是缓存池(常量池),数值在这范围内的hash值是固定的,而超过这个范围,Integer赋值则需要重新指向新的内存地址,== 在比较基本数据类型时比较的是数值,而比较引用类型时比较的是地址值

13. 列出几种常见的遍历输出方式

for循环

foreach循环

Iterator迭代遍历 while(hasNext){}

14. 手写一个冒泡排序
public static void main(String[] args) {
		int a[] = {0,3,2,4,5,6,7,9,10,1,8};
		for (int i = 0; i < a.length; i++) {
			for (int j = i+1; j < a.length; j++) {
				if(a[i]>a[j]) {
					int temp = a[i];
					a[i] = a[j];
					a[j] = temp;
				}
				
			}
		}
		for (int i : a) {
			System.out.print(i);
		}
		
	}
15. 说一些你知道的算法及使用场景

快速算法 实际项目中有很多地方是有给序列号的,有时需要对这些序列号进行排序。

哈希算法 用于计算hashCode值,HashMap底层就是用到了哈希算法

16. 说一些你知道的设计模式及使用场景。

Spring ioc就是用到了工厂模式和单例模式

17. JVM内存结构了解吗?

流程:生成.class可执行>>>类装载子系统>>>运行时数据区(内存模型)>>>字节码执行引擎

内存模型

  • :存放局部变量

  • :开辟内存空间,创建对象

  • 方法区:常量 + 静态变量 + 类信息

  • 本地方法栈:native修饰,底层C语言实现的。本地方法栈运行的区域(例如:加减操作)

  • 程序计数器:多线程挂起,一个线程转为另外一个线程,判断从何处开始

18. 一个加锁的方法去调用另一个加锁的方法会怎样?

加了锁的非静态方法没有受到任何影响,因为它所竞争的锁并非是class对象锁,而是实例化对象锁,受到影响的有synchronized修饰的静态方法,还有便是加了Class对象锁的方法,本质上便是它们都在竞争当前类的Class对象锁

19. 你遇到过 OutOfMemoryError 错误嘛?你是怎么搞定的?

内存溢出异常,扩大新生代和老年代的内存分配,在允许的情况下

20. 如果我想要让自己的Object作为Key应该怎么办呢?

重写hashCode()和equals()方法

1、重写hashCode()是因为需要计算存储的存储位置

2、重写equals, 目的是为了保证key在哈希表中的唯一性

21.Spring框架你是如何使用的?
  • 在项目中引入Spring 框架可以带来以下好处:

    • 降低组件之间的耦合度,实现软件各层之间的解耦,可以使用容器提供众多服务,如事务管理服务,服务消费等等,当我们使用容器管理事务时,就不用再手动控制事务,也不需处理复杂的事务传播,容器提供单例模式支持,不用再自己编写实现代码,容器AOP技术,利用它很容易实现,权限拦截运行期监控等功能

关注博客爵士,更多精彩等你来战!!(大数据,python,java,操作系统)
http://www.yazz.top/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值