面试小记

目录

java基础

currenthashmap

TCP协议(三次握手四次挥手)

死锁预防条件

事物隔离级别

spring

BeanFactory和ApplicationContext的区别

springboot原理

排序算法

排序算法时间复杂度

排序算法(冒泡)

排序算法(插入)

排序算法(选择)

排序算法(快排)


currenthashmap

jdk7:数组+Segment+分段锁

每一个Segment包含了一个hashEntry数组,每个hashEntry又是一个链表结构,也就是说跟hashmap区别在于Segment。

因为多了个Segment,所以不同于hashmap的一次hash定位,currenthashmap需要两次hash定位。

Segment分段锁,Segment继承了ReentrantLock,插入时锁定一个Segment,不影响其他Segment操作。

获取时用volatile保证。

jdk8:数组+链表+红黑树

ConcurrentHashMap结构基本上和Java8的HashMap一样,不过保证线程安全性。Node的val和next被volatile修饰。

采用CAS+Synchronized保证线程安全,放弃分段锁思想。其中查询,替换,赋值都用cas,数组扩容使用synchronize。

 

TCP协议(三次握手四次挥手)

三次握手

第一次握手:建立连接时,客户端发送syn包(seq=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers);

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(seq=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

四次挥手

第一步,当主机A的应用程序通知TCP数据已经发送完毕时,TCP向主机B发送一个带有FIN附加标记的报文段(FIN表示英文finish);

第二步,主机B收到这个FIN报文段之后,并不立即用FIN报文段回复主机A,而是先向主机A发送一个确认序号ACK,同时通知自己相应的应用程序:对方要求关闭连接(先发送ACK的目的是为了防止在这段时间内,对方重传FIN报文段);

第三步,主机B的应用程序告诉TCP:我要彻底的关闭连接,TCP向主机A送一个FIN报文段;

第四步,主机A收到这个FIN报文段后,向主机B发送一个ACK表示连接彻底释放。

 

为什么需要第三次握手

防止失效的连接请求报文段被服务端接受,从而产生错误。比如网络拥堵的时候客户端发的第一次握手没被服务端接受到,客户端超时接受不到服务端的第二次握手,就会再发一次第一次握手,服务端正确接受到并确认应答,双方开始通信然后结束后释放连接。但如果只有两次握手,这时因网络不再拥堵之前第一次握手被服务端接受到,并打开连接,服务端就会一直延续状态,非常浪费资源。

 

为什么第四次挥手

 

死锁预防条件

1)互斥:一个资源只被一个进程占有;

2)不可剥夺:在进程执行时,其他进程不可强行抢走;

3)请求与保持:进程已经获得了至少一个资源,但是提出了新资源的请求,并且不放手旧资源;

4)循环等待:若干线程循环成圈,等待资源;

打破四个必要条件之一就能有效预防死锁的发生。

 

事物隔离级别

READ_UNCOMMITTED(读未提交)

即能够读取到没有被提交的数据,所以很明显这个级别的隔离机制无法解决脏读、不可重复读、幻读中的任何一种。

READ_COMMITED(读已提交)

即能够读到那些已经提交的数据,可防止脏读。

REPEATABLE_READ(可重复读)

即在数据读出来之后加锁,可防止脏读、不可重复读。

SERLALIZABLE(串行化)

最高的事务隔离级别,不管多少事务,挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务,解决了脏读、不可重复读和幻读。

 

BeanFactory和ApplicationContext的区别

ApplicationContext是BeanFactory的子接口;

BeanFactory延迟注入bean;

ApplicationContext在容器启动,一次性创建所有bean。

 

springboot原理

简述:@Import(AutoConfigurationPackages.Registrar.class) 给容器中导入一个组件,作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

1)@SpringBootConfiguration,即@configuration
2)@ComponentScan,即,扫描包路径,扫描当前启动类同级的包
3)@EnableAutoConfiguration,即自动装配,包含了@Import(AutoConfigurationImportSelector.class)和@AutoConfigurationPackage
1、@Import(AutoConfigurationImportSelector.class),即给容器导入组件AutoConfigurationImportSelector :自动配置导入选择器。

AutoConfigurationImportSelector内一个方法getAutoConfigurationEntry,目的是获取标注了EnableAutoConfiguration类的所有包的所有配置

