java笔记

java概述

对java平台的理解

  1. 对java平台的理解
    分为三个方面,java的面向对象与其类库、java的跨平台、java的虚拟机和垃圾回收机制。
    (1)java的面向对象和类库:java是一门面向对象的语言,允许程序员以优雅的思维方式进行复杂的编程。java的类库很全,如其核心类库,集合容器、线程相关类、JUC并发包、异常和安全,IO/NIO 等类库。
    (2)java的跨平台:java是“一次编写,到处运行”,他以虚拟机为中间层,非常容易的获取到了跨平台的能力。而C/C++ 是面相操作系统来编程的,开发者需要关心不同操作系统之间的差异,JAVA却通过虚拟机来取消了这种差异。
    (3)java的虚拟机和垃圾回收机制:Java通过垃圾收集器回收分配内存,大部分情况下程序员不需要操心内存的分配与回收。针对虚拟机的效率也有优化的技术,如:JIT技术,会将热点代码编译成机器码。AOT技术,在运行前,通过工具将字节码转为机器码。

    对Java是解释执行的理解

  2. 对Java是解释执行的理解
    首先,先了解编译执行和解释执行的区别,编译执行就相当于将代码或指令等按照一定的规范来书写,再利用编译器一次性翻译成CPU能识别的。而解释执行就是发送一条指令便翻译执行一条指令,这样效率较低。
    这种说法是不太准确的,在 开发时,首先是将源码(即我们写的Java 代码)通过javac 编译为字节码,在运行的时候,通过jvm中的解释器,将字节码转化为机器码。但是在一些常见的JVM中都提供了JIT编译器,其会将热点代码编译为机器码,这种情况下这部分热点代码就属于编译执行而不是解释执行。

    JVM,JRE,JDK 的区别

  3. JVM,JRE,JDK 的区别
    JVM:Java Virtual Machine ,java虚拟机,Java程序需要运行在自己的虚拟机上,不同平台都有自己的虚拟机,也是因此Java可以实现跨平台。
    JRE:Java Runtime Environment, java运行环境,其包含java虚拟机和java运行所包需要的核心类库。核心类库主要包括java.lang包下的,包含了运行java必不可少的系统类,如:包装类型,基本数学函数,字符串处理,线程,异常处理类等,一个开发好的java程序,装上jre即可运行。
    JDK:java Development Kit ,java开发工具,是给java开发人员使用,包含了java开发工具和jre,安装了jdk就不需要安装jre了。
    java开发工具: java.exe 运行工具 , javac.exe 编译工具,javaw.exe GUI 工具
    可以理解为
    jvm + 核心类库 = jre
    jre + 开发工具 = jdk

    什么是跨平台,原理是什么

  4. 什么是跨平台,原理是什么
    跨平台就是一次编译到处运行.原理就是java通过jvm虚拟机来运行在各个平台,只要装了相应的java虚拟机就可以运行java程序

    什么是字节码,采用字节码最大的好处是什么

  5. 什么是字节码,采用字节码最大的好处是什么
    字节码是java的源代码通过java虚拟机的编译器(javac)编译而成,放在.class文件里,不面向任何的处理器和操作系统,只面向虚拟机
    好处: 通过字节码的方式,一定程度的解决了解释型语言效率低的问题,且保留了解释型语言可移植的特点,所以其效率高.由于字节码文件只面向虚拟机,所以放到别的平台上不需要再次编译即可运行
    执行顺序: java源代码经过编译器(javac)编译成字节码----jvm执行字节码(即虚拟命令)-----jvm中的解释器将其转化为机器码----机器执行二进制机器码—运行

    基础语法

    数据类型

    1. 数据类型
      (1)基本数据类型: byte,short,int,long,float,double,boolean,char,1,2,4,8,4,8,1,2
      (2)引用数据类型:class,interface,数组…

    访问修饰符

    1. 访问修饰符
      java中可通过访问修饰符来保护类,对象,变量,方法.
      (1)private , 只能在同一类中可见。可作用在变量、方法中
      (2)default, 不写修饰符默认就是default,在同一包内可见。可作用在类、接口、变量、方法中。
      (3)protected, 对同一包内的类和所有子类可见,可作用在变量、方法中。
      (4)public: 对所有类可见,可作用对象:类、接口、方法、变量

    & 和 &&,| 和 || 的区别

    1. &运算符有两种用法:按位与和逻辑与
      && 是短路运算符,逻辑与&和短路与&&的差别非常大,虽然两者都要求等号两边都为true结果才为true但是 &&当等号左边的值为false的时候便不会计算右边的值,因此被称为短路与
      | 和 || 也是一样。

    final finally finalize的区别

    1. final finally finalize的区别
      (1)final是一个修饰符关键字,其可以修饰类、方法、变量,final修饰的类就不能被继承,final修饰的方法不能被重写,final修饰的变量不能被重新赋值
      (2)finally 是一个异常处理的关键字,一般用在try-catch-finally中,在处理异常的时候通常会将一定执行的代码放到finally中,表示不管是否出现异常都会执行改代码,一般用来放关闭资源的代码。
      (3)finalize 是属于Object类的一个方法,该方法一般由垃圾回收器来调用,它的设计目的是保证对象在被垃圾收集前完成特定资源的回收,现在已经不推荐使用.jdk9中已经弃用

    this super

    1. this super
      (1) this是指向对象本身的一个指针
      其用法分为三类
      普通直接引用,相当于指向了当前对象本身
      当形参和成员名重名,用this来区分
      引用本类的构造函数
      (2)super 可以理解为是指向自己父类对象的一个指针,且指的是离自己最近的一个父类
      其用法分为三类
      普通直接引用,相当于指向当前对象的父类并引用,可以使用super.xx来引用父类的成员
      当子类中的成员变量或方法与父类的重名时,可以使用super来区分
      引用父类的构造函数

    static的主要意义

    1. static的主要意义
      static的主要意义是在于创建独立于具体对象的变量名或者方法。即使不创建对象也可以使用属性和调用方法。
      static还可以用来形成静态代码块来优化程序性能。static可以放到类中的任何地方,可以有多个static块,在类被初次加载的时候会按照static块的顺序来依次执行且只会执行一次,一般将只需要进行一次初始化的操作放在static代码块中。

    面向对象

    面向对象和面向过程的区别

    1. 面向对象和面向过程的区别
      (1)面向过程:
      优点:性能比面向对象高,因为类调用的时候需要实例化,开销较大,比较消耗资源;如单片机、嵌入式、Linux等,性能是最重要的。
      缺点:没有面向对象以维护、易复用、易扩展
      (2) 面向对象:
      优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态的特性,可以设计出低耦合的系统,使系统更灵活,易维护。
      缺点:性能低于面向过程
      (3)面向过程是具体化的,流程化的,解决一个问题需要一步步的分析,一步步的实现
      (4)面向对象是抽象化的,模型化的,只需要抽象出一个类,拥有数据和解决问题的方法。需要什么功能直接实现即可,不需要一步步实现,具体如何实现就不需要我们关心。
      (5)面向对象的底层还是面向过程,只不过把面向过程抽象化然后封装,方便使用。

    面向对象三大特性

    1. 面向对象三大特性
      (1)封装:将一个对象的属性私有化,隐藏内部的实现细节,但同时提供一些共外界访问该属性的方法。通过封装可以提高程序复用性,安全性。
      (2)继承:在自己已有类的基础上,建立新的类,新类可以增加新的数据或功能,也可使用父类的功能,但是不能选择性的继承父类。通过父类可以提高代码复用性。子类可以用自己的方式来实现父类的方法,可以对父类进行扩展,有自己的属性方法,继承是多态的前提。
      (3)多态:父类或接口定义的引用变量可以指向子类或者实现类的实例对象。提高了程序的扩展性,至于该引用变量会指向哪个类的实例对象,只有该引用变量发出的方法调用到底是哪个类中实现的方法,必须在程序运行期间执行。
      (4)实现多态的三个必要条件:继承、重现、向上转型。
      继承:在多态中必须存在有继承关系的子类和父类。
      重写:子类对父类的某些方法重新定义
      向上转型:在多态中需要将子类的引用赋给父类对象,这样才能够具备调用父类和子类的方法的技能。

