Java基础相关面试知识

Java基础

Java八大基本数据类型

  • 四整形:byte(1字节=8位)short(2字)、int(4字)、long(8字)
  • 两浮点:float(4字)、double(8字)
  • 一字符:char(2字)
  • 一布尔:boolean(1位)

什么是自动装箱拆箱 

        装箱就是自动将基本数据类型转换为包装器类型,拆箱则相反。

static 和 final 关键字 

        static 可以用于修饰类的成员变量和方法,被static 所修饰的属于类的静态资源,被所有类实例所共享,通过类名可以直接调用。 

  1. 静态变量在内存中只有一个副本,它仅在类初次加载时会被初始化,而非静态变量为对象所拥有,在创建对象的时候被初始化。
  2. static 也用于静态代码块(只会在类加载的时候执行一次)、静态内部类(无需外部类实例便可创建)和静态导包(导入类中所有的静态资源省去类名直接调用)。

        final

  1. 基本数据类型用final 修饰属于常量不能修改;对象引用被final 修饰,则引用变量指向地址不能修改,但对象本身可以修改。
  2. final 修饰的方法不能被子类重写
  3. final 修饰的不能被继承

String为什么不可变

         从String的源码可以看出,String对象在内部就是一个个字符,存储在一个value数组中,而这个数组被final 所修饰,且String对象没有对外提供修改内部状态的方法,所以String是不可变的。

        那为什么设计成不可变?

  1. 不可变既线程安全,可以被多个线程所共享;
  2. 不可变既hash值固定,使用到hash值的场景(如作为Map的Key)无需重复计算;
  3. 字符串常量池优化,String对象创建后会缓存到字符串常量池中,下次需要创建同样的对象时可以直接返回缓存的引用。

Java类的实例化顺序

        1静态属性,静态代码块;2普通属性,普通代码块;3构造方法;

 接口和抽象类的区别

        语法层面

  1. 接口的方法中只能是抽象方法,而抽象类可以有方法实现;
  2. 接口中的成员变量只能是public static final类型,而抽象类中的可以是各种类型;
  3. 接口中不能含有静态代码块以及静态方法,而抽象类可以;
  4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口;

        设计层面

  1. 抽象类是对整个类整体进行抽象,包括属性(如颜色)和行为(跑),但接口只是对类的行为进行抽象;继承抽象类是一种"属不属于某一类"的关系,而接口实现则是 "有没有某一行为"的关系;
  2. 继承抽象类的是具有相似特点的类,而实现接口的却可以不同的类;

常见的Exception有哪些

  • 类型转换异常 ClassCastException
  • 数组越界异常 IndexOutOfBoundsException
  • 空指针 NullPointerException
  • 数字格式化异常 NumberFormatException 等

(Error和Exception的区别:Error为JVM无法解决的严重问题如堆栈溢出,Exception为其它因编程错误或外在因素导致的一般问题,可以通过代码进行解决。) 

什么是反射

        在运行状态中,对于任意一个类,能够知道这个类的所有属性和方法。并且对于任意一个对象,能够调用它的任意一个方法。这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。

        反射的应用场景:

  1. JDBC连接数据库时通过反射加载数据库的驱动程序
  2. Eclispe、IDEA等开发工具通过反射解析对象,动态提示对象的属性和方法
  3. Web服务器中利用反射调用Sevlet的service方法
  4. JDK动态代理底层依赖反射实现

什么是跨域 

        跨域是指从一个域名的网页去请求另一个域名的资源。由于有同源策略的关系,一般是不允许直接访问的。比如在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域问题。

什么是同源策略

        同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。同源策略限制了一些行为,如Cookie无法读取、AJAX请求不能发送等。

为什么要有同源策略

        为了安全,比如个人信息或账号密码存放在Cookie中,访问钓鱼网站时便会被盗取或者直接模拟用户请求修改后台数据。

跨域如何解决(A to B)

  1. CORS 跨域资源共享
           CORS 是浏览器制定的一个规范,服务端通过设置一些请求头来限制可以访问的外部域。
  2. @CrossOrigin 注解
            SpringMVC 可以通过给Controller类或接口方法加该注解就可以实现跨域处理。
  3. Nginx 反向代理
            同源策略是浏览器的安全策略,服务器端请求HTTP接口只是使用HTTP协议,不会执行JS脚本也就不存在跨越问题。所以可以通过Nginx 配置一个代理服务器域名与A一致,代理请求域名B实现跨域处理。

        (同时可以修改cookie中的信息,方便当前域cookie写入,实现跨域登录)

server {
    listen       81;
    server_name  A;
    location / {
        proxy_pass   http://B:8080;  #反向代理
        proxy_cookie_domain B A; #修改cookie里域名
        index  index.html index.htm;
        
        add_header Access-Control-Allow-Origin http://A;
    }
}

网络相关

TCP和UDP的区别

        TCP是面向字节流、可靠有序的、面向连接的传输协议,只能一对一通信(传输速度较慢,适用于可靠传输如文件传输)。而UDP是面向报文、不可靠无序的、无需连接的传输协议,支持一对多和多对多通信(传输速度较快,适用于实时传输如视频音频)。

TCP为什么可靠

        TCP协议的可靠是指传输的数据可以无差错、不丢失、不重复的按序给到对方。因此TCP通过“三次握手和四次挥手”、“确认应答和超时重发”、“滑动窗口”、“拥塞控制”等机制来保证可靠性。

