java后端研发经典面试题总结六

本文深入探讨了TCP/IP协议中的滑动窗口机制及其在流量控制中的应用,并详细介绍了HTTP协议的不同版本及其工作原理。此外,还讲解了多种设计模式,包括单例模式的不同实现方式及观察者模式的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 滑动窗口是什么设计的?

    窗口:是一段可以被发送者发送的字节序列,其连续的范围称为“窗口”

    滑动:这段“允许发送的范围”是随着发送的过程而不断变换的,表现的形式就是“按照顺序滑动”

    流量控制:

    (1)TCP利用滑动窗口实现流量的控制机制

    (2)如何考虑流量控制中的传输效率

    流量控制,接受方传递信息给发送方,使其发送数据不要太快,是一种端到端的控制,主要的方式是返回的ack中会包含自己的接受的窗口的大小,发送方收到该窗口的大小时会控制自己的数据发送。

    传递效率:单个发送字节单个确认,和窗口有一个空余即通知发送方发送一个字节,会增加网络中许多不必要的报文,因为会为一个字节数据添加40个字节的头部。

    TCP/UDP的区别

    1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。

    2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。
    3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
    UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
    4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
    5、TCP首部开销20字节;UDP的首部开销小,只有8个字节

    6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠

    TCP报文结构

    紧急比特URG:URG=1,注解该报文应该尽快送达,而不需要按照原来的的队列次序依次送达

    确认比特ACK:只有当ACK=1,确认序号字段才有意义

    急迫比特PSH:当PSH=1时,注解恳求远地TCP将本报文段立即传送给应用层

    复位比特RST:当注解呈现严重错误时,必须开释连接,进行重新的传输连接

    同步比特SYN:当SYN=1而ACK=0时,这是一个连接请求报文段,若对方赞成连接请求会将SYN=1而且ACK=1

    终止比特FIN:当FIN=1,注解字符串已经发送完毕,并请求开释传输连接。

    HTTP的报文结构(请求报文+响应报文)

    HTTP请求报文:(1)请求行+(2)请求头部+(3)请求正文

    (1)请求行:请求方法+URL+协议版本

    请求方法:常用GET、POST

    协议版本:HTTP/主版本号.次版本号 常用HTTP/1.0和HTTP/1.1

    (2)为请求报文添加的一些附加的信息,“名/值”组成,并且是每行一对 用冒号进行分割

    在请求头部存在空行,表示请求头部的结束,接下来是请求正文!

    区别get和post方式

    对于get方式没有请求的正文,对于post方式有请求的正文。

    HTTP响应的报文格式:

    (1)状态行+(2)响应头部+(3)响应正文

    (1)状态行:协议版本+状态码+状态码描述

    (2)响应头部:也是由键值对所组成

    (3)响应正文,由服务器端接受数据

    HTTP状态码的含义

    http request的几种类型(8种)

    (1)OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送’*'的请求来测试服务器的功能性。
    (2)HEAD:向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。
    (3)GET:向特定的资源发出请求。
    (4)POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建和/或已有资源的修改。
    (5)PUT:向指定资源位置上传其最新内容。
    (6)DELETE:请求服务器删除Request-URI所标识的资源。
    (7)TRACE:回显服务器收到的请求,主要用于测试或诊断。

    (8)CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

    GET方式和POST方式对比:

    GET方式:请求数据放在HTTP包头;使用明文传送,不安全;长度较小,一般为1024B;应用的场景为查询数据;如果传送的是英文数字或者是数字,直接发送,如果传送的是中文字符或则是其他的字符,则会进行BASE64编码

    POST方式:请求数据放在HTTP正文;可明文或者密文传送,较为安全;长度一般没有限制;应用在修改数据上。

    http1.0 和 http1.1的区别

    (1)HTTP1.0 规定浏览与服务器只是保持短暂的连接,浏览器每次请求都需要和服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不去跟踪每个客户也不去记录每个客户过去的请求。HTTP1.0 不支持HOST请求字段

    (2)HTTP1.1支持久连接,在一个TCP上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟;

    允许客户端不用等待上一次请求的返回结果,就可以 去发送下一个请求,但是服务器端必须按照接受的客户端请求的先后顺序依次会送响应的结果,这样客户端才能够区分出每次请求的响应的内容。

    HTTP1.0 支持HOST请求字段,这样就可以使用一个IP地址和端口号,在此基础上使用不同的主机名创建多个虚拟的WEB站点;

    HTTP1.1 提供了与身份认证、状态管理和cache缓存等机制

    http怎么去处理长连接

    http1.1 默认支持长连接,即一次tcp连接,允许发送多个http请求。

    当web服务器看到keep-alive值时,会建立长连接。

    电脑上访问一个网页的整个过程是怎样的?DNS、HTTP、TCP、OSPF、IP、ARP

    步骤1:当访问www.baidu.com时,会先从本地的host文件中获取该域名对应的IP地址,如果找不到就会用DNS协议来获取IP,在该DNS协议中,计算机会由本地的DNS服务器来解析该域名,最终找到对应的IP地址。

    步骤2:接下来是使用TCP协议,建立TCP连接,在建立连接之前需要,为了将给服务器的消息带给服务器,则需要OSPFIPARP协议的支持,IP告诉该消息从哪里出发,去向那里;消息的传送会经过一个个的路由器,OSPF会利用路由算法找出最佳的通往目的地址的路径;ARP负责找到下一个节点的地址,ARP协议使用的MAC地址,整个的发送的过程涉及到每一个节点的MAP地址。

    步骤3:通过步骤2的解析IP,现在可以和服务器建立TCP连接了,这时客户端便可以将Http请求数据发送给服务器端。服务器端进行处理,然后以http response的形式发送给客户端。

    IP地址的分类

    A类地址:1个字节的网络号+3个字节的主机地址 0.0.0.0~126.255.255.255

    B类地址:2个字节的网络号+2个字节的主机地址 128.0.0.0~191.255.255.255

    C类地址:3个字节的网络号+1个字节的主机地址 192.0.0.0~223.255.255.255

    D类地址:多播地址

    E类地址:保留为今后使用

    路由器和交换机的区别

    交换机:为数据桢从一个端口到另外一个端口的转发提供了低时延、低开销的通路,使得任意端口接受的数据帧都能够从其他的端口送出。

    路由器:网络连接和路由选择,用于网络层的数据转发。

    如何设计一个高并发的系统?

    ① 数据库的优化,包括合理的事务隔离级别、SQL语句优化、索引的优化

    ② 使用缓存,尽量减少数据库 IO

    ③ 分布式数据库、分布式缓存

    ④ 服务器的负载均衡

    设计模式

    简单工厂模式

    有一个抽象的产品父类将所有的具体的产品抽象出来,达到复用的目的。同时有一个简单工厂维护一个对抽象产品的依赖,在该简单工厂中去负责实例的创建,在该工厂中去实例不同的对象,往往需要利用case判断语句去动态实例化相关的类。

    工厂方法模式

    创建对象的接口,让子类去决定具体实例化的对象,把简单的内部逻辑的判断,转移到了客户端,让客户端去动态地实例化相关的子类。工厂方法模式克服了简单工厂违背开放-封闭原则的特点。

    抽象工厂模式

    提供创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类。

    职责链模式

    使得多个对象都有机会去处理请求,从而避免请求的 发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链去传递该请求,直到有一个对象处理它为之。

    单例模式

    (2)恶汉式的单例模式

    利用静态static的方式进行实例化,在类被加载时就会创建实例。

    /**

    • 饿汉式实现单例模式

    */

    public class Singleton {

    ** private static Singleton instance = new Singleton();**

    private Singleton() {
    
    }
    
    public static Singleton getInstance() {
    
        return instance;
    
    }
    

    }

    (6)懒汉式实现单例模式

    在被第一次引用时才去创建对象。

    /**

    • 懒汉式实现单例模式

    */

    public class Singleton {

    private static Singleton instance;//创建私有的静态变量
    
    private Singleton() {//私有的构造函数
    
    }
    
    // synchronized方法,多线程情况下保证单例对象唯一
    

    public static synchronized Singleton getInstance() {

    //如果实例对象为空,就重新去实例化

        if (instance == null) {
    
            instance = new Singleton();
    
        }
    
        return instance;
    
    }
    

    }

    分析:这中方法的实现,效率不高,因为该方法定义为同步的方法。

    (7)双重锁实现的单例模式

    /**

    • DCL实现单例模式

    */

    public class Singleton {

    private static Singleton instance = null;
    
    private Singleton() {
    
    }
    
    public static Singleton getInstance() {
    
        // 两层判空,第一层是为了避免不必要的同步
    
        // 第二层是为了在null的情况下创建实例
    
        if (instance == null) {
    
            synchronized (Singleton.class) {
    
                if (instance == null) {
    
                    instance = new Singleton();
    
                }
    
            }
    
        }
    
        return instance;
    
    }
    

    }

    分析:资源的利用率较高,在需要的时候去初始化实例,而且可以保证线程的安全,该方法没有去进行同步锁,效率比较好。

    (8)静态内部类实现单例模式

    /**

    • 静态内部类实现单例模式

    */

    public class Singleton {

    private Singleton() {
    

    }

    //返回实例的方法

    public static Singleton getInstance() {
    
        return SingletonHolder.instance;
    
    }
    
    /**
    
     * 静态内部类
    
     */
    

    private static class SingletonHolder {

    ** //静态私有的实例对象**

    ** private static Singleton instance = new Singleton();**

    ** }**

    }

    分析:第一次加载类时不会去初始化instance,只有第一次调用getInstance()方法时,虚拟机才会加载内部类,初始化instance

    可以保证线程的安全,单例对象的唯一,延迟了单例的初始化。

    (9)枚举单例

    /**

    • 枚举实现单例模式

    */

    public enum SingletonEnum {

    INSTANCE;
    
    public void doSomething() {
    
        System.out.println("do something");
    
    }
    

    }

    分析:枚举实例的创建是线程安全的,即使反序列化也不会生成新的实例,在任何的情况下都是单例的。

    适配器模式

    将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口步兼容而不能一起工作的类变得可以一起工作。

    target是我们所期望的接口的类型,包含一个request方法,通过使用adapter去实现该接口,并实现其中的request方法,在adapter中建立一个私有的adaptee对象,在adapter重写的方法中去调用specificRequest方法,这样适配器adapter就构建好了。只需要在客户端,创建adapter实例,调用request方法就可以利用多态的方式,实现了specificRequest()方法。

    观察者模式

    定义了一种一对多的依赖关系,让多个观察者可以同时去监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有的观察者对象,使得他们能够自动更新自己。

    Subject:把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者,可以增加删除观察者对象。

    Observer:抽象观察者,为所有的具体的观察者定义一个接口,在得到主题时更新自己。

    concreteObserver:具体的观察者,实现更新的方法

    concreteSubject:具体的主题

    作用:应用在一个对象改变时,需要改变其他的对象,而且具体不知道有多少个对象需要改变,将耦合的双方都依赖于抽象而不是依赖于具体,从而使得各自的变化都不会影响到另外一边的变化。

    大整数BigInteger 大浮点数 BigDecimal

    java运算的优先级:优先级相同时比较结合性:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值