抽象类和接口的对比

  1. 抽象类和接口对比
    (1)抽象类是用来捕捉子类的通用特性的,实现代码重用。接口是抽象方法的合集,利用接口可以达到API定义和实现分离的目的提供程序的扩展性和可维护性,从设计方面来说,抽象类是对类的抽象,是一种模板设计而接口是行为的抽象,是一种行为的规范。
    (2)相同点:接口和抽象类都不能实例化。都位于继承的顶端,用于被其他类实现或继承。都包含抽象方法,其子类都必须重写这些抽象方法。
    (3)不同点:抽象类使用的关键词是abstract,接口用的是interface。抽象类子类通过extends关键字来继承抽象类并实现该抽象类的所有方法(必须实现),接口通过implements关键字实现接口,并实现接口中的所有方法(必须实现)。抽象类中可以有构造器,接口中没有。抽象类的修饰符可以为任意修饰符默认defalut,接口中的修饰符不能为private或protected且默认修饰符为public。抽象类的字段声明也可以是任意的,接口默认是static和final的。一个类只能继承一个抽象类却可以实现多个接口
    (5)两者在何时使用
    抽象类用来定义某个领域固有的属性,即抽象类表示他是什么,接口用来定义某个领域的扩展功能,即接口表示他能做什么。
    当需要为子类提供公共代码的时候优先考虑抽象类,抽象类中的非抽象方法可以被子类继承,使实现功能的代码更简洁
    当注重代码的扩展性和可维护性时,优先考虑接口。接口和实现类之间不存在任何层次关系,接口可以实现毫不相关类的行为,比抽象类的使用更加方便灵活。接口只关心对象之间的交付方法,而不关心对象所对应的具体实现。接口是程序之间的一个协议,规定。比抽象类的使用更安全、清晰。一般使用接口的情况较多。

