记录大佬面经---第十周

                                                     第一天 

  招银凉经
 

1.算法:两链表的公共节点。

解:牛客网

2.接口与抽象类的区别。什么时候用接口,什么时候用抽象类。

解:  抽象类是对类的抽象,接口是对行为的抽象

如果行为跨越不同类的对象,可使用接口,对于一些现实的类对象,用继承抽象类。

抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知道子类的存在,方法如何实现还不确认,预先定义。

3.浅拷贝和深拷贝区别,深拷贝怎么实现。

解:简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝。

浅拷贝(Shallow Copy):①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。

深拷贝:对于深拷贝来说,不仅要复制对象的所有基本数据类型的成员变量值,还要为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。

实现浅拷贝的方法:通过重写clone()方法进行浅拷贝

/* clone方法实现浅拷贝 */
public class ShallowCopy {
    public static void main(String[] args) {
        Age a=new Age(20);
        Student stu1=new Student("摇头耶稣",a,175);
        
        //通过调用重写后的clone方法进行浅拷贝
        Student stu2=(Student)stu1.clone();
        System.out.println(stu1.toString());
        System.out.println(stu2.toString());
        
        //尝试修改stu1中的各属性,观察stu2的属性有没有变化
        stu1.setName("大傻子");
        //改变age这个引用类型的成员变量的值
        a.setAge(99);
        //stu1.setaAge(new Age(99));    使用这种方式修改age属性值的话,stu2是不会跟着改变的。因为创建了一个新的Age类对象而不是改变原对象的实例值
        stu1.setLength(216);
        System.out.println(stu1.toString());
        System.out.println(stu2.toString());
    }
}

/*
 * 创建年龄类
 */
class Age{
    //年龄类的成员变量(属性)
    private int age;
    //构造方法
    public Age(int age) {
        this.age=age;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public String toString() {
        return this.age+"";
    }
}
/*
 * 创建学生类
 */
class Student implements Cloneable{
    //学生类的成员变量(属性),其中一个属性为类的对象
    private String name;
    private Age aage;
    private int length;
    //构造方法,其中一个参数为另一个类的对象
    public Student(String name,Age a,int length) {
        this.name=name;
        this.aage=a;
        this.length=length;
    }
    //eclipe中alt+shift+s自动添加所有的set和get方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public Age getaAge() {
        return this.aage;
    }
    
    public void setaAge(Age age) {
        this.aage=age;
    }
    
    public int getLength() {
        return this.length;
    }
    