而@EnableAutoConfiguration注解了SpringBootApplication,则目的是获取启动类下的所有资源,被导入

加载META-INF/spring.factories:自动配置的核心文件,里面一堆的配置类

2、@AutoConfigurationPackage,使用了@Import(AutoConfigurationPackages.Registrar.class)导入类。

Registrar:

 

排序算法时间复杂度

 

排序算法(冒泡)

public void bubbleSort(int []arr){
        int temp;
        boolean flag = false;//优化
        for (int i =0;i<arr.length-1;i++) {//定下来要排四趟序

            for (int j = 0; j < arr.length - 1 - i; j++) {//每趟排序要交换几次数据
                if (arr[j] > arr[j + 1]) {
                    flag = true;//这一趟交换过了
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (flag){//交换过了,那允许继续
                flag = false;
            }else{//都没交换过,继续交换下去也是浪费时间
                break;
            }
        }

 

排序算法(插入)

public static void insertSort(int[]arr){
        for (int i = 1;i<arr.length;i++){//有几张牌就比较(几-1)次
            //记录下抽取的那张牌,数组以0为开始,我们抽取下标为1的第二个元素
            int insertVal = arr[i];//无序牌的值
            int insertIndex = i-1;//有序牌的下标
                //无序牌和有序牌一个一个的作比较,直到无序牌比一张有序牌大才停止
                while(insertIndex >= 0 && insertVal<arr[insertIndex]){
                    arr[insertIndex+1] = arr[insertIndex];//往前挪一位
                    insertIndex--;//有序牌下标减一
                }
                if(insertIndex+1!=i){//优化
                    arr[insertIndex+1] = insertVal;//终于找到比手牌大的了,就放在手牌的后一张
                }
        }
    }

 

排序算法(选择)

public static void selectSort(int[]arr){
        for (int i = 0;i<arr.length;i++){
            int minIndex = i;//记下最小值的下标
            int min = arr[i];//记下最小值
            for (int j = i + 1;j<arr.length;j++){//和所有在第i:0其后的j:1数比较,然后第二个和和所有在其后的数比较
                if (min>arr[j]){
                    min = arr[j];
                    minIndex = j;//更改最小值下标
                }
            }
            if (minIndex!= i){
                arr[minIndex] = arr[i];//最小值保存了,可以后赋值
                arr[i] = min;//最小值赋值给arr[i:0]第一个元素
            }
        }
    }

 

排序算法(快排)

public void quickSort(int[]arr,int left , int right){
        int l = left;//最左边的值,如果你选0的话
        int r = right;
        //中间值
        int pivot = arr[(left+right)/2];
        int temp = 0;
        while(l<r){//只有l和r不相等,那就是还有一个数没被比较

            //不管中间值怎么换来换去,l和r不可能相撞,中间值只有可能和l or r互换,下边的判断arr[l]和arr[r]是否等于中间值,等于则往里面前进,
            //极端现象:如果中间值的左边都不用做出任何改变!那就让中间值和右边交换
            //(接上面)但是!因为会让中间值和右边进行交换,则左边原本是中间值的位置,则换成小于中间值的数,然后就会继续进入while循环中,到右边的位置找比中间值小的数
            while(arr[l]<pivot){//在pivot的左边一直找!直到找到和pivot一样大 or 比piovt大的值才退出
                l+=1;//找不到就+1继续找
            }
            while(arr[r]>pivot){//在pivot的右边一直找!
                r-=1;//找不到就-1继续找
            }
            //
            if (l>=r){//取中间为判断值的话,因为看上面的while分析
                break;
            }
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;
            //这一步是优化,也可以不写,arr[l]成了中间值则 r 前进一位,arr[r]成了中间值则 l 后退一位,毕竟等于中间值只是因为上面和中间互换过
//            if (arr[l] == pivot){
//                r-=1;
//            }
//            if (arr[r] == pivot){
//                l+=1;
//            }
        }
        if (l == r){//不错开则一直满足循环条件,会栈内存溢出
            l+=1;
            r-=1;
        }
        if (left<r){
            System.out.println("排序左边"+left+"+"+r);
            quickSort(arr,left,r);
        }
        if (right>l){
            System.out.println("排序右边"+right+"+"+l);
            quickSort(arr,l,right);
        }
    }

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值