成员变量与局部变量的区别

15.成员变量与局部变量的区别
(1)变量是值程序执行的过程中,其值可以在某个范围内发生改变的量.从本质上讲,变量其实是内存中的一小块区域.
(2)成员变量: 包括实例变量和静态变量.作用在整个类中,相当于C语言的全局变量,定义在方法体和语句块外,一般定义在类的声明之下.
(3)实例变量:无static修饰
(4)静态变量:用static修饰,一个类中只有一份,属于对象共用,存储在静态储存区域,经常被声明为变量.
(5)局部变量:类的方法中的变量,访问修饰符不能用于局部变量,声明在方法、构造方法或语句块中,在栈上分配,无默认值(不赋值就不能使用),必须初始化后才能使用。

重载和重写

  1. 重载和重写
    (1)方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态,后者实现的是运行时的多态。
    (2)重载发生在同一个类中,方法名相同但是参数(类型,个数,顺序)不同,与方法返回值和修饰符无关。
    (3)重写是发生在子类中,其方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问的修饰符大于等于父类,如果父类的修饰符为private则子类不能重写,而是个新的方法。(private修饰的只能在同类下访问,因此子类不能继承)

==和equals的区别

  1. ==和equals的区别
    (1) 双等于在基本数据类型中比的是值,引用数据类型是比较的内存地址,判断的是俩个对象是不是同一个。
    (2)equals 默认比的也是对象,但是一般都会覆盖equals方法,来比较两个对象的内容,相等就返回true说明这两个对象相等
    (3)如:String的equals方法就是重写过的,Object的equals比较的是内存地址而String中比的是对象的值。且当创建String对象的时候,虚拟机会在常量池中查找有没有已存在的值和要创建的对象的值相等,如果相等则直接引用,没有就在常量池中创建一个String对象。
    (4)String 在java中是比较特殊的,他有两种赋值方式,引号和new。如果使用引号来赋值,会在常量池中创建字符串对象(如果该常量池中没有该对象相等的值),不会在堆中创建对象,如果使用new来赋值,会在常量池(如果该常量池中没有该对象相等的值)和堆中都创建对象,且String的比较是先在堆中找对象,没有再去常量池中找。

hashCode和equals

  1. hashCode和equals
    (1)HashCode的作用是获取哈希码也叫散列码。其返回的是一个int类型的整数。作用是确定该对象在哈希表中的索引位置,hashCode()定义在JDK的Object中,意味着java中的任何类都有hashCode()函数。散列表存储的是键值对,他能根据键来快速查找值,这其中就用到了散列码(可以快速找到所需对象)。
    (2)为什么要有hashCode
    以HashSet为例,他会先计算对象的hashCode来判断对象加入的位置,同时也会与其他已经加入的对象的hashCode做比较,如果没有相同的hashCode,HashSet就知道对象没有重复出现。但如果有相同的hashCode就会再调用equals来检查对象是否相同,如果相同,就不会加入成功,如果不同则重新散列到其他位置。先使用hashcode后使用equals会减少equals的使用次数,提高执行速度
    (3)如果两个对象相等,则hashCode也一定相同,且通过equals比较返回为true。但是如果两个对象有相同的hashCode却不一定相同,因此当重写equals的时候也要重写hashCode,这样是为了不违背hashCode中相同对象必须有相同哈希值的约定

IO

IO流的种类

  1. IO流的种类
    按照流的流向可分为输入流和输出流
    按照操作单元划分可以分为字节流和字符流
    按照流的角色划分可以分为节点流和处理流
    虽然javaIO流涉及40多个种类,虽然种类多但有规则,且彼此间关系亲密,这四十多个类大部分都是如下四个抽象类基类中派生出的
    (1)InputStream/Reader:所有的输入流的基类,前者是字节流,后者是字符流
    (2)OutputStream/Writer:所输出流的基类,前者是字节输出流,后者是字符输出流

BIO,NIO,AIO的区别

  1. BIO,NIO,AIO的区别
    (1)BIO:Block IO 同步阻塞式IO,是平常使用的传统IO,基于流模型实现,模式为:一个连接一个线程,当客户端有连接请求的时候服务端就需要启动一个线程进行处理,线程开销大,BIO是面向流的,且Stream是单向的
    (2)NIO: Non IO 同步非阻塞IO,是传统IO的升级,提供了Channel、Selector、Buffer等新的抽象,客户端和服务端通过Channel实现了多路复用。客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理,NIO是面向缓冲区的,NIO的channel是双向的。
    NIO通过一个固定大小的线程池来管理工作线程,避免频繁创建、销毁线程的开销等,是构建并发服务的典型方式 。利用单线程轮询机制,通过channel来决定做什么,select阶段的阻塞可以有效的避免大量客户端连接时,频繁线程切换带来的问题,应用的扩展能力有了非常大的提高。
    (3)AIO:Asnchronous IO 异步非阻塞IO,是NIO的升级,异步IO的操作基于事件和回调机制,性能是最好的。底层实现是通过epoll的I/O多路复用。