    public void setLength(int length) {
        this.length=length;
    }
    //设置输出的字符串形式
    public String toString() {
        return "姓名是: "+this.getName()+", 年龄为: "+this.getaAge().toString()+", 长度是: "+this.getLength();
    }
    //重写Object类的clone方法
    public Object clone() {
        Object obj=null;
        //调用Object类的clone方法,返回一个Object实例
        try {
            obj= super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }
}


运行结果如下:

姓名是: 摇头耶稣, 年龄为: 20, 长度是: 175
姓名是: 摇头耶稣, 年龄为: 20, 长度是: 175
姓名是: 大傻子, 年龄为: 99, 长度是: 216
姓名是: 摇头耶稣, 年龄为: 99, 长度是: 175

 

实现深拷贝:通过重写clone方法来实现深拷贝

package linearList;
/* 层次调用clone方法实现深拷贝 */
public class DeepCopy {
    public static void main(String[] args) {
        Age a=new Age(20);
        Student stu1=new Student("摇头耶稣",a,175);
        
        //通过调用重写后的clone方法进行浅拷贝
        Student stu2=(Student)stu1.clone();
        System.out.println(stu1.toString());
        System.out.println(stu2.toString());
        System.out.println();
        
        //尝试修改stu1中的各属性,观察stu2的属性有没有变化
        stu1.setName("大傻子");
        //改变age这个引用类型的成员变量的值
        a.setAge(99);
        //stu1.setaAge(new Age(99));    使用这种方式修改age属性值的话,stu2是不会跟着改变的。因为创建了一个新的Age类对象而不是改变原对象的实例值
        stu1.setLength(216);
        System.out.println(stu1.toString());
        System.out.println(stu2.toString());
    }
}

/*
 * 创建年龄类
 */
class Age implements Cloneable{
    //年龄类的成员变量(属性)
    private int age;
    //构造方法
    public Age(int age) {
        this.age=age;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public String toString() {
        return this.age+"";
    }
    
    //重写Object的clone方法
    public Object clone() {
        Object obj=null;
        try {
            obj=super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }
}
/*
 * 创建学生类
 */
class Student implements Cloneable{
    //学生类的成员变量(属性),其中一个属性为类的对象
    private String name;
    private Age aage;
    private int length;
    //构造方法,其中一个参数为另一个类的对象
    public Student(String name,Age a,int length) {
        this.name=name;
        this.aage=a;
        this.length=length;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public Age getaAge() {
        return this.aage;
    }
    
    public void setaAge(Age age) {
        this.aage=age;
    }
    
    public int getLength() {
        return this.length;
    }
    
    public void setLength(int length) {
        this.length=length;
    }
    public String toString() {
        return "姓名是: "+this.getName()+", 年龄为: "+this.getaAge().toString()+", 长度是: "+this.getLength();
    }
    //重写Object类的clone方法
    public Object clone() {
        Object obj=null;
        //调用Object类的clone方法——浅拷贝
        try {
            obj= super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        //调用Age类的clone方法进行深拷贝
        //先将obj转化为学生类实例
        Student stu=(Student)obj;
        //学生类实例的Age对象属性,调用其clone方法进行拷贝
        stu.aage=(Age)stu.getaAge().clone();
        return obj;
    }
}

 

4.双亲委派机制。指定加载器中的类怎么实现?

解:

public class Hello {
   public void test(String str){
       System.out.println(str);
   }
}

public class MyClassloader extends ClassLoader {

    /**
     * 读取文件内容
     *
     * @param fileName 文件名
     * @return
     */
    private byte[] getBytes(String fileName) throws IOException {
        File file = new File(fileName);
        long len = file.length();
        byte[] raw = new byte[(int) len];
        try (FileInputStream fin = new FileInputStream(file)) {
            //一次性读取Class文件的全部二进制数据
            int read = fin.read(raw);
            if (read != len) {
                throw new IOException("无法读取全部文件");
            }
            return raw;
        }
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class clazz = null;
        //将包路径的(.)替换为斜线(/)
        String fileStub = name.replace(".", "/");
        String classFileName = fileStub + ".class";
        File classFile = new File(classFileName);

        //如果Class文件存在,系统负责将该文件转换为Class对象
        if (classFile.exists()) {
            try {
                //将Class文件的二进制数据读入数组
                byte[] raw = getBytes(classFileName);
                //调用ClassLoader的defineClass方法将二进制数据转换为Class对象
                clazz = defineClass(name, raw, 0, raw.length);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //如果clazz为null,表明加载失败,抛出异常
        if (null == clazz) {
            throw new ClassNotFoundException(name);
        }
        return clazz;
    }

    public static void main(String[] args) throws Exception {
        String classPath = "loader.Hello";
        MyClassloader myClassloader = new MyClassloader();
        Class<?> aClass = myClassloader.loadClass(classPath);
        Method main = aClass.getMethod("test", String.class);
        System.out.println(main);
        main.invoke(aClass.newInstance(), "Hello World");
    }
}
//输出结果
//Hello World

 

5.JVM1.8之后的GC区别。

解:现在讲讲JDK1.8带来的变化,JDK1.8的运行时数据区把方法区移除了,变成了元数据区,所以之前的那个图里面的数据块应该变成如下;

 

6.JVM具体调优参数,说几个?

解:-Xms:初始堆大小,默认是物理内存的1/64。

-Xmx:最大堆大小。默认是物理内存的1/4 默认。

-XX:NewSize=n:设置年轻代大小(初始值)。
-XX:MaxNewSize:设置年轻代最大值。

-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。

7.分页操作怎么实现?

解:利用MySQL的语句进行分页。使用MySQL的插件pagehelper。mybatis的拦截器实现。

SELECT * FROM table WHERE 查询条件 ORDER BY 排序条件 LIMIT ((页码-1)*页大小),页大小;

8.事物的隔离级别

9.脏读

10.spring aop的实现。

11.cglib aop 和jdk aop的区别,什么时候用?

12.为什么不实现接口的时候要用cglib。

解:

public final class $Proxy0 extends Proxy implements Hello 

 可以看到默认的jdk动态代理$Proxy0承了一个类,不能在继承了。

13.spring事物。

14.为什么要序列化。

解:

什么叫序列化:把内存中的Java对象转换成二进制流,对象的序列化是操作的堆内存中的数据。

        java对象序列化后可以很方便的存储或者在网络中传输。
        从服务器硬盘上把序列化的对象取出,然后通过网络传到客户端,再由客户端把序列化的对象读入内存,执行相应的处理。

15.不序列化除了transient怎么实现。

解:使用static修饰。

16、给两张表,A、B

A : name(姓名) id(id) project(课程)

B:name(姓名) id(id) class(班级)

求class=class1班中,各个课程的人数?

SELECT  A.project,COUNT(*)AS '人数' FROM A,B WHERE A.id=B.id AND B.class='c1' GROUP BY A.project 

 

                                                    第二天

因为自我介绍的时候提到了项目,所以面试官问了挺久,这部分就不展开了。

1.springboot加载配置的顺序?

解:

工程根目录:./config/
工程根目录:./
classpath:/config/
classpath:/----对应的yml和properties

2.GC回收的是什么对象?

解:

(1)、软引用:内存不足的时候被回收。使用SoftReference API来定义。使用场景:缓存,当内存不足时,JVM自动进行回收。

(2)、弱引用:无论内存是否充足,只能活到下一次GC前,就会回收被WeakReference引用关联的对象。(当只有弱引用时,只要GC就一定会被回收)

(3)可达性分析后标记的对象:第一次标记不可达的对象,然后在这群对象里面将第一次执行finalize()方法的对象放入一个队列中,去执行这个方法(可能自救成功),第二次是队列的小规模标记。这时候,还被标记的对象就可以被GC了。

(4)使用引用计数法标记的对象当计数为零时会被GC回收掉
 

3.Full GC什么时候触发

(1)、老年代空间不足,没有连续的内存空间盛放大对象。

(2)、空间分配担保机制失败:虚拟机检查老年代的最大连续空间是否大于新生代所有对象的总和。

(3)、GMS失败发生concurrent mode failure会引起Full GC,因为老年代剩余的连续空间不足,导致和GC线程并发执行的用户线程创建的大对象无法直接进入老年代。

(4)调用System.gc:可能会GC。

(5)统计得到的Minor GC晋升到旧生代的平均大小大于老年代的剩余空间。

(6)Metaspace区内存达到阈值

4.main能被重载吗

可以的

5.为什么不行

6.父类的静态方法能被子类重写吗?

这一题我答得胸有成竹,不行,如果子类非要重写,其实相当于是把父类的那个方法隐藏了自己定义一个,如果是Father son = new Son(),son.say();这种格式的话,最终调用的还是Father自己的say,并不能实现多态。

面试官嗯了一声听得出来他很满意哈哈

7.String类为什么是final

解:

(1)、为了实现字符串池:因为不同的字符串变量都指向池中的同一个字符串,可以节约很多heap空间

(2)、为了实现String可以创建HashCode不可变性:适合做键

(3)、线程安全

8.反射 Class.forName 和 classLoader有什么区别

解:在java中Class.forName()和ClassLoader都可以对类进行加载。ClassLoader就是遵循双亲委派模型最终调用启动类加载器的类加载器,实现的功能是“通过一个类的全限定名来获取描述此类的二进制字节流”,获取到二进制流后放到JVM中。Class.forName()方法实际上也是调用的CLassLoader来实现的。

9.HashTable和HashMap有什么区别

我回答一个安全一个不安全,HashTable相当于加了一把大锁,又扯了一下ConcurrentHashMap以为面试官会被我带过去,但是面试官居然没有深入问ConcurrentHashMap

10.还有吗?

我说应用场景的话大概就是这样子了,如果你要说底层源码之类的话,HashTable初始值11,扩容方式是2x+1,而HashMap是16,扩容方式是2x;

11.Java有什么IO流

字符流和字节流

12.有什么区别吗

解:

字节流是最基本的,采用ASCII编码,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的
但实际中很多的数据是文本,又提出了字符流的概念,采用Unicode编码.它是按虚拟机的encode来处理,也就是要进行字符集的转化

13.死锁和避免死锁

解:死锁的概念 :是指多个进程在运行过程中因争夺资源而造成的一种僵局.

(1)、确保所有线程顺序加锁

(2)、在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求。若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。

(3)、死锁检测是一个更好的死锁预防机制

(4)减小锁的作用范围

14.索引什么时候失效

我答对索引列使用函数操作的时候,一通举例,面试官说还有吗,我说还有隐式格式转换的时候,又是一通举例

解:

(1)、如果索引多列最佳左前缀,如若跳过最左列则失效

(2)、索引列上做任何操作(计算、函数、(自动or手动)类型转换)

(3)、 范围 :若有索引则能使用到索引,范围条件右边的索引会失效(范围条件右边与范围条件使用的同一个组合索引,右边的才会失效。若是不同索引则不会失效)

(4)、mysql 在使用不等于(!= 或者<>)的时候无法使用索引会导致全表扫描

(5)、is not null 也无法使用索引

(6)、like以通配符开头('%abc...')mysql索引失效会变成全表扫描的操作

(7)、字符串不加单引号索引失效

(8)、少用or,用它来连接时会索引失效

15.一百亿个整数找出其中只出现过一次的数字

解:

Hash分桶法。

 Hash分桶法,将100亿个整数映射到不同的区间,在每个区间中分别找只出现一次的整数。

 

16.怎么处理高并发的服务

这个问题一下子大脑就懵了,怎么问这种问题啊,这一般人没有实际摸过哪里说得出个所以然啊,最后支支吾吾说可以用消息队列削峰填谷。

17.分布式部署 怎么同步会话状态

这道题我就吹了蛮多的,因为之前面腾讯的时候给问过所以查了挺多,大概就是

①nginx代理确保相同客户机请求到同一服务器

②注册一台中心校验服务器,所有机器的校验环节都丢给这台校验服务器,会话状态只需要保留在校验服务器

③上面两种是基于session需要服务器保留会话状态的,如果是不需要服务器保留会话状态而只需要做一些身份校验的话,只需要把登录状态转为token保留到客户端,客户端每次请求都带上,服务器再解析出状态,这样每一台服务器的编码规则是一样的,就不存在冲突了,还顺带提了一嘴说我自己的服务器就是这么实现的。

 

                                                        第三天

百度提前批一面部分内容

1、序列化方式有哪些,有什么用,怎么序列化,Serializable接口下有什么方法(到此不会了,真的想不起来了)

解:定义:序列化就是指把Java对象转换为字节序列的过程即把对象进行流化。

用处:将对象转为字节流存储到硬盘上,做持久化处理

         网络传输(二进制形式),方便了网络传输。

序列化的方式:

Java Serialization(主要是采用JDK自带的Java序列化实现,性能很不理想)

Json(目前有两种实现,一种是采用的阿里的fastjson库,另一种是采用dubbo中自己实现的简单json库)

FastJson(阿里的fastjson库)

Hession(它基于HTTP协议传输,使用Hessian二进制序列化,对于数据包比较大的情况比较友好。) Dubbo Serialization(阿里dubbo序列化)

java中一般将需要序列化的对象实现serializable接口。如果你想某个字段不序列化,将其声明为transient.。

使用jdk自带的序列化。实现Serializable接口实现这个接口就会添加一个serialVersionUID
的版本号,这个版本号的作用是用来验证反序列化时是否用的是同一个类
序列化是通过ObjectOutputStream类的writeObject()方法将对象直接写出
反序列化时通过ObjectInputStream类的readObject()方法从流中读取数据
 

彩蛋:反序列化会有什么问题?

可能会导致InvalidClassException异常。如果没有显式声明序列版本UID,对对象的需求进行了改动,那么兼容性将会遭到破坏,在运行时导致InvalidClassException

 

2、AOP默认的动态代理是什么(JDK),什么时候不用,两个的区别是什么,Cglib返回的是什么,实现原理是什么?

解:JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

       CGlib动态代理:将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

       区别:JDK代理只能对实现接口的类生成代理;CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类。

      总结:1.JDK代理使用的是反射机制实现aop的动态代理,CGLIB代理使用字节码处理框架asm,通过修改字节码生成子类。所以jdk动态代理的方式创建代理对象效率较高,执行效率较低,cglib创建效率较低,执行效率高;2.JDK动态代理机制是委托机制,具体说动态实现接口类,在动态生成的实现类里面委托hanlder去调用原始实现类方法,CGLIB则使用的继承机制,具体说被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,如果被代理类有接口,那么代理类也可以赋值给接口。
 

 

3、.问问网络吧,TCP和HTTP的区别,那你能用TCP写HTTP吗(我??????)

public class HttpServerPost {

    public static void main(String[] args) {
        //1.. 创建服务器,  指定端口
        ServerSocket server;

        try {
            server = new ServerSocket(9999);
            // 2. 指定客户端   阻塞式
            //  完成 三次握手 , 建立管道
            System.out.println("服务器阻塞,等待客户端连接");
            Socket client= server.accept();
            System.out.println("一个客户端建立连接");
            byte[] data=new byte[20480];
            // 接收客户端请求POST
            int len=client.getInputStream().read(data);
            String requestInfo=new String(data,0,len);


//  post请求结果是:POST / HTTP/1.1      请求行 
//  Host: localhost:9999             请求头
//  Connection: keep-alive
//  Content-Length: 20
//  Cache-Control: max-age=0
//  Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
//  Origin: http://127.0.0.1:8020
//  Upgrade-Insecure-Requests: 1
//  User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
//  Content-Type: application/x-www-form-urlencoded
//  Referer: http://127.0.0.1:8020/HelloHBuilder/index2.html?__hbt=1586174211226
//  Accept-Encoding: gzip, deflate
//  Accept-Language: zh-CN,zh;q=0.8
//
//  username=111&pwd=111             请求体,请求体和请求头中间有换行


            System.out.println("post请求结果是:"+requestInfo);
            /***
             *
             * 响应行:HTTP/1.1 200 OK
             * 响应头:
             * Server:xiaozhi Server/0.0.1
             Date:Mon Apr 06 20:34:05 CST 2020
             Content-type:text/html;charset=GBK
             Content-Length:144
             响应头: 可以是text/html : 网页内容
             可以是json
             可会是文件 流
             可以是图片  
             *
             */
            String CRLF="\r\n";
            String BLANK=" ";
            // 响应
            StringBuilder responseContext=new StringBuilder();
            responseContext.append("<!DOCTYPE html>\r\n" +
                    "<html>\r\n" +
                    "	<head>\r\n" +
                    "		<meta charset=\"UTF-8\">\r\n" +
                    "		<title>小置同学</title>\r\n" +
                    "	</head>\r\n" +
                    "	<body>\r\n" +
                    "		 hello!小置同学\r\n" +
                    "	</body>\r\n" +
                    "</html>\r\n" +
                    "");
            System.out.println("响应体:"+responseContext);

            StringBuilder response =new StringBuilder();
            //1)  HTTP协议版本、状态代码、描述
            response.append("HTTP/1.1").append(BLANK).append("200").
                    append(BLANK).append("OK").append(CRLF);
            System.out.println("响应行:"+response.toString());
            //2)  响应头(Response Head)
            response.append("Server:xiaozhi Server/0.0.1").append(CRLF);
            response.append("Date:").append(new Date()).append(CRLF);
            response.append("Content-type:text/html;charset=GBK").
                    append(CRLF);
            //正文长度 :字节长度
            response.append("Content-Length:").
                    // 正文长度,这里必须是字节数正文的
                            append(responseContext.toString().getBytes().length).
                    append(CRLF);
            //3)正文之前
            response.append(CRLF);
            //4)正文
            response.append(responseContext);


            System.out.println("响应头:"+response);

            //输出流
            BufferedWriter bw = new BufferedWriter(new
                    OutputStreamWriter(client.getOutputStream()));
            bw.write(response.toString());
            bw.flush();
            bw.close();


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

4、那挥手的过程中什么时候客户端真正不能传递数据了呢(第三次....吧,我猜的)

5、学了分布式?学了点啥(一致性协议啊,Raft,ZAB,Gossip之类的),那你说说REST(我刚刚提到REST了吗?不知道,我只知道RPC)

解:

ZAB:ZAB协议

Paxos:Paxos

6、那你说说分布式锁吧(三种,实现+原理+性能)

解:https://blog.csdn.net/qq_22343483/article/details/99632956

(1)、redis实现:集群环境下走你

(2)、memcanch:

(3)、zooker:走你

7、.因为之前问set为什么无序,我说分配地址不连续要计算hashcode,所以问hashcode怎么计算(我以为要说hash算法刚说DES,AES说不是这个意思...)

8、map的键有什么要求吗,为什么不用引用数据类型?

解:所以key不能为基本数据类型,则是因为基本数据类型不能调用其hashcode()方法和equals()方法,进行比较,所以HashMap集合的key只能为引用数据类型,不能为基本数据类型。

9、AQS原理

 

                                                           第四天

字节提前批

1. 项目相关

2. Spring介绍一下

3. SpringMVC工作流程?

解:这个网上一搜即可

4. 常见注解说一下?

解:@Autowired @Resource @mapper @value

5. Java用过什么集合框架?

6. HashMap源码说一下(细说,从初始化到put、get、扩容、红黑树、1.8做了哪些优化)

7. ConcurrentHashMap源码看过吗?讲一下吧

8. 如何保证线程安全,1.7呢?

9. JUC包下还知道什么类,讲一下?

解:

JUC的atomic包下运用了CAS的AtomicBoolean、AtomicInteger、AtomicReference等原子变量类

JUC的locks包下的AbstractQueuedSynchronizer(AQS)以及使用AQS的ReentantLock(显式锁)、ReentrantReadWriteLock

附:运用了AQS的类还有:Semaphore、CountDownLatch、ReentantLock(显式锁)、ReentrantReadWriteLock

JUC下的一些同步工具类:CountDownLatch(闭锁)、Semaphore(信号量)、CyclicBarrier(栅栏)、FutureTask
 

10. synchronized实现原理?和Lock的区别?

解:

实现原理:

Synchronized的语义底层是通过一个monitor的对象来完成,其实wait/notify等方法也依赖于monitor对象,这就是为什么只有在同步的块或者方法中才能调用wait/notify等方法,否则会抛出java.lang.IllegalMonitorStateException的异常的原因。

走你

区别:

(1)、锁的实现:一个是JVM级别的一个市API级别的

(2)、性能:在1.6以后对synchronized进行了大量的优化目前两者性能差不多

(3)、等待可中断:synchronized不可以,lock可以

(4)、公平性:都是非公平的而lock可实现非公平的

(5)、绑定多个条件

彩蛋:常见synchronized问题

走你

 

11. volatile呢?怎么实现的?

12. 类加载、双亲委派、自己实现的话怎么做?

解:  https://blog.csdn.net/zhou920786312/article/details/83774608

13. GC讲一下?

14. 说一下你知道的垃圾回收器?

15. Class类文件怎么回收(不是对象,太菜了,想了半天不知道咋回收,没答上)?

解:1、该类的所有实例都被回收

       2、加载该类的类加载器已经被回收

       3、该类的Class对象没有任何被引用,无法通过反射访问该类的方法。

16. 浏览器输入url发生了什么?(细说,包括每一层涉及到的协议)?

17. 刚刚提到TCP三次握手,详细说一下吧?

18. 四次挥手最后等待为什么2MSL?

解:

19. RIP协议怎么解决的环路问题

解决:

(1)触发更新(2)水平分割(3)毒性逆转(4)触发gengxin

20. 数据库范式讲一下(没答好)?

解:

第一范式:列不可分及属性不可再分(保证原子性)

第二范式:非码属性必须完全依赖于主键即要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。例如在员工表中的身份证号码即可实现每个一员工的区分,该身份证号码即为候选键,任何一个候选键都可以被选作主键。

第三范式:任何非主属性不依赖于其它非主属性即要求一个关系中不包含已在其它关系已包含的非主关键字信息,例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在的员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。

21. 引擎讲一下?

解:

 

22. 隔离级别?

 

解:

对下图的解释https://www.cnblogs.com/wajika/p/6680196.html

rr级别下解决幻读:mvcc+next-key-recordhttps://blog.csdn.net/sinat_27143551/article/details/81736330

23. 有哪些索引,为什么用B+树?

解:

24. 项目哪里用到了redis,说一下常用数据类型的使用场景?

25. 三大问题解决?

26. 刚刚提到的分布式锁怎么实现的?

解:

27. Unicode和UTF-8和ASCLL之间的关系?(不知道)?

解决:UTF-8是Unicode一种实现方式

28. Spring里面的设计模式?

29. 还知道哪些?

30. 写个单例吧

31. 时间差不多了,写个简单的题目吧(单词翻转)

 

                                                   第五天

1、如何实现跨域单点登录,如何注销?

解:https://www.cnblogs.com/wuyoucao/p/11089054.html

2、又问https了解吗?我就顺着说了ssl加密和https构建链接的流程对称非对称加密和证书和签名和端口?

解:常见的非对称算法有 RSA。

解:

3、Java自定义类作为HashMap的key需要注意什么?

4、http连接的整个过程?

5、索引为什么快(从b树 b+树讲起,推导到io,到索引,到最左匹配原则以及在物理存储上的结构)?

解:

   (1)、如果没有索引我们查询数据是需要遍历双向链表来定位对应的page,现在通过索引创建的“目录”就可以很快定位对应页上了。

 

6、表A 表B,A有10条数据,B有20条数据,A和B相同的主键有5条,问join,left join, right join各多少条(5,10)?

7、算法题:两个字符串数组,求并差交集?

8、zookeeper选举,原理?

9、JVM哪些对象可以被回收?什么情况下会启动垃圾回收?

10、UDP报头的校验和计算?TCP和UDP的区别,TCP如何解决丢包?

解:https://blog.csdn.net/u010547141/article/details/103425656

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值