面试总结====java基础

目录

            • 1、https和http有什么区别?
            • 1、HashMap的put过程是怎样的?
            • 1、ArrayList是怎么实现的?
            • 1、HashSet是线程安全的吗?如果让你自己实现一个HashSet以及HashMap你会怎么设计?如果要实现线程安全的呢?
            • 1、final关键字、static关键字具体作用有哪些?
            • 1、static关键字修饰的变量在jvm哪个区?
            • 1、编程式事务和声明式事务区别?使用场景分别是什么?
            • 1、线程和进程的区别?并发和并行的区别?
            • 1、servlet3.0,spring的DeferredResult是怎么实现的?
            • 1、catch里的return和finally谁先执行?
            • 1、怎么上传多个文件?
            • 1、nio的3大核心组件是什么?
            • 1、怎么计算hashmap的初始长度?
            • 1、用过jdk8语法吗?
            • 2、动态代理和静态代理的区别?
            • 3、cglib和jdk动态代理有什么区别?
            • 4、如何避免异常?
            • 5、Object中有哪些默认方法?都是干啥用的?重写hashcode方法是为了什么,一般是怎么重写的?
            • 5、Intenger(100)类型和int(100)用==比较是true还是false?如果是200呢?超过127会怎样?
            • 5、写一个rpc框架需要用到哪些技术点?
            • 1、计算机资源和操作系统以及jvm的关系?
            • 5、来手写一个单例模式?
            • 5、两个Long怎么比较?
            • 15、反射获取class的方式?反射创建对象的方式?
            • 6、反射和类加载有什么区别?
            • 7、集合copy后,2个变量一个想变一个不想变怎么解决?
            • 8、==nettty中nio是什么?io多路复用什么意思及意义何在?==
            • 9、正向代理和反向代理区别?
            • 10、java spi是怎么做的?
            • 28、java中的spi到底是怎么实现的?
            • 11、类变量、静态、构造、父类等加载顺序?
            • 14、传值和传址的区别与本质?
            • 30、String是传值还是传址?
            • 30、String类为什么要加final?
            • 31、netty和nio的关系?
            • 32、字节流和二进制流一样吗?
            • 33、http报文结构及状态码?
            • 33、会shell编程吗?
            • 5、hashmap的key为什么要以2的幂次方?这个问题有问题吧?
            • 29、HashMap的实现原理?
            • 12、HashMap的数据结构和原理是什么?
            • 13、1.7中HashMap死循环是怎么产生的?
            • 13、ConcurrentHashMap中1.7和1.8有什么区别?1.7中死锁是怎么产生的?1.8有哪些改进?
            • 13、ConcurrentHashMap的数据结构和实现原理?
            • 16、注解的本质,怎么自定义注解?
            • 17、上传文件后台是怎么处理的?
            • 18、java中基本类型和引用类型?
            • 19、tcp三次握手,四次挥手?tcp为什么要3次握手?
            • 20、一次完整的http请求过程?
            • 21、序列化与反序列化的本质?
            • 22、http2.0与http1.1的特点与区别?
            • 23、io模型有哪些?
            • 24、uri和url区别?
            • 25、bio与nio的区别?
            • 26、网卡是什么?
            • 27、tcp/ip四层模型?osi七层模型?

1、https和http有什么区别?
1、HashMap的put过程是怎样的?
1、ArrayList是怎么实现的?
1、HashSet是线程安全的吗?如果让你自己实现一个HashSet以及HashMap你会怎么设计?如果要实现线程安全的呢?
1、final关键字、static关键字具体作用有哪些?
1、static关键字修饰的变量在jvm哪个区?
1、编程式事务和声明式事务区别?使用场景分别是什么?

1、声明式事务,自动开启、提交、回滚事务,使用简单。aop的方式实现。但问题很多,比如在事务中有远程调用,就会拉长整个事务,那么就会导致本事务的数据库连接一直被占用,那么如果类似操作过多或者并发量较大,就会导致数据库连接池耗尽。就需要编程式事务手动控制了。
2、编程式事务,手动开启、提交、回滚事务。粒度更细自己编程控制事务。