BIO的原理

  1. BIO的原理
    ①BIO模型是最早的jdk提供的一种处理网络连接请求的模型,是同步阻塞结构.通常由一个独立的Acceptor线程负责监听客户端的连接,收到连接请求后为其创建一个新的线程进行链路处理,处理完后通过输出流来返回给客户端,线程也会销毁.属于典型的一请求一应答模型.
    ②通常在循环中,服务端会调用accept方法等待接收客户端的请求,一旦接收到一个请求,就开始建立通信套接字进行读写,且不能再接受其他客户端的请求,只能等待当前的客户端操作完成.想要BIO处理多个客户端请求,就要使用多线程来处理,为每个客户端都创建一个的线程来单独处理.

NIO原理

  1. NIO原理
    ①NIO的事件处理流程
    Acceptor注册Selector, 监听accept
    当客户端连接后,触发accept事件
    服务器构建对应的Channel,并在其上注册Selector,监听读写事件.
    当发生读写事件后,进行相应的读写处理
    ②NIO是基于事件驱动思想来完成,主要想解决的是BIO的大并发问题,如果想要同时处理多个客户端请求或客户端同时和多个服务器进行通讯,就必须使用多线程处理,即每一个客户端都分配一个线程来单独处理,虽然可以达到要求,但是每创建一个线程,就要分配一定的内存空间,如果客户端请求过多,可能会使服务端程序瘫痪等.N
    ③NIO中当selector 有流可读或者可写入socket的时候,操作系统会相应的通知应用程序进行处理,应用再将流读取到缓冲区或写入操作系统,就不是一个连接对应一个处理线程了,而是有效的请求,对应一个线程,当连接后没有数据时,就没有工作线程来处理.

AIO

  1. AIO 的原理
    与NIO不同,当进行读写操作的时候,只需要调用API的reade或read方法即可.这两种方法均为异步的,对于读操作而言,当有流可读的时候操作系统会将可读的流传入read方法的缓冲区,并通知应用程序.对于写操作而言,当操作系统将writer方法传递的流写入完毕的时候,操作系统主动通知应用程序.

反射

什么是反射机制

  1. 什么是反射机制
    JAVA反射机制是在程序运行过程中,对于任意一个类或对象,都能够知道这个类或对象的所有属性和方法,这种动态获取信息以及动态调用对象方法的功能叫做反射机制.
    静态编译:在编译时确定类型,绑定对象
    动态编译:在运行时确定类型,绑定对象

反射机制的优缺点

  1. 反射机制的优缺点
    ①优点: 运行期类型的判断,动态的加载类,提高代码的灵活性.
    ②缺点: 性能瓶颈:反射相当于一系列解释操作,通知JVM要做的事情,性能比直接的java代码要慢很多.
    ③反射慢的原因: 反射调用过程中会产生大量的临时对象,这些对象会占用内存,可能会导致频繁gc(垃圾回收),从而影响性能.反射调用方法的时候回去方法数组中遍历查找,并且检查可见性等操作会比较耗时.反射达到一定次数后会动态编写字节码并加载到内存中,这个字节码没有经过编译器的优化,也不能被JIT优化.反射一般会涉及到自动装箱/拆箱和类型转换,都会带来一定的资源开销.

反射的应用场景

  1. 反射的应用场景
    反射是框架的灵魂,平时的开发过程一般不会直接用到反射,但实际上有很多的设计,开发,都与反射有关.
    例如:
    ①:JDBC连接数据库的时候,使用Class.forName()通过反射来加载数据库中的驱动程序
    ②:Spring中最典型的xml配置文件.用他来装载Bean,首先,将所有的XML或者Properties文件加载进内存,在java类里面解析xml和peoperties文件的内容,得到相应的实体类的字节码字符串以及相关的属性信息.使用反射机制根据字符串获取某个类的Class实例,最后动态的配置实例的属性.

网络编程

TCP/IP的五层体系结构

  1. TCP/IP的五层体系结构

应用层

应用层的任务是通过应用进程间的交互来完成特定的网络应用,定义的是应用间进程通信和交互的规则.
应用层的协议有很多,如:DNS 域名系统, HTTP协议, SMTP 电子邮件协议等

运输层

运输层的主要任务是负责向两台主机进程之间的通信提供通用的数据传输服务,应用进程利用该服务传送应用层报文.运输层主要使用的协议有:传输控制协议TCP, 用户数据协议UDP.
二者的区别:
①UDP是 无连接的不可靠传输,不使用流量控制和拥塞控制,支持一对一,一对多,多对一,多对多交互通信.传输方式是面向报文传输,首部开销小,仅占8个字节,适用于实时应用,如:IP电话,视频会议,直播等
②TCP是面向连接的可靠传输,且只能一对一通信,传输的方式是面向报文传输,首部最少20字节最大60字节,适用于要求可靠传输的应用,如:文件的传输
每个应用层协议都会使用到这两个传输协议之一,如:
①运行在TCP上的协议:
HTTP超文本传输协议,主要用于普通浏览器
HTTPS安全超文本传输协议,HTTP协议的安全版本
FTP文件传输协议,用于文件传输
POP3邮局协议,收邮件用
SMTP简单邮件传输协议,用来发送电子邮件.
TELNET网络电传,通过一个终端登录到网络
SSH 用于代替安全性差的TELNET协议,用于加密安全登录用
②运行在UDP上的协议
BOOTP 启动协议,应用于无盘设备
NTP网络时间协议,用于网络同步
DHCP动态主机配置协议,动态配置IP地址
③运行在TCP和UDP上的协议
DNS域名服务,用于完整地址查找,邮件转发等工作.

