面试题Two

1 自增面试题

  public static void main(String[] args) {
        int i = 1 ;
        i=i++;
        int j = i++;
        int k = i+ ++i*i++;
        System.out.println("i="+i);//4
        System.out.println("j="+j);//1
        System.out.println("k="+k);//11
    }
	//  局部变量()        操作数栈()
    //i++,与++i的关系, i++是先将值压入操作数栈中,后来再把值给回局部变量

    // i    局部变量(1)        操作数栈(1)
    // 执行 i++ 局部变量 i的值 + 1 =2
    // 执行完后局部变量=2,
    // 然后将操作数栈的值重新给回局部变量,所以i的值又变回1
    // i    局部变量(2)        操作数栈(1)

    // 执行int j = i++
    // i    局部变量(1)        操作数栈(1)
    // j    局部变量(0)        操作数栈(无)
    // 执行完后i的局部变量+1 ,然后将i的操作数栈的值给了j
    // i    局部变量(2)        操作数栈(无)
    // j    局部变量(1)        操作数栈(无)
    //此时i的值2 , j的值为1     k的值为0

    // int k = i+ ++i*i++;
    //      i 局部变量(2)        操作数栈()
    //      k 局部变量(0)        操作数栈()
    // int k = i+ ++i*i++; 先算前面再算后边,所以先将i的值压入操作数栈
    //      i 局部变量(2)        操作数栈(2)
    //      k 局部变量(0)        操作数栈(无)
    // int k = i+ ++i*i++; 开始算后边的++i,优先级较高,先将局部变量+1 再压入操作数栈
    //                    压入的 操作数栈(3)
    //      i 局部变量(3)        操作数栈(2)
    //      k 局部变量(0)        操作数栈(无)
    // int k = i+ ++i*i++; 开始算最后边的i++,先压入操作数栈,再让局部变量+1
    //                    压入的 操作数栈(3)
    //                    压入的 操作数栈(3)
    //      i 局部变量(4)        操作数栈(2)
    //      k 局部变量(0)        操作数栈(无)
    // 至此所有数据压入完毕,开始算最后的结果
    // ++i压入的操作数栈为3,i++压入的操作数栈为3     ++i*i++ =   3*3 =9
    // i+ 压入的操作数栈是2      所以i+ ++i*i++  = 2 + 9 = 11
    // 最后将操作数栈的值赋值给k=11 ,而i的局部变量是4
    //最终的结果为i=4 j=1 k=11


  public static void main(String[] args) {
        int i = 1 ;
        i++;
        int j = i++;
        int k = i+ ++i*i++;
        System.out.println("i="+i);//5
        System.out.println("j="+j);//2
        System.out.println("k="+k);//19
    }

        

在这里插入图片描述

2 什么是Singleton

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

解决懒汉式线程安全问题(加锁)

public class Singleton4 {
    private  static  Singleton4 instance;
    private  Singleton4(){

    }
public  static  Singleton4 getInstance(){
        //=============待优化  
    synchronized(Singleton4.class){   
       if(instance == null){
            instance = new Singleton4();
        }      
    }
     return  instance;
        //==================优化,提高性能,(如果已经存在一个对象,就不用加锁了,直接返回这个对象)
   if(instance==null){
        synchronized(Singleton4.class){   
       		if(instance == null){
           		 instance = new Singleton4();
       		 }       
   		 }
   }     
        return  instance;
        
        
    }
     

}

懒汉式2

/**
 * 在内部类被加载和初始化时,才创建INSTANCE实例对象
 * 静态内部类不会自动随着外部类的加载和初始化而初始化,他是要单独去加载和初始化的
 * 因为是在内部类加载和初始化时,创建的,因此是线程安全的
 */
public class Singleton5 {
    private  Singleton5(){
        
    }
    private static  class  Inner{
        private  static  final  Singleton5 INSTANCE = new Singleton5();
    }
    public  static  Singleton5 getInstance(){
        return  Inner.INSTANCE;
    }
}