1、线程和进程的区别?并发和并行的区别?

1、进程是程序的一次动态执行,程序是静态的指令集合。进程是操作系统除cpu外的系统资源分配的基本单位,线程是cpu资源分配的基本单位。线程是轻量级进程,是cpu执行的基本单元,进程中的多个线程可以共享进程的系统资源。
2、并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。公交车前后门都可以上车是并行,只有一个门一起挤公交是并发。

1、servlet3.0,spring的DeferredResult是怎么实现的?

开启异步servlet,提高吞吐量,就是一个异步的思想,观察者模式。

1、catch里的return和finally谁先执行?

在执行时,return语句先把返回值写入但内存中,然后停下来等待finally语句块执行完,return再执行后面的一段。
当finally调用的任何可变API,会修改返回值;当finally调用任何的不可变API,对返回值没有影响。

1、怎么上传多个文件?

1、MultipartFile[]
2、(MultipartHttpServletRequest) request

1、nio的3大核心组件是什么?

面试总结====java基础_第1张图片

传统 IO 基于字节流和字符流进行操作,而 NIO 基于 Channel 和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。IO 是面向流的,NIO 是面向缓冲区的。Selector(选择器)用于监听多个通道的事件,也就是管理多个连接。只有在连接真正有读写事件发生时,才会调用函数来进行读写,大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护
多个线程,并且避免了多线程之间的上下文切换导致的开销。Stream流是单向的,而 Channel是双向的,既可以用来进行读操作,又可以用来进行写操作。Buffer缓冲区,实际上是一个容器,是一个连续数组。
1、NIO三大核心组件:Selector、Buffer、Channel
2、BIO中是基于流操作的,而NIO中是基于通道(channel)和缓冲区(buffer) 来操作的。
3、一个Selector对应一个线程。一个Selector对应多个Channel。一个Channel对应一个Buffer。
4、ServerSocketChannel的职责只负责处理来自客户端段的连接,不做其他的操作。SocketChannel负责处理服务器与客户端的读写操作。

面试总结====java基础_第2张图片

1、怎么计算hashmap的初始长度?

1、100除以0.75=134。感觉不一定对。

1、用过jdk8语法吗?

1、Lambda表达式,函数式编程FunctionInterface只有一个方法的接口,箭头函数
2、stream流,流式编程,分为终结操作和中间操作,中间操作完还是流类似表,终结操作完就是结果集类似行数据。如map操作每一个item*2,anyMatch有一个匹配就返回。本质是一个管道pipeline。

2、动态代理和静态代理的区别?

1、静态代理是编译时就写好了代理类。代理类和被代理类都要实现相同的目标接口,扩展时要自己写新的代理类或者修改代理类增加代理方法,要修改代码。
2、动态代理是运行时生成的代理类。代理类自动生成不需要自己写,被代理类实现目标接口就好了。

3、cglib和jdk动态代理有什么区别?

1、cglib依赖第三方包,通过修改被代理类字节码来增强并生成子类来实现代理。jdk是自带的,通过实现拦截器InvocationHandler进行增强,通过Proxy.newProxyInstance反射生成代理类并把增强作为参数放进去。
2、jdk要求被代理类必须实现目标接口,cglib不要求被代理实现目标接口,cglib是通过继承被代理类生成子类来实现增强的。这有就是spring当被代理类实现目标接口时使用jdk,如果没实现使用cglib的原因。看起来jdk的功能有所欠缺。
3、jdk8中jdk代理性能比cglib高,spring默认用jdk动态代理。

4、如何避免异常?

异常是可以被处理的,而错误是没法处理的。有些IOE是不能避免的。
1、尽量捕获原始精确的异常
2、尽量不要打印堆栈后再抛出异常,会出现打印多次,不好定位问题
3、非空判断
面试总结====java基础_第3张图片

5、Object中有哪些默认方法?都是干啥用的?重写hashcode方法是为了什么,一般是怎么重写的?

面试总结====java基础_第4张图片

1、重写equals方法时需要重写hashCode方法,主要是针对Map、Set等集合类型的使用,以保证当equals返回TRUE时,hashCode也返回Ture,这样才能使得集合中存放的对象唯一。
2、基于17和31散列码思想来实现。new HashCodeBuilder();Objects.hash;lombok。