三次握手(客 to 服,服 to 客,客 to 服)
  1. 第一次:客户端将数据包(标志位SYN = 1,随机值序列号seq = x)发送给服务端,客户端 进入syn_sent 状态,等待服务端确认。
  2. 第二次:服务端收到数据包后由标志位SYN = 1 知道客户端请求建立连接,服务端发送一个数据包(标志位SYNACK = 1ack = x+1,随机值序列号seq = y)给客户端以确认连接请求,服务端进入syn_rcvd 状态。
  3. 第三次:客户端收到确认后检查,正确则发送一个数据包(标志位ACK = 1seq = x+1ack = y+1)给服务端,服务端进行检查如果正确则连接建立成功,客户端和服务端进入established 状态,可以开始传输数据。

       (SYN:建立连接标识;ACK:收到请求标识;seq:自己的发送数据;ack:收到的对方数据;seq和ack用于数据确认)

四次挥手(客 to 服,[ 服 to 客,服 to 客 ],客 to 服)
  1. 第一次:客户端发送一个FIN,关闭客户端到服务端的数据传送,客户端进入fin_wait_1状态。
  2. 第二次:服务端收到FIN后,发送一个ACK给客户端,服务端进入Close_wait状态。此时连接处于半关闭状态,即客户端已经没有要发送的数据了,但服务端若发送数据,客户端仍要接收。
  3. 第三次:服务端发送一个FIN,关闭服务端到客户端的数据传送,服务端进入Last_ack状态。
  4. 第四次:客户端收到FIN后,客户端进入Time_wait状态,接着发送一个ACK给服务端,确认后,服务端进入Closed状态,完全关闭连接。
 确认应答和超时重发

        TCP每次发送数据时,会给每个数据包分配一个序列号,每发送一个数据包都会等待接收端的ACK(确认应答)回复,如果一定时间没收到ACK回复,发送端就会自动重发。

序列号的作用不仅仅是应答,有了序列号能够将接收到的数据根据序列号排序,并且可以丢弃重复序列号的数据。)

滑动窗口

        根据确认应答机制,每个数据包发送成功需要一个来回并且是串行化的,一个个发送效率太低,一次性全发占用流量大且失败重发的话也浪费流量,所以通过滑动窗口机制实现部分发送。(批量发送同时要保证有序接收就需要预留位置批量接收,所以发送端和接收端都有滑动窗口)

        对于发送端的滑动窗口,有四部分:

  1. 未发送,同时接收端也未准备接收的数据
  2. 未发送但已经告知接收方的数据(既已缓存在窗口中)
  3. 已发送但没有被确认(属于窗口内的数据)
  4. 已发送并已经被确认的数据(离开窗口)

         对于接收端的滑动窗口,也有四部分:

  1. 有空间,还没有被接收的数据
  2. 已经接收,但还没有回复ACK的数据(既已缓存在窗口中)
  3. 已确认回复,但还没有被上层应用程序接收的数据(属于窗口内的数据)
  4. 已被上层接收的数据(离开窗口)

        总的来说滑动窗口按窗口内外分为左边界、已发送未确认、窗口缓存区、右边界四部分数据,“滑动”指的是数据不断进入和离开窗口,而窗口的大小会根据接收端返回的情况动态调整。

(注意:TCP不是每收到一个数据块返回一个ACK,比如发送了1、2、3三个数据,2和3先收到了,会预留1个位置然后等1收到了再返回一个ACK 3?代表三个数据都收到了)

拥塞控制

        根据超时重发机制,如果发送端迟迟未收到ACK应答会认为数据丢包进行重新发送数据。而实际情况可能是太多主机使用网络通信造成网络拥塞了,所以数据包或ACK堵在途中未到达,这个时候进行重新发送数据不仅浪费资源还会让网络变得更加拥塞,因此需要进行拥塞控制

        拥塞控制算法主要有:慢启动、拥塞避免、快重传和快恢复;

         

        慢启动和拥塞避免

        为了探测网络的拥塞情况,可以采取从1开始线性递增或指数翻倍发送数的两种方式,网络情况肯定会存在一个瓶颈值,两种方式对于到达瓶颈值都不会,要么太慢要么太快,所以结合两者采取开始先指数增长,到达一个阈值ssthresh后再线性增长的方式。

        指数增长阶段称之为慢启动,线性增长阶段称之为拥塞避免

        快重传

        快重传要求接收端在收到一个失序的报文段后就立即发出重复确认,而不要等到发送数据时捎带确认,当发送端连续收到三个重复确认就立即重传对方尚未收到的报文段,而不必继续等待设置的重传倒计时。

        快恢复

        快恢复是与快重传配合使用的算法,发送端连续收到三个重复确认时把ssthresh阈值减半(预防拥塞),然后再次执行拥塞避免算法来增大发送数;

(注意:慢启动算法只在TCP建立连接和网络超时后重连时使用)

 为什么需要三次握手而不是两次

       在TCP可靠传输中序列号起到关键作用,三次握手即是通信双方相互告知序列号起始值,且确认对方成功收到了序列号证明网络没有问题。

为什么TCP挥手需要4次,三次行不行

        首先TCP是全双工(即双方都可以发送数据且可以同时发送数据)通信协议,A到B和B到A属于两条通道,A端发出FIN报文后B端返回了确认就不会再接收A端的数据了,但此时B端可能还有数据没有传输完成,还是需要A端接收数据的,所以只有当B端确认完毕后才发出FIN报文,并确认A端接收到时才真正断开连接。

        即如果服务端收到FIN报文时确认无数据要发送了,就可以同时把ACK和FIN合并返回给发送端变成了“三次挥手”。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值