网络层

网络层的任务就是选择合适的网间路由和交换节点,确保计算机通信的数据及时传送,在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送.网络层使用的是IP协议,因此分组也叫IP数据报,简称数据报.
互联网是由大量的异构网络通过路由器相互连接起来的.互联网使用的网络层协议是无连接的网际协议和许多路由器选择协议,因此互联网的网络层也叫做网际层或IP层.

数据链路层

数据链路层通常简称链路层.两台主机之间的数据传输,总是在一段段的链路上传送的,这就需要使用专门的链路层的协议.
在两个相邻节点之间传送数据时,数据链路层将网络层传下来的IP数据报组装成帧,在两个相邻节点的链路上传送帧.每一帧包括数据和必要的控制信息.
在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始到哪个比特结束.
发送端在层与层之间传输数据时,每经过一层会被打上一个该层所属的首部信息,反之接收端在层与层之间传输数据时,每经过一层会把对应的首部信息去除.

物理层

在物理层上所传送的数据单位是比特.其作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传送介质和物理层设备的差异.使他上面的数据链路层不必考虑网络的具体介质是什么.

四层协议、五层协议、七层协议的区别

  1. 四层协议、五层协议、七层协议的区别
    ①OSI的七层协议体系结构的概念清楚、理论也比较完整但是复杂不实用,其主要包括应用层、表示层、会话层、运输层、网络层、数据链路层、物理层。
    ②TCP/IP四层协议体系结构最实用,从实质上看,TCP/IP只有最上面的三层,最下面的网络接口层没有什么具体内容,其主要包括应用层、运输层、网际层、网络接口层。
    ③五层协议体系结构,综合了OSI和TCP/IP的优点,主要是供学习计算机网络的原理时使用,其主要包括应用层、运输层、网络层、数据链路层、物理层。

三次握手和四次挥手

  1. 三次握手和四次挥手
    ①TCP是一种面相连接的可靠的基于字节流的传输层通信协议,它可以处理IP层或以下的层的丢包、重复、错误问题。发送数据前彼此建立一条连接(客户端和服务端用来存放关于对方的信息,如IP、端口号等,放到TCP头部)
    ②一个TCP连接通常分为三个阶段:连接、数据传输、退出。通过三次握手建立连接,四次挥手关闭连接。当一个连接被建立或者被终止的时候交换的报文段只包含TCP头部而没有数据。
    ③三次握手的理解:相当于是A给B发邮件,当B收到的时候,B知道了A的发件能力是可以的。然后B给A发邮件,A收到的时候A就知道了B的收邮件和发邮件的能力都是可以的,以为他收到了自己发的还给自己回了一个,但是这时候B还不知道A的收件能力,所以A再给B发一个,当B收到的时候两者的收发邮件的能力都清楚了。之后就可以随便来往了。所以为三次握手。
    ④三次握手的具体含义:第一次握手客户端向服务器发起请求,先生成一个其实序列号ISN,假设为100,则客户端向服务端发送的报文段包含了 SYN(表示发起新连接)标志位 =1,序列号seq=100.第二次握手服务端收到了客户端发来的报文后,发现SYN等于1就知道要建立一个新的连接请求。他会先将客户端发出的起始序列号seq=100存起来,并生成一个属于服务端自己的起始序列号,假设为200,然后回复给客户端一段报文,报文的内容包含了SYN(表示发起新连接)标志位 =1,ACK(当ACK为1的时候才表示确认序号有效,即让对方知道他收到了)=1,seq=200,确认号ack=101(客户端发来的序列号+1),第三次握手客户端收到了服务的回复的ACK=1并知道ack=101,就知道服务端收到了自己之前发的报文,同时收到了SYN=1,就说明服务的同意了这次请求,于是存下服务端发来的序列号200,并再给服务端发送报文,报文包含 ACK = 1, ack = 301, seq=101(第一次发的时候是100,所以加一接着发),当服务端知道ACK=1并且ack=301,就知道客户端收到了自己的报文,然后二者就建立了连接。
    ⑤四次挥手理解:A和B想要分开,A先和B断开连接,B收到A的请求后,同意了A断开连接并和A说可以,但是B在A断开连接之前,给A发的有数据,所以B和A说再等等,等我发的数据到了在断开,等数据到后,B再次和A说,断开吧,最后A给B再次回复断开吧,就结束了连接
    ⑥四次挥手具体含义:第一次挥手当客户端的数据都传输完成后,客户端向服务端发出连接释放报文(数据没发完时也可以停止发送数据),释放连接报文包含FIN(断开连接的请求)标志位=1、序列号seq=(100+1+连接后客户端发送的字节,其中的1是建立连接时占的一个序列号)。需要注意的是客户端发出FIN报文段后只是不能发数据了,但是还可以正常收数据;另外FIN报文段即使不携带数据也要占据一个序列号。第二次挥手:服务端收到客户端发的FIN报文后给客户端回复确认报文,确认报文包含ACK=1、确认号ack=(客户端FIN报文序列号seq+1)、序列号seq=(200+连接后服务的回应的字节)。此时服务端处于关闭等待状态,而不是立马给客户端发FIN报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。第三次挥手∶服务端将最后数据发送完毕后就向客户端发出连接释放报文,报文包含FIN和ACK标志位(FIN=1,ACK=1)、确认号和第二次挥手一样ack、序列号seq=(上次的seq+剩余的数据)。
    第四次挥手:客户端收到服务端发的FIN报文后,向服务端发出确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=2351、序列号seq=1102。注意客户端发出确认报文后不是立马释放TCP连接,而是要经过2MSL(最长报文段寿命的2倍时长)后才释放TCP连接。而服务端一旦收到客户端发出的确认报文就会立马释放TCP连接,所以服务端结束TCP连接的时间要比客户端早一些。