5、Intenger(100)类型和int(100)用==比较是true还是false?如果是200呢?超过127会怎样?

面试总结====java基础_第5张图片

5、写一个rpc框架需要用到哪些技术点?
1、计算机资源和操作系统以及jvm的关系?
5、来手写一个单例模式?

面试总结====java基础_第6张图片

5、两个Long怎么比较?

1、包装类型==是不合法的但运行不报错,用longValue()==比较值或者equals比较值

面试总结====java基础_第7张图片

15、反射获取class的方式?反射创建对象的方式?

1、调用对象的getClass()方法
2、类.class
3、Class.forName(),静态方法,性能最好,能够实现解耦,最常用。装入类,并且会初始化类的静态块静态方法。

1、使用.newInstane 方法创建对象。Class clazz=Class.forName(“reflection.Person”); Person p=(Person) clazz.newInstance();
2、使用构造方法并创建对象。Constructor c=clazz.getDeclaredConstructor(String.class,String.class,int.class);Person p1=(Person) c.newInstance(“李四”,“男”,20);

6、反射和类加载有什么区别?

1、类加载就是读入class字节流到jvm方法区,并在堆中创建一个Class对象即java.lang.Class的实例作为方法区的引用,故而才能调Class类的方法。类加载过程包括加载即装载,连接即分配内存空间,初始化即赋值。
2、反射就是程序在运行时能够获取自身的信息。可以获取这个Claas对象查看Class信息或者生成并操作对象的实例。本质就是一个类的操作工具。
3、反射包括类加载的功能还有类的其他操作,也只是类加载的一种方式。如Class.forName()是要求JVM查找并加载指定的类加载连接并初始化,在需要对类进行初始化的时候使用,而ClassLoader.loadClass()就是类加载器从相应目录下找class文件只是加载和连接,没有初始化,是一种延迟加载。反射就是具体类的抽象,具体类的所有操作的工具类,包括类的加载,反射加载类功能底层也是类加载器完成的。

类加载的3种方式:
new隐式加载能够直接获取对象的实例,而loadClass()、forName() 显式加载需要调用 Class 对象的 newInstance() 方法来生成对象的实例。
1、由new关键字创建一个类的实例。运行时用 new 方法载入。Person person = new Person();
2、使用Class.forName()。通过反射加载类型,并创建对象实例。如Class clazz = Class.forName(“Person”);Object person =clazz.newInstance();
3、使用某个ClassLoader的loadClass()方法。通过该 ClassLoader 的 loadClass() 方法载入。应用程序可以通过继承 ClassLoader 实现自己的类装载器。如Class clazz = classLoader.loadClass(“Person”);Object person =clazz.newInstance();

7、集合copy后,2个变量一个想变一个不想变怎么解决?

其实就是浅拷贝和深拷贝的东西,引用对象浅拷贝出的新对象会随源对象变化而变化,深拷贝出的新对象不随源对象变化而变化就相当于开辟了新的内存空间了。

浅拷贝:复制引用但不复制引用的对象
深拷贝:不仅复制对象本身,而且复制对象包含的引用指向的所有对象。

浅拷贝的方式
1、遍历循环复制
2、使用List实现类的构造方法。
3、使用list.addAll()方法。
4、使用System.arraycopy()方法。

//1、遍历循环复制
List<Person> destList=new ArrayList<Person>(srcList.size());  
for(Person p : srcList){
       
    destList.add(p);  
}
//2、使用List实现类的构造方法
List<Person> destList=new ArrayList<Person>(srcList);
//3、使用list.addAll()方法
List<Person> destList=new ArrayList<Person>();  
destList.addAll(srcList);
//4、使用System.arraycopy()方法
Person[] srcPersons=srcList.toArray(new Person[0]);  
Person[] destPersons=new Person[srcPersons.length];  
System.arraycopy(srcPersons, 0, destPersons, 0, srcPersons.length); 

深拷贝的方式
1、序列化
2、重写clone方法

