2024.4.8 招商银行春招Java面经
1.Lamada表达式的作用?是JAVA8 的特性,允许把函数作为一个方法的参数;免去了使用匿名方法的麻烦,使得代码更为简洁,并且给予Java简单但是强大的函数化的编程能力。语法形式:(参数)->{语句}
2.Java集合有哪些?Collection(List和Set):存储单列数据的集合 和 Map :存储双列数据的集合分为三种:List(ArrayList LinkedList Vector):有序可重复的结合、Set(HashSet和TreeSet):适合于不可重复的集合和Map(HashMap和TreeMap和HashTable):键值对的存储,键不可重复,值是可重复的。各自的特性:ArrayList: 底层数据结构是数组,查询快(根据下标直接访问),增删慢,线程不安全,效率高;LinkedList:底层数据结构是链表,查询慢(遍历整个链表),增删慢,线程不安全,效率高;Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低;
HashSet: 底层数据结构是哈希表,数据无序,可以存放一个Null值,根据哈希算法存取对象,存取速度快,当HashSet中元素个数超过数组大小(默认值为0.75)时,会进行近似两倍的扩容,哈希表将元素添加到集合的过程:当要向哈希表中添加一个元素时,首先,会通过调用hashcode()计算该元素的hashcode;然后,如果哈希表中存在相同hashcode的元素,会调用equals()进行比较:如果返回”true“,则说明这两个元素是相等的,因此,不会将元素添加到集合中,以避免重复;如果返回”false“,则说明这两个元素不相等,新元素会被直接添加到结合中;如果未找到相同的hashcode,则新元素会直接被添加到集合中。
LinkedHashSet: 底层数据结构是链表和哈希表,由链表保证元素有序,由hash表保证元素唯一,允许存储一个null值,其hashcode为0。
TreeSet: 底层数据结构是红黑树,有序,不允许存放null值。
TreeMap: 二叉树实现的,有序HashMap: 无序,线程不安全HashTable:无序,线程安全
3.线程不安全的集合变成线程安全的方法?
List集合的方法:1.Collections工具类:eg:ArrayList list1 = new ArrayList<>();List list = Collections.SynchronizedList(list1)2.使用java.util.concurrent包下的CopyonWriteArrayList()Eg: List list = new CopyonWriteArrayList<>();(先copy出一个容器,往这个容器里面添加新的数据,把新的容器的引用地址赋值给旧的容器地址;在添加数据期间,其他线程读取数据,仍然读取的是旧的容器里的数据,会导致不能实时保证数据的一致性)
Set集合:1.使用Collections集合类:Collections.synchronizedSet()2.使用CopyWriteArraySet()
Map集合:1.HashTable2.Collections.synchronizedMap()3.使用ConcurrentHashMap()
4.JDK1.8的特性?
1.Lambda表达式:允许在Java中更简洁地使用函数式编程风格,代替匿名函数,使得代码更易读、易写。
2.Stream API:一种用于处理集合和数组的声明式编程模型,可以更直观的操作数据集合,比如:过滤fliter、映射map、排序sorted等操作;
3.新的日期与时间API(Java.time):LocalDate currentDate = LocalDate.now();
4.方法引用 System.out::println;
5.default关键字 使得接口中可以有具体的方法:eg:interface Formula{double calcaute(int a);
6.红黑树
5.HTTP传送请求的一次流程
DNS域名解析-》tcp建立三次握手-》发送http请求-》服务器返回html->浏览器根据html构建dom树,cssdom树,加载资源-》呈现给用户
HTTP是基于请求和响应的无状态的基于TCP/IP的应用层协议。
完整的流程:在浏览器中输入url地址,计算机先在浏览器缓存-》系统缓存-》路由器缓存 中找对应的ip地址,如果没有找到,则在本地host服务器中查找,如果还没有找到,则在本地DNS域名服务器中查找。找到后通过TCP的三次握手建立连接,客户端发送一个SYN同步请求,同时客户端进入SYN_SENT状态,服务器接收到数据包,进入SYN_REVD状态,同时返回SYN同步请求和确认号ACK给客户端,客户端接收到ACK后进入ESTABLISHED就绪状态,服务器接收到ACK确认包后也进入established就绪状态。客户端发送http请求给服务器,服务器返回html;浏览器根据html构建dom树和cssom树,合并成渲染树呈现在浏览器页面中,最后加载所需的资源;会话结束后根据四次挥手断开连接。请求方发送一个FIN请求释放连接,同时进入FIN_Wait1状态,接收方收到FIN进入CLOSE_Wait状态,表示已经接收到发送方发过来的关闭连接请求,并发送ACK确认包给发送方,发送方收到ACK后进入Close_wait2状态,等到接收方的数据发送完毕时发送FIN给发送方同时进入Last_ACK状态,发送方收到FIN后,进入Time_Wait状态,并发送ACK确认包给接收方,在等待2msl时间后进入CLOSED状态,接收方收到ACK后则进入CLOSED状态。
6.进程和线程的区别进程是计算机中正在运行的一个程序实例,比如打开微信;进程是轻量级的进程,多个线程可以在一个进程中同时执行,并且共享进程的资源,比如内存空间、网络连接等,比如微信中专门拉取别人发的消息;
区别:1. 进程是资源分配的基本单位,线程是资源调度和执行的基本单位;2. 进程是相互独立的,每个进程都有独立的内存空间和系统资源,线程共享父进程的所有资源;3. 线程之间的切换开销小,不利于资源的管理和保护,进程相反;
7.如何创建线程?1.继承Thread类:重写Thread类的run()方法,将创建的线程要执行的代码放在run()方法中,然后创建实例并调用start()启动线程。2.实现Runnable接口:重新Runnable接口的run()。创建实例,并将实例作为Thread的参数创建Thread对象,该Thread对象是真正的线程对象。3.实现Callable和Future接口,重写Callable接口的call(),可以有返回值,返回值通过FutureTask进行封装。创建实例,将实例作为Thread参数。4.使用ExecutorService线程池或者自定义线程池ThreadPoolExecutor;5.使用CompletableFuture类执行异步任务。
8.线程的生命周期和状态?Java线程在运行的生命周期中的指定时刻只可能处于下面6种状态的其中一种状态:New:初始状态,线程被创建出来但没有被调用start();Runnable:就绪状态,线程被调用了start()等待运行的状态;Running:运行状态,线程获取到CPU资源并执行其run();Blocked:阻塞状态,需要等待锁释放;Waiting:等待状态,表示该线程需要等待其他线程通知或中断(notidy())Time_waiting:超时等待状态,可以在指定时间后自行返回;Terminated:终止状态,表示该线程已经运行完毕;
9.JUC并发编程中的ThreadPoolExculor的拒绝策略什么时候发生?数据源连接池一般请求的连接数超过连接池的最大值的时候就会触发拒绝策略;
10.SpringBoot框架的AOP、IOC/DI?SpringBoot AOP能够将与业务无关,却为业务模块共同调用的通用功能封装起来(事务管理、日志记录、权限控制),便于减少系统的重复代码,降低模块间的耦合性。
分离功能性需求和非功能性需求,是开发人员集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。
Spring AOP是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy, 去创建代理对象,而对于没有实现接口的对象,使用Cglib生成一个被代理对象的子类作为代理。
Spring IOC:创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,现在这种权力交给了IOC容器。动态的向某个对象提供它所需要的其他对象。
11.UDP和TCP的区别?12.了解mysql、redis吗?13.编程题:删除链表的倒数第n个节点