DNS解析过程

  1. DNS解析过程
    ①浏览器会先查找缓存中有没有该域名解析过的IP地址,有了就直接结束
    ②如果①中找不到,操作系统会从其本身去做域名解析,在Windows中的host文件可以设置特定的域名IP映射,文件位置为:C\Windows\System32\drivers\etc\hosts
    ③如果①②都找不到,就需要向LDNS发起域名解析,可通过ipconfig/all查看,LDNS是本地域名解析服务器,一般都缓存了大部分的域名解析结果,当然缓存时间也受域名失效的时间控制,大部分解析工作到主力就差不多结束了,LDNS负责了大部分的解析工作。
    ④如果还没有找到就向RDNS(根域名解析服务器)发起域名解析请求
    ⑤LDNS向根域名服务器发起请求,根域名服务器返回的是所查询的通用顶级域名(GTLD)地址,常见的顶级域名有.com,.org,.edu
    ⑥本地域名服务器gTLD发起解析域名请求
    ⑦gTLD服务器接收请求并返回注册的域名服务器(Name Server服务器,名称服务器),当gTLD服务器接收到本地域名服务器发起的请求后,并根据需要解析的域名,找到该域名对应的Name Server服务器,通常情况下,这个Name Server服务器就是你注册的域名服务器,那么你注册的域名的服务上的服务器将承担起域名解析的任务
    ⑧本地域名服务器向Name Server服务器发起域名解析请求
    ⑨Name Server服务器会查询存储的域名和IP的映射关系表,然后返回该域名对应的ip和TTL给本地域名服务器,本地域名服务器进行缓存这个域名和ip的对应关系,缓存时间由TTL决定。
    ⑩本地域名服务器返回查询域名对应的ip给用户(浏览器),浏览器进行缓存,缓存时间由TTL决定。

GET和POST的区别

  1. GET和POST的区别
    ①GET是不安全的,在传输过程中数据会放在URL中.POST的所有操作对用户来说都是不可见的.但是也可以在GET请求上加request body, 给post请求加上URL参数
    ②GET请求的URL数据最多只能2048个字节,该限制是浏览器或者服务器添加的,并不是http对URL的长度进行的限制,而该目的是为了防止有人恶意发送请求.POST则没有大小限制.
    ③GET限制form表单的数据集必须为ASCII字符,Post支持整个ISO10646字符集
    ④GET执行效率比Post快.GET是form提交的默认方式
    ⑤GET产生一个TCP数据包,POST产生两个TCP数据包,对于GET浏览器会把HTTP HEADER 和 DATA一起发送出去,直接响应200,对于POST浏览器先发送HEADER,服务器响应100后再发送Data,服务器响应200.

Session、Cookie、Token的区别

  1. Session、Cookie、Token的区别
    ①Cookie:保存在用户浏览器上的小文件(Key-Value的格式),包含用户相关的信息。客户端向服务器发起请求的时候,如果服务器需要记录该用户状态,就使用response给客户端发一个Cookie.客户端的浏览器把Cookie保存起来,下次浏览器再请求该网站的时候,就把Cookei一起发给服务器,用它来识别用户的身份。
    ②Session:session是cookie的实现,是服务端的对象。session是浏览器和服务器会话过程中,服务器分配的一块存储空间。服务器默认为浏览器在cookie中设置sessionid,服务器根据sessionid获取会话中存储的信息,然后确认会话的身份信息。
    ③Token:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码是否正确,并做出相应提示,Token因此产生。
    Token是服务端生成的一串字符串,以客户端进行请求的一个令牌,第一次登录的时候,服务器生产一个Token并返回给客户端,客户端带上Token即可请求数据,不再需要账号密码。Token是为了减轻服务器压力,减少频繁的查询数据库,使服务器更加健壮。
    ④cookie和session的区别
    cookie放在客户端,安全性差。session放在服务器上,安全性相对较高
    单个的cookie存的数据不能超过4K,在浏览器上也会限制每个站点最多保存的cookie数量,session没有限制。
    session一定时间内保存在服务器上,访问增多的时候占用服务器性能,而cookie不会。
    ⑤session和token的区别
    session机制存在服务器压力增大,CSRF跨站伪造请求,扩展性不强等问题
    session存储在服务器端,token存在客户端
    token提供认证和授权功能,作为身份认证的话,安全性高于session
    token适用于前后端分离,session是客户端服务端在同一服务器上。