//序列化方式
public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
       
    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
    ObjectOutputStream out = new ObjectOutputStream(byteOut);  
    out.writeObject(src);  

    ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());  
    ObjectInputStream in = new ObjectInputStream(byteIn);  
    @SuppressWarnings("unchecked")  
    List<T> dest = (List<T>) in.readObject();  
    return dest;  
}  
List<Person> destList=deepCopy(srcList);  //调用该方法



//clone方法
public class A implements Cloneable {
     
    public String name[];

    public A() {
     
        name = new String[2];
    }

    public Object clone() {
     
        A o = null;
        try {
     
            o = (A) super.clone();
        } catch (CloneNotSupportedException e) {
     
            e.printStackTrace();
        }
        return o;
    }
}

@Test
public void testDeep() {
     
    List<A> src = new ArrayList<>();
    src.add(new A());
    src.add(new A());
    List<A> copy = new ArrayList<>();
    for (int i = 0; i < src.size(); i++) {
     
        copy.add((A) src.get(i).clone());
    }
    //未改变之前打印
    src.forEach(a -> System.out.println("src====" + a));
    copy.forEach(a -> System.out.println("copy====" + a));
    System.out.println("---------------------------");
    src.add(new A());
    //改变之后打印
    src.forEach(a -> System.out.println("src====" + a));
    copy.forEach(a -> System.out.println("copy====" + a));
}

面试总结====java基础_第8张图片

8、nettty中nio是什么?io多路复用什么意思及意义何在?

1、nio就是同步非阻塞,nio是java中的,就是轮询处理。netty对nio做了优化封装,提高了效率。

io多路复用
1、虽然2次调用(等待数据,数据拷贝到用户空间完成)效率低,但是可以监控多个socket通道,根据选择器注册通道,客户端订阅通道,事件通知机制轮询处理多个用户线程。
2、netty4 用的io复用模型,netty5用的异步io即aio,是最先进的,但效果不太好也不完善,netty目前也是主推netty4,基于io复用+nio。windows实现了aio,而linux没有。netty是一个网络通讯框架,封装了这些io网络编程。

select、poll、epoll区别,在io复用中用的比较多,epoll最优秀可以根据情况选型
1、支持打开的最大线程数不同
2、io效率问题
3、报文的传递方式不同

9、正向代理和反向代理区别?

1、正向代理代理的是客户端消费者,反向代理代理的是服务器提供者。
2、正向代理是客户端的一个带头大哥,服务器并不知道实际的客户端即消费者是谁;反向代理是服务器的一个门面,客户端并不知道实际提供服务的是谁。
3、正向代理可以做缓存加速访问资源,反向代理作为公网地址保证内网安全。

10、java spi是怎么做的?

1、在src/main/resources/META-INF/services下定义一个文件名为接口全限定名、内容为实现类的全限定名的配置文件。
2、util包下ServiceLoader.load加载该类,反射实例化,再往深就是继承AbstractProcessor编译时扫描。如mysql驱动中Class.forName(“com.mysql.jdbc.Driver”)这句就被删掉了,用spi就可以实现。个人理解可以看作是对适配类的加载,或者实现类的加载。

28、java中的spi到底是怎么实现的?

1、spi就是基于接口编程+策略模式+配置文件。
2、ServiceLoader,util包下的工具类,一个加载外部服务的工具,服务提供者可以以扩展的形式比如将 jar 文件放入扩展目录中或者给出应用程序类路径。通过扫描classes下META-INF/service下的接口中的实现类,然后ServicerLoader.load。唯一要求实现类要有无参构造,才能反射实例化。以延迟方式查找和实例化服务,也就是说根据需要进行。

11、类变量、静态、构造、父类等加载顺序?

1、父类–静态成员变量;静态代码块;静态方法
2、子类–静态成员变量;静态代码块;静态方法
3、父类–成员变量;代码块
4、父类–构造方法
5、子类–成员变量;代码块
6、子类–构造方法
7、父类–普通方法
8、子类–普通方法

14、传值和传址的区别与本质?