3 以下代码执行的顺序是什么?

在这里插入图片描述

在这里插入图片描述

4 编程题: 有n步台阶,一次只能上一步或两步,共有多少种走法

在这里插入图片描述

public class 台阶走法 {
//编程题: 有n步台阶,一次只能上一步或两步,共有多少种走法
    public  int f(int n){

        if(n==1||n==2){
            return  n;
        }

        return f(n-2)+f(n-1);//递归
        自己画图     4台阶是5种走法     5台阶是 8//5      f3 + f4
        //     3      f2+f3
        //    结果 3+ 2+3 =8
        
        
        // 7  f5 + f4 
        //    f3+f4   +     f2+f3
        //   3 + f2+f3   +    2+3
        //  3+2+3   +       5
        //  =13
    }

    public static void main(String[] args) {
         台阶走法 台阶走法 = new 台阶走法();
        long start = System.currentTimeMillis();
        System.out.println(台阶走法.f(40));//165580141
        long end = System.currentTimeMillis();
        System.out.println(end-start);//589
    }

}

在这里插入图片描述



public class test2 {

    public  static  int total(int step){
        if(step==1||step==2){
            return  step;
        }

        int oneStep =2;//最后走一步,说明到了第二层台阶的坐标处,有两种走法
        int twoStep =1;//最后走2步,说明在第一层台阶的坐标处,有一种走法
        int sum =0;

        //现在第三步台阶,那么最后走一步和最后走2步的之前的走法加起来就是总的方法
        for(int i=3;i<=step;i++){
            sum = oneStep+twoStep;//到达第三步台阶的总方法

            //当下一次加1台阶的时候为4,最后走一步的台阶位置坐标变成了最后走2步的台阶的位置
            twoStep = oneStep;//最后走2步的原本坐标位置是1,现在坐标位置是2  2+2 =4
            //然后当前的sum的坐标就是最后走一步的坐标
            oneStep = sum;//最后走一步的原本坐标位置是2,现在坐标位置是3,  3+1 =4


        }
        return  sum;
    }


    public static void main(String[] args) {
        System.out.println(total(5));
    }

}

在这里插入图片描述

5 数据库常考

一 数据概念

假设现在有两个事务: t1 和t2

1 脏读

(1) t1 将某条记录的AGE值从20修改为30

(2) t2 读取了t1更新后的值30

(3) t1 回滚,AGE值恢复到了20

(4) 此时t2读取到的30就是一个无效值

就是读取到了别人更新但是还没有提交的数据

2 不可重复读

(1) t1 读取了AGE值为20

(2) t2 将AGE值修改为30

(3) t1 再次读取AGE值为30,和第一次读取的值不一致

不可重复读,读到的值没有重复

3 幻读

1 t1 读取了STUDENT表中的一部分数据

2 t2 向STUDENT表中插入了新的行

3 t1 读取STUDENT表时,多出了一些行

幻读:通俗点来说就是你妈在你不知道的时候放了钱进银行卡,你去查的时候发现多了钱,

以为出现了幻觉

二、隔离级别:

数据库系统必须具有隔离并发运行各个事务的能力,使他们不会相互影响,避免各种并发问题

一个事务与其他事务隔离的级别称为隔离级别,SQL标准中规定了多种事务隔离级别,不同隔离

级别对应不同的干扰程度,隔离级别越高,数据一致性越好,但并发性越弱

1 读未提交 Read uncommitted 、

允许t1读取 t2未提交的修改

2读已提交Read committed 、

要求t1只能读取 t2已提交的修改

3可重复读Repeatable read 、

确保t1可以多次从一个字段中读取到相同的值,即t1执行期间禁止其他事务对这个字段进行更新

4串行化 Serializable

确保t1可以多次从一个表读取到相同的行,在t1执行期间,禁止其他事务对这个表进行添加、更新

删除等操作,可以避免任何并发问题,但性能十分低下

在这里插入图片描述
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值