Socket

33.Socket
①什么是Socket:Socket被翻译为"套接字",是计算机之间通信的一种约定,网络上的两个程序通过一个双向的链路连接实现数据交换,这个双向链路的一端成为一个socket,一个socket由一个IP地址和一个端口确定其唯一性.Socket偏向于底层,一般很少直接使用socket来编程,框架底层使用socket较多.
②Socket位于哪一层:Socket是应用层和TCP/IP协议族通信的中间软件抽象层,是一组接口.在设计模式中Socket是一个外观模式,将复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说一组接口就是全部.
③通讯过程:基于TCP,服务器先初始化Socket,然后与端口绑定,对端口进行监听,调用accept阻塞,等待客户端连接,如果有客户端初始化一个socket,然后连接服务器,连接成功的话,客户端发送数据请求,服务端接收请求并处理请求,然后将响应数据发给客户端,客户端读取数据,之后关闭连接结束交互.

HTTP和HTTPS

  1. HTTP和HTTPS
    ①HTTPS的工作原理:❶客户端向服务端发起一个HTTPS请求,端口号为443,❷服务端将配置好的公钥证书返回给客户端.❸客户端验证公钥证书是否有效❹客户端使用伪随机数生成器生成加密使用的会话密钥,使用证书的公钥加密这个会话秘钥发送给服务端.❺服务端使用自己的私钥解密这个消息,得到该会话秘钥(两者现在都有会话秘钥),❻服务端使用会话秘钥加密明文内容发送给客户端,❼客户端使用会话秘钥解密,并得到明文内容❽客户端再发起请求,加密明文并发给服务端,…一直重复该过程.
    ②一次完整的HTTP请求步骤:❶根据域名和DNS来解析到服务器的IP地址.❷通过ARP协议获得IP地址对应的物理机器的MAC地址❸浏览器对服务器发起TCP连接❹建立TCP连接后发起HTTP请求报文❺服务器响应 HTTP 请求,将响应报文返回给浏览器❻短连接的情况下通过TCP的四次挥手断开连接,长连接的话,就当一段时间没有再访问服务器就断开连接❼浏览器得到响应信息中的HTML代码,并获取js,css,图片,视频等资源❽浏览器对页面进行渲染并呈现给用户

HTTP状态码

  1. HTTP状态码
    ①1xx:信息状态码,服务端收到请求后需要请求端继续操作。
    ②2xx:成功状态码,操作被成功接收并处理
    ③3xx:重定向状态码, 需要进一步操作以完成请求
    ④4xx:客户端错误状态码,请求包含语法错误或无法完成请求
    ⑤5xx:服务器错误状态码,服务器在请求的过程中发生了错误
    ⑥常见的状态码:
    200, 请求成功,一般用于POST和GET请求
    204,服务器成功处理但未返回内容,在未刷新网页的情况下,确保浏览器继续显示当前网络。
    206,对资源的部分请求,服务器成功处理了部分GET请求,响应报文中包含由Content-Range指定范围的实体内容。
    301,永久性重定向,请求的资源被永久的移动到新的URI,返回信息会包括新的URI,浏览器会 自动定向到新的URI,之后的请求也会如此
    302,临时重定向,与301类似,只不过资源是临时的,后面还要使用原有的URI
    303,查看其他地址,与302类似,使用GET请求查看
    304,307…
    400, 客户端请求报文中存在语法错误,服务器无法理解
    401,请求要求用户的身份认证,通过HTTP等的认证信息,若之前已进行过一次请求,则表示用户认证失败
    402, 保留,将来使用、
    403,服务器理解客户端的请求,但是拒绝执行此请求
    404,服务器无法根据客户端的请求来找到该资源
    500,服务器内部错误,一般是代码出BUG了
    501,服务器不支持请求的功能,无法完成请求
    503,由于超载或系统维护,服务器暂时无法处理客户端的请求

常用API

装箱与拆箱

  1. 装箱与拆箱
    ①装箱:就是讲基本数据类型,使用它们对应的引用数据类型给包装起来
    ②拆箱:将包装类型转化为基本数据类型。