1、传值。传入参数为基本数据类型和字符串String类型时是值传递?本质就是这个值的拷贝在传递。包括基本类型的包装类型?String是不可变的,底层的char数组是final的。new出的string也一样。这里个人理解比如Long和String的hashcode是计算而得固定的,且都加了final,所以可以看作对象是不变的,但应该都是引用类型所以应该都是址传递。
2、传址。传入参数为StringBuffer、数组、对象时是址传递,本质就是对象引用的拷贝在传递。拷贝跟原对象指定的是同一块内存区域,所以在方法里面改变该内存区域的内容对外面会有同样的影响。

面试总结====java基础_第9张图片

30、String是传值还是传址?

1、引用对象都是传址,String本质是个char数组,所以是传址的。
2、基本类型都是传值的,但基本类型的包装类都是传址的,引用对象都是传址。

30、String类为什么要加final?

1、为了实现字符串常量池,这样可以在运行时节约很多heap空间。而如果不加final,变量改变了它的值,那么其它指向这个值的变量的值也会一起改变,比如这个变量指向一个对象。
2、为了实现String可以创建HashCode不可变性。 因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
3、不可变性支持线程安全。虽然value是不可变的,也只是value的引用地址不可变。挡不住Array数组本身数据是可变的事实。所以final并不一定是线程安全的。final只能保证可见性,每次读到的是最新的而已。这里还有待再深入理解。
面试总结====java基础_第10张图片

31、netty和nio的关系?

netty是一个java写的开源框架,封装了java中nio编码的繁琐,简化了网络编程的开发,能快速开发出高性能高可用的网络应用程序。

32、字节流和二进制流一样吗?

字节流读写二进制数据?二进制流和文本流有差别。

面试总结====java基础_第11张图片

33、http报文结构及状态码?

面试总结====java基础_第12张图片

面试总结====java基础_第13张图片
面试总结====java基础_第14张图片

33、会shell编程吗?
>#!/bin/bash
num1=$[2*3]
num2=$[1+5]
>if test $[num1] -eq $[num2]
	then
	    echo '两个数字相等!'
	else
	    echo '两个数字不相等!'
fi

>#!/bin/bash
for var in item1 item2 ... itemN
	do
	    command1
	    command2
done
5、hashmap的key为什么要以2的幂次方?这个问题有问题吧?
29、HashMap的实现原理?

HashMap,hash映射是一种压缩映射,就会有hash冲突,解决方法比如链地址法,Hashmap和ConcurrentHashMap链表挂葡萄就是一种链地址法。hash算法就是将消息压缩到某一固定长度的摘要函数。常用hash函数有直接取余法,乘法取整法,平方取中法,md5,sha-1都是摘要计算压缩映射。md5是不可逆的但可以用彩虹表破解,所以要加盐。位运算,比取模运算快,所以都要求长度为2的乘方数速度快。扩容为原来的2倍,重新散列。为什么扩容2倍,了2的乘方位运算速度快,还因为这样可以使得添加的元素均匀分布在HashMap中的数组上,减少hash碰撞,避免形成链表的结构,使得查询效率降低。

12、HashMap的数据结构和原理是什么?

HashMap的数据结构是集数组、线性链表、二叉树(红黑树)优点为一体的结构。链表长度大于等于8,先看table的长度如果小于64先扩容,否则转红黑树。红黑树节点小于等于6转链表。扩容2倍,负载因子0.75是基于对时间和空间的综合结果。hashcode的高16位和低16位进行异或运算得出hash常数,再取模数组长度找到下标(实际上是用与运算的效率高,和数组长度-1进行与运算)。具体就是3步:
1、hashCode是native方法返回jvm内存地址可以这么理解。而String的hashCode是对字符数组每一位进行计算而来的,乘子31是因为31 * i =(i << 5) - i 转为位运算简单效率高,且是质数降低hash冲突效果相对更好(101比31更好),而且乘数相对小得出的哈希值不易超出int的最大范围。超出32位用long进行存储64位但最终只取低32位的,高位丢弃。
2、然后对hashCode计算hash。hash就是散列,使分布均匀的算法。hashCode ^ (hashCode >>> 16),高16bit不变,低16bit和高16bit做一个异或,为了减少hash碰撞。
3、拿到hash后与length做与运算得到数组下标,h & (length-1),与运算比取模%性能高。其实 h & (length-1) = h % 16。