字符型常量和字符串常量

  1. 字符型常量和字符串常量
    ①字符常量是单引号引起的一个字符,字符串常量是引号引起的若干个字符
    ②字符常量相当于一个整型值(ASCII值),可以参加表达式运算,字符串常量代表一个地址
    ③字符常量只占2个字节,字符串常量占N个

String,字符串常量池

  1. String,字符串常量池
    ①创建机理:以为String在Java中使用过于频繁,为了提高内存的使用率,避免开辟多块空间存储相同的字符串,所以引入了字符串常量池(字符串常量池在堆内存中)
    ②运行机制:在创建字符串的时候JVM会首先检查字符串常量池,如果该字符串存在于字符串常量池中,则返回他的引用,如果不存在就实例化一个字符串放到常量池中并返回其引用。
    ③String为什么设计为final:final修饰的String类,代表了String不能被继承。String类一旦在常量池中创建,无法修改的,在后面拼接字符的话,会生成一个新的地址并存储这个新的字符串。提高了线程的安全性,多线程下对资源进行写操作是有风险的,不可变的对象不能被写。因为字符串是不可变的,所以创建的时候Hash Code就被缓存了,不需要重新计算。
    注:String的底层是char类型的数组

String,String Buffer, StringBuilder的区别

  1. String,String Buffer, StringBuilder的区别
    ①可变性:String类中使用的是字符串数组保存字符串,使用private final 来修饰,所以String对象是不可变的。StringBuilder和StringBuffer都继承于AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组来保存字符串,但是这两种对象都是可变的。
    ②线程安全:String中的对象是不可变的,也就可以理解为常量,线程安全。而另外两个中,StringBuffer对方法加了同步锁,是线程安全的。StringBuilder并没有对方法进行加同步锁,是非线程安全的。
    ③性能:String对象每当改变的时候,都会生成一个新的对象,然后指针指向这个新的对象。StringBuffer和String Builder是对对象本身进行操作,不是生成新的对象。且String Builder性能比String Buffer高一点但是有多线程不安全的风险
    ④使用场景:如果字符串内容不经常发生变化就优先使用String类,单线程情况下,如果频繁使用字符串的操作,则建议使用String Builder,在多线程情况下,如果频繁地使用字符串则建议使用StringBuffer.

异常

什么是异常

  1. 什么是异常
    java异常是java提供的一种识别及响应错误的一致性机制。jav异常处理机制可以使程序中异常处理代码和正常代码分离,保证程序代码更优雅,提高健壮性。如果正确的使用异常,可以清晰的回答 ,what, where,why三个问题。即异常类型回答了 ’什么‘被抛出,异常堆栈跟踪回答了‘在哪’抛出,异常信息回答了‘为什么’抛出。

Error 和 Exception的区别

  1. Error 和 Exception的区别
    ①Error是程序正常运行中不大可能出现的错误,通常为虚拟机相关的错误,如:系统崩溃、内存不足、堆栈溢出等。编译器不会对这类错误进行检测,应用程序也不会对此进行捕捉,一旦发生错误,程序会被终止,仅靠程序本身无法恢复。
    ②Exception是是程序正常运行中可以预料的意外情况,遇到这种情况后应对其进行处理使程序可以继续正常运行。

    运行异常和编译异常

  2. 运行异常和编译异常
    ①运行异常
    RuntimeException以及其子类
    该类不会被java编译器检查,即如果不主动捕获或者抛出该异常,还是可以编译通过的.运行的异吊

    定义: RuntimeException类及其子类。
    特点: Java编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既"没有通过throws声明抛出它",也"没有用try-catch语句捕获它",还是会编译通过。比如
    NullPointerException空指针异常ArrayIndexOutBoundException数组下标越界异常ClassCastException类型转换异常
    ArithmeticExecption算术异常等。
    此类异常属于非受检异常,在程序中可以选择捕获,抛出,也可以不处理,此类异常一般是由程序逻辑错误引起的,需要通过修改代码来进行避免。
    ②编译异常
    定义:Exception中除了运行异常以及其子类的所有异常
    特点:会被java编译器检测到,该异常需要抛出或捕获处理,不然就不能通过编译,如ClassNotFoundException找不到指定类异常,IOException IO流异常。通常不会自定义该异常,而是直接使用系统提供的异常类。

受检异常和非受检异常

  1. 受检异常和非受检异常
    ①受检异常:
    编译器要求必须处理的异常,当编译器经检查到该类的异常的时候,要么捕获要么抛出,不然通过不了编译,该类异常包括Exception中除了运行时异常以及其子类之外的所有异常
    ②:非受检异常
    编译器不会进行检查也不要求必须处理,不捕获和抛出也没有问题,也可以正常通过编译。该类异常包括了运行时异常以及其子类和错误(ERROR)。

异常处理的最佳实践

①在finally中清理资源
②对异常进行文档说明
③使用描述性消息抛出异常
④尽量不要捕获Exception这样的通用异常类,捕获具体化
⑤不要捕捉Throwable类
⑥不要忽略异常也不要生吞异常
⑦包装异常时不要抛弃原始异常
⑧尽量使用标准异常
⑨异常会影响性能

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值