面试总结====java基础_第15张图片

<< : 左移运算符,num << 1,相当于num乘以2  低位补0
>> : 右移运算符,num >> 1,相当于num除以2  高位补0
>>>: 无符号右移,忽略符号位,空位都以0补齐
% : 模运算 取余
^ : 异或 0^0=00^1=11^0=11^1=0& :0&0=0;   0&1=0;    1&0=0;     1&1=1;
| :0|0=00|1=11|0=11|1=1~ :~0=1~1=0static final int hash(Object key) {
     
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

/**
 * 返回数组下标
 */
static int indexFor(int h, int length) {
     
    return h & (length-1);
}

面试总结====java基础_第16张图片

面试总结====java基础_第17张图片

13、1.7中HashMap死循环是怎么产生的?

1.7中HashMap死循环,多线程情况下扩容时环形链表待续

13、ConcurrentHashMap中1.7和1.8有什么区别?1.7中死锁是怎么产生的?1.8有哪些改进?
13、ConcurrentHashMap的数据结构和实现原理?

面试总结====java基础_第18张图片

ConcurrentHashMap是线程安全的,HashTable也是线程安全的但是性能不好已被淘汰。
1、JDK 1.7 中使用分段锁,相当于把一个 HashMap 分成多个段,每段分配一把锁,锁粒度基于 Segment,Segment 继承 ReentrantLock 加锁。
2、JDK 1.8 中使用 CAS + synchronized。table的每个桶都是一个锁,锁粒度更小了。

16、注解的本质,怎么自定义注解?

1、注解就是打标签,定义一种规则,一类的抽象。
2、注解本质是一个继承了Annotation的特殊接口。解析注解,一种是编译期扫描,一种是运行期反射。如编译器检测到某个方法被修饰了@Override 注解,就会检查父类中是否具有一个同样的方法签名。运行期反射时,JDK 动态代理生成一个目标注解的代理类,通过AnnotationInvocationHandler进行增强。也就是通过反射获取类 、方法或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

面试总结====java基础_第19张图片

自定义注解,元注解就是注解的注解
@Target:注解的作用目标,如ElementType.METHOD
@Retention:注解的生命周期,如RetentionPolicy.RUNTIME
@Documented:注解是否应当被包含在 JavaDoc 文档中
@Inherited:是否允许子类继承该注解

类继承关系中@Inherited的作用:
1、类继承关系中:子类会继承父类使用的注解中被@Inherited修饰的注解
2、接口继承关系中@Inherited的作用:接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被@Inherited修饰
3、类实现接口关系中@Inherited的作用:类实现接口时不会继承任何接口中定义的注解

17、上传文件后台是怎么处理的?

1、借助minio、fastdfs的客户端,MultipartFile接收,InputStream while(true)循环读写。

18、java中基本类型和引用类型?

基本类型:
1、byte,short,int,long,flout,double,boolean,char
2、占用字节数1,2,4,8,4,8,1,2字节。1字节8位。

面试总结====java基础_第20张图片

引用类型:
1、类class
2、接口interface
3、数组array

19、tcp三次握手,四次挥手?tcp为什么要3次握手?

1、第1次握手:客户端将标志位 SYN 置为 1,随机产生一个值 seq=J,并将该数据包发送给服务器端,客户端进入 SYN_SENT 状态,等待服务器端确认。
2、第2次握手:服务器端收到数据包后由标志位 SYN=1 知道客户端请求建立连 接,服务器端将标志位 SYN 和 ACK 都置为 1,ack=J+1,随机产生一个值 seq=K, 并将该数据包发送给客户端以确认连接请求,服务器端进入 SYN_RCVD 状态。
3、第3次握手:客户端收到确认后,检查 ack 是否为 J+1,ACK 是否为 1,如果 正确则将标志位 ACK 置为 1,ack=K+1,并将该数据包发送给服务器端,服务器 端检查 ack 是否为 K+1,ACK 是否为 1,如果正确则连接建立成功,客户端和服 务器端进入 ESTABLISHED 状态,完成三次握手,随后客户端与服务器端之间可以 开始传输数据了。

类似打电话:
1、你好,李四在吗,我是张三?
2、你好张三,我是李四,去吃大餐吗?
3、可以走。

总结:
可以这样理解SYN=1,seq=k 这种消息是一个发送格式。ACK=1,ack=k+1 这种消息是一个应答格式。ack是对seq的应答+1。

面试总结====java基础_第21张图片

面试总结====java基础_第22张图片

面试总结====java基础_第23张图片

20、一次完整的http请求过程?

1、http报文,tcp包一层,ip包一层,以太网包一层

面试总结====java基础_第24张图片

面试总结====java基础_第25张图片

21、序列化与反序列化的本质?

jdk提供的序列化Serializable接口就实现好了,jdk这个序列化效率低,有很多高效的序列化算法的。
1、序列化:对象转01串
2、反序列化:01串转对象

22、http2.0与http1.1的特点与区别?

http1.0
  1、无状态、无连接、性能差
http1.1
  1、持久连接,keep-alive,5秒
  2、请求管道化
  3、增加缓存处理(新的字段如cache-control)
  4、增加Host字段、支持断点传输等
http2.0
  1、二进制分帧
  2、多路复用(或连接共享),性能提升很多
  3、头部压缩,节约带宽
  4、服务器推送
http3.0

23、io模型有哪些?

1、bio同步阻塞
2、nio同步非阻塞
3、io复用
4、aio(nio2)异步非阻塞

同步和异步的区别
1、表示结果的通知机制,同步就是调用方主动等待结果返回,异步是不需要主动等待而是用其他消息方式通知

阻塞和非租塞的区别
1、表示结果返回前,调用方的状态。阻塞就是等待结果啥也不干了,非租塞就是线程可以解放做其他的事

面试总结====java基础_第26张图片
面试总结====java基础_第27张图片

24、uri和url区别?

uri:统一资源标识符,用于标识 Web 资源的字符串的各个不同部分,如http://www.baidu.com
url:统一资源定位符,是uri的特例,是uri的子集。包含了定位 Web 资源的足够信息,如http://www.enjoyedu.com:8080/news/index.jpg?boardID=5&ID=24618&page= 1#name

25、bio与nio的区别?

1、面向流和面向缓冲区
2、阻塞和非租塞,线程可以抽出来干其他事情
3、nio的selector选择器,一个线程可以处理多个网络连接,监视多个通道。事件监听机制,有事件执行。处理完删除事件。读、写、连接、接受连接4个事件。

26、网卡是什么?

1、网卡是电脑与局域网相互连接的设备,包括OSI 模型的两个层物理层和数据链路层。可以理解为电信号或者电磁波信号收发的设备。
2、网卡的功能主要有2个:
  1、将电脑的数据封装为帧,并通过网线(对无线网络来说就是电磁波)将数据发送到网络上去;
  2、接收网络上其它设备传过来的帧,并将帧重新组合成数据,发送到所在的电脑中。

网卡能接收所有在网络上传输的信号,但正常情况下只接受发送到该电脑的帧和广播帧,将其余的帧丢弃。然后,传送到系统CPU做进一步处理。当电脑发送数据时,网卡等待合适的时间将分组插入到数据流中。接收系统通知电脑消息是否完整地到达,如果出现问题, 将要求对方重新发送。那怎么区分发送的帧呢?
1、MAC 从PCI 总线收到IP数据包,根据ip和自己匹配,然后可以记录在以太网ARP路由表中。
2、无线网卡,当物理层接收到信号并确认无错后提交给MAC-PHY子层,经过拆包后把数据上交MAC层,然后判断是否是发给本网卡的数据,若是则上交,否则丢弃。

27、tcp/ip四层模型?osi七层模型?

1、tcp/ip四层应用层、传输层、网络层、链路层
2、osi七层应用层表示层会话层、传输层、网络层、链路层物理层

面试总结====java基础_第28张图片
面试总结====java基础_第29张图片
面试总结====java基础_第30张图片

你可能感兴趣的:(面试)