Java - 程序员面试笔记记录 实现 - Part2

2.1 输入输出流

流可以被看作一组有序的字节集合,即数据在两个设备间的传输。

字节流:以字节作为单位,读到一个字节就返回一个字节;InputStream & OutputStream。

字符流:使用字节流读到一个到多个字节先查询码表再返回;Reader & Writer。会使用缓存。

Java IO 类设计时采用了 Decorator 模式(装饰者)

2.1 补充 - 装饰者模式

装饰者模式的组成部分:

  1. Component(抽象组件):定义了一个接口,描述了可以动态添加的责任。

  2. ConcreteComponent(具体组件):定义了Component接口的具体实现。

  3. Decorator(抽象装饰者):抽象类,实现了Component接口,并持有Component接口的一个实例。

  4. ConcreteDecorator(具体装饰者):具体装饰者类,实现Decorator的抽象方法,并添加额外的功能。

装饰者模式的实现步骤:

  1. 定义组件接口(Component),它有一个方法,比如 operation()

  2. 创建具体组件类(ConcreteComponent),实现Component接口。

  3. 创建装饰者抽象类(Decorator),实现Component接口,并包含一个Component接口的引用。

  4. 实现具体装饰者类(ConcreteDecorator),继承Decorator类,并添加额外的功能。

  5. 通过组合,Decorator可以动态地给Component添加功能。

装饰者模式的好处主要包括:

  1. 动态扩展性:可以在运行时动态地给一个对象添加额外的职责,而不需要修改原有的代码结构。

  2. 灵活性:装饰者模式提供了一种灵活的替代方案,用于继承,可以基于需要向对象添加任意数量的职责。

  3. 低耦合性:装饰者模式允许系统在对象间保持较低的耦合度,因为对象不需要知道它是由哪些装饰者组成的。

  4. 可维护性:当需要添加新的功能时,可以简单地创建新的装饰者类,而不是修改现有的类,这符合开闭原则(对扩展开放,对修改封闭)。

  5. 责任分离:装饰者模式有助于将类的不同职责分离开来,使得各个职责可以独立地变化和扩展。

使用装饰者模式而不是继承的理由:

  1. 避免类的爆炸式增长:如果使用继承来扩展功能,每个类的新组合都会产生一个新的子类,这可能导致类的数量急剧增加。

  2. 减少继承的缺陷:继承是一种静态的、静态绑定的关系,它限制了灵活性。装饰者模式使用组合和动态绑定,提供了更大的灵活性。

  3. 继承是强耦合的:继承关系使得基类和子类之间存在强耦合,基类的任何变化都可能影响到子类。装饰者模式通过组合来实现,耦合度较低。

  4. 继承层次结构可能很复杂:随着功能的增加,基于继承的层次结构可能变得复杂且难以管理。装饰者模式提供了一种更扁平化和灵活的结构。

  5. 多重继承问题:Java不支持多重类继承,但可以有多多个接口。如果需要实现多个不相关的功能扩展,继承可能无法满足需求,装饰者模式可以解决这个问题。

总之,装饰者模式提供了一种更加灵活和动态的方式来扩展对象的功能,同时避免了继承可能带来的问题和限制。

2.1 Java Socket \ TCP & UDP

Socket 由IP地址和端口号唯一确定。

面向链接的 Socket (TCP)

面向无连接的 Socket (UDP)

TCP(传输控制协议)

  1. 连接导向:TCP 需要在数据传输之前建立连接,通过三次握手过程。

  2. 可靠的:TCP 提供可靠的数据传输服务,确保数据包正确、按顺序地到达目的地。

  3. 面向字节流:TCP 没有消息边界,它将数据视为字节流。

  4. 错误恢复:TCP 有错误检测和重传机制,如果数据包丢失或损坏,TCP 会重新发送它们。

  5. 拥塞控制:TCP 有拥塞控制机制,可以在网络拥塞时减慢数据传输速度。

  6. 有序传输:TCP 保证数据包的顺序传输,如果出现乱序,接收方会缓存数据直到可以按顺序重组。

  7. 带宽消耗:由于 TCP 的可靠性和控制机制,它可能会消耗更多的带宽。

UDP(用户数据报协议)

  1. 无连接:UDP 是无连接的,它在数据传输前不需要建立连接。

  2. 不可靠的:UDP 不保证数据包的到达、顺序或完整性,它只是尽可能快地发送数据。

  3. 面向消息:UDP 面向消息,发送的数据被分割成数据报,每个数据报都是独立的。

  4. 错误检测有限:UDP 只提供了最基本的错误检测,不负责重传丢失的数据包。

  5. 无拥塞控制:UDP 没有拥塞控制,即使网络拥堵,它也会继续以全速发送数据。

  6. 有序性不保证:UDP 不保证数据包的顺序,如果数据包乱序到达,接收方需要自己处理。

  7. 带宽消耗较少:UDP 由于其简单性,通常消耗较少的带宽。

TCP(传输控制协议)的三次握手是建立一个可靠的连接所必须的过程。这个过程确保了两个端点(客户端和服务器)都能够接收和发送数据。以下是三次握手的步骤:

  1. SYN(同步序列编号)

    • 客户端选择一个初始序列号(ISN,Initial Sequence Number)并发送一个带有 SYN 标志位设置为 1 的数据包给服务器,以请求建立连接。这表示客户端准备好发送数据了。
  2. SYN-ACK(同步-确认)

    • 服务器接收到客户端的 SYN 数据包后,会用自己的初始序列号响应一个 SYN-ACK 数据包。这个响应中 SYN 标志位和 ACK(确认)标志位都被设置为 1。服务器的序列号是它选择的 ISN,而 ACK 值是客户端的 ISN 加 1。
  3. ACK(确认)

    • 客户端接收到服务器的 SYN-ACK 数据包后,会发送一个带有 ACK 标志位设置为 1 的数据包给服务器,以完成连接建立。客户端的 ACK 值是服务器的 ISN 加 1。此时,连接建立完成,客户端和服务器都可以开始发送数据。
2.1 Java 序列化

- 序列化:实现序列化的类需要实现Serializable 接口(标记接口),调用方法为:使用一个输出流构造一个 ObjectOutputStream 对象,使用其 writeObject 方法来写出对象。被声明为 static 和 transient 的数据成员不可以被序列化。

  • 对于 static 数据成员

    • 由于static字段是类级别的,通常不需要序列化。如果你需要保存类的状态,可以考虑将static字段的值存储在某个地方,然后在对象反序列化后恢复它们。
    • 例如,你可以使用一个静态方法来获取和设置static字段的值,然后在序列化和反序列化过程中手动调用这个方法。
  • 对于 transient 数据成员

    • 如果你需要在反序列化后恢复transient字段的状态,你可以在反序列化过程中显式地重新赋值。
    • 一种常见的做法是在类的构造函数或一个单独的初始化方法中重新设置transient字段的值。

- 外部序列化:自定义读写接口

2.2 同步 \ 异步 \ 阻塞 \ 非阻塞

多线程语境下:

- 同步 & 异步:关注任务是否可以被多个线程同时调用,同步是仅可以被一个线程访问。

- 阻塞 & 非阻塞:关注线程的状态,阻塞代表线程挂起。

IO语境下:

- 同步 & 异步:关注消息发起和接受的机制,同步是发起一个IO操作后得到返回才进行后续操作,异步是指发起IO操作后不等待返回。通过轮询、回调等方式等待结果。

- 阻塞 & 非阻塞:关注等待结果的状态:阻塞指需要等待IO操作结束。

并发 & 并行:并发在同一时刻只有一条指令执行;并行同一时刻多条指令同时执行。

2.3 BIO \ NIO \ AIO

BIO :阻塞式IO;

NIO:基于Selector 的异步网络 IO( Selector 轮询所有被注册的 channel ,一旦发现 Channel 上被注册的事件发生就可以进行处理)

AIO:基于 Proactor 实现基于事件和回调机制的 I/O 操作方式,允许应用程序在执行 I/O 操作时不被阻塞,从而可以处理其他任务。

1. 每个 socket 链接在事件分离器注册IO完成事件和回调处理;

2. 应用程序需要进行IO时,向分离器发出IO请求,分离器通知系统处理;

3. 系统尝试IO操作,完成后通知分离器;

4. 分离器检测到IO完成事件后,激活回调。

2.3 补充 Channel 

在 Java NIO(New Input/Output)库中,"Channel" 是指可以用于执行 I/O 操作的通道。Java NIO 中的通道类似于传统的"流",但有一些重要的区别:

  • 通道可以非阻塞,允许单线程处理多个输入/输出通道。
  • 通道总是基于缓冲区的,数据从通道读取到缓冲区,或从缓冲区写入到通道。

3.1 Collections

Java 中的容器可以分为两类

Collection:存储独立的元素,包括

- List:按插入顺序保存元素;eg:LinkedList & ArrayList & Vector;

- Set:不可有重复元素,通过equals 方法来保证唯一;eg:HashSet & TreeSet;

- Queue: 队列

- Stack:堆栈

Map:存储键值对;eg: HashMap、TreeMap、LinkedHashMap;

3.2 LinkedList & ArrayList & Vector

ArrayList: 数组实现。读取快,扩容慢。

LinkedList:双向链表;非线程安全。注意:Java标准库并没有直接提供一个现成的线程安全的双向链表实现。

Vector:与 ArrayList 相比是线程安全的。

3.3 Map

HashMap: 键值与下标的关系由 hashcode 决定,即 hash 桶。仅当 hashcode 和 equals 相同才被认为是一个对象。

Java 8 之前的实现是数组加链表

Java 8 之后:采用了数组+树+链表的结构,当链表达到最大深度时,重构为红黑树。

TreeMap:完全由红黑树实现,元素有序。

LinkedHashMap

Java 8 之前:为每个数据节点的引用多维护了一份链表。

Java 8 中

HashTable : hashtable 为线程安全的,不可存储 null 值;

WeakHashTable: key值如果没有外部强引用,垃圾回收时,对应内容也会被移除掉。

ConcurrentHashMap: HashMap 中支持高并发、高吞吐的线程安全版本。包含一个 Segment 数组,结构和 HashMap类似,每个Segment 守护着一个 HashEntry 里的元素,对 HashEntry 数组进行修改时需要先获得 Segment 锁。注意,在某些情况下还是存在线程不安全的可能,例如 map.pub 方法不是一个原子操作。所以在进行操作时最好在线程里对操作加锁。

3.4 Set

HashSet:HashSet 内部通过 HashMap 实现,所有的值使用相同的 value。同样,其不是线程安全的。

LinkedHashSet:可维护插入数据的顺序。底层是 LinedHashMap。

TreeSet:底层使用 TreeMap 来存储数据

3.5 BlockingQueue

生产者线程在仓库装满之后会被阻塞,消费者线程则实在仓库清空后阻塞。

ArrayBlockingQueue:基于数组实现的有界 BlockingQueue,陷入先出。线程安全。

LinkedBlockingQueue:使用了双锁队列算法。线程安全。

PriorityBlockingQueue:队头元素是队列的最小元素。使用的最小堆结构。

ConcurrentLinkedQueue: 非阻塞的线程安全队列。采用的CAS 方式保证。

DelayQueue:阻塞的优先队列,管理的对象必须要实现util.concurrent.delayed接口,其线程安全由重入锁实现。

3.5 - 补充 CAS 算法

CAS(Compare-And-Swap,比较并交换)算法是一种用于并发控制的技术,主要用于多处理器系统中实现原子操作。CAS操作通常由三个参数组成:内存位置(V),预期值(A)和新值(B)。基本思想是,如果内存位置的当前值与预期值相匹配,那么将内存位置的值更新为新值。如果不相匹配,操作则不执行任何操作或回滚。

3.7 迭代器

使用 Iterator 遍历容器时,如果对容器增加或者删除操作操作就会改变容器数量,导致抛出异常。解决方法:使用线程安全的容器来做迭代器。eg: ConcurrentHashMap 等。

3.8 并行数组操作

例如 parallexXXX 方法,使用多线程进行操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38667.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于RabbitMQ的异步消息传递:发送与消费

引言 RabbitMQ是一个流行的开源消息代理,用于在分布式系统中实现异步消息传递。它基于Erlang语言编写,具有高可用性和可伸缩性。在本文中,我们将探讨如何在Python中使用RabbitMQ进行消息发送和消费。 安装RabbitMQ 在 Ubuntu 上安装 Rabbi…

提升写作效率:探索AI在现代办公自动化中的应用

工欲善其事,必先利其器。 随着AI技术与各个行业或细分场景的深度融合,日常工作可使用的AI工具呈现出井喷式发展的趋势,AI工具的类别也从最初的AI文本生成、AI绘画工具,逐渐扩展到AI思维导图工具、AI流程图工具、AI生成PPT工具、AI…

ubuntu 系统中 使用docker 制作 Windows 系统,从此告别 vmware虚拟机

我的系统是 ubuntu 24 前期准备工作: 安装dockerdocker pull 或者 手动制作镜像 docker build 的话 必须要 科学上网, 好像阿里镜像都下不下来。需要 知道 docker 和docker compose 命令的使用方式 我是给docker 挂了 http代理 如果你能pull下来镜像 …

springboot健身房管理系统-计算机毕业设计源码031807

摘 要 大数据时代下,数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势。在健身房管理的要求下,开发一款整体式结构的健身房管理系统…

Windows环境使用SpringBoot整合Minio平替OSS

目录 配置Minio环境 一、下载minio.exe mc.exe 二、设置用户名和密码 用管理员模式打开cmd 三、启动Minio服务器 四、访问WebUI给的地址 SpringBoot整合Minio 一、配置依赖,application.yml 二、代码部分 FileVO MinioConfig MinioUploadService MinioController 三…

使用Python绘制太阳系图

使用Python绘制太阳系图 太阳系图太阳系图的优点使用场景 效果代码 太阳系图 太阳系图(Sunburst Chart)是一种层次结构图表,用于表示数据的分层结构。它使用同心圆表示各个层级,中心圆代表最高层级,向外的圆环代表逐级…

CCT技术

概念介绍 多个功能核心的集成可以通过片上系统(SOC)或封装中系统(SIP)设备的开发来实现。SOC器件将核心集成到单个集成电路中。SIP集成是将多个集成电路组合到单个封装中。核心数量 的增加可能导致必要的测试人员资源和/或测试时间的增加。这直接影响了与测试这些设备相关的…

CesiumJS【Basic】- #031 绘制虚线(Entity方式)

文章目录 绘制虚线(Entity方式)1 目标2 代码2.1 main.ts绘制虚线(Entity方式) 1 目标 使用Entity方式绘制虚线 2 代码 2.1 main.ts import * as Cesium from cesium;const viewer = new Cesium.Viewer(

SAP实现特别总账的凭证预制

SAP实现特别总账的凭证预制 仔细理解只有”其他”的特殊总帐标识才可预制凭证这句话. F-29/f-48不可预制。F-29/f-48预制时出现错误消息号 FP 030,提示特殊总帐标志类型“汇票和”预付定金“的特别总帐标志的过帐代码不能预制,这是系统写死的&#xff…

现在电气真的比不过计算机吗 ?

电气工程和计算机科学在今天的科技和工业领域中各有其重要性和发展空间,并不存在简单的比较谁“比不过”谁的情况。我收集制作一份plc学习包,对于新手而言简直不要太棒,里面包括了新手各个时期的学习方向,包括了编程教学&#xff…

Pycharm的终端(Terminal)中切换到当前项目所在的虚拟环境

1.在Pycharm最下端点击终端/Terminal, 2.点击终端窗口最上端最右边的∨, 3.点击Command Prompt,切换环境, 可以看到现在环境已经由默认的PS(Window PowerShell)切换为项目所使用的虚拟环境。 4.更近一步,如果想让Pycharm默认显示…

Linux常用工具使用方式

目录 常用工具: 安装包管理工具: 查找含有关键字的软件包 安装软件 安装文件传输工具 安装编辑器 C语言编译器 C编译器 安装调试器 安装项目版本管理工具 cmake 卸载软件 安装jsoncpp 安装boost库 安装mariadb 安装tree(让目录…

潜水耳机哪个牌子好?用户精选,这四款潜水耳机质量上乘!

在这个快节奏的时代,人们越来越渴望在运动中也能享受到音乐的陪伴。潜水,作为一种独特的水下运动,自然也不例外。然而,并非所有的耳机都能承受水下的压力和环境,这就要求我们对潜水耳机有着更高的要求。作为一名资深的…

Kubernetes的发展历程:从Google内部项目到云原生计算的基石

目录 一、起源与背景 1.1 Google的内部项目 1.2 Omega的出现 二、Kubernetes的诞生 2.1 开源的决策 2.2 初期发布 三、Kubernetes的发展历程 3.1 社区的成长 3.2 生态系统的壮大 3.3 重大版本和功能 3.4 多云和混合云的支持 四、Kubernetes的核心概念 4.1 Pod 4.…

hive4 从入门到精通

查询hive 架构 准备 HDFS配置 vim $HADOOP_HOME/etc/hadoop/core-site.xml <!--配置所有节点的root用户都可作为代理用户--><property><name>hadoop.proxyuser.root.hosts</name><value>*</value></property><!--配置root用户…

Jenkins接口自动化项目的工程创建

jenkins的下载安装 jenkins下载的官网地址 https://www.jenkins.io/download/ java环境变量的配置下载 jenkins是用java语言编写的所以要配置java环境 需要安装java的JDK 推荐安装JDK17(https://blog.csdn.net/wochunyang/article/details/138520209) JDK17的下载地址 ht…

加载数据到mysql并解决原始数据乱码问题

查看linux上数据&#xff1a; 使用命令转换编码&#xff1a; iconv -f GBK -t UTF-8 toutiao.csv -o toutiao2.csv加载数据到mysql: load data local infile /root/toutiao2.csv INTO TABLE pdz FIELDS TERMINATED BY , LINES TERMINATED BY \r\n;

ZXL-2000砌体砂浆强度点荷仪

一、产品简介&#xff1a; 砌体砂浆强度点荷仪&#xff08;又名&#xff1a;砂浆点荷仪&#xff09;&#xff0c;是根据GB/T50315-2000《砌体工程现场检验技术规程》而研制生产的。是砌体砂浆强度检测的专用仪器&#xff0c;其特点是能在现场或试验室直接测试&#xff0c;不影…

Java短剧系统

探索影视新体验 &#x1f4f1;一、引言&#xff1a;短剧时代的来临 在数字化的今天&#xff0c;我们见证了许多内容消费模式的转变。从长篇大论的电视剧到短小精悍的短视频&#xff0c;再到如今备受瞩目的短剧&#xff0c;观众对于影视内容的需求越来越多元化。而短剧系统微信…

vite+vue集成cesium

1、创建项目、选择框架vuejs pnpm create vite demo_cesium 2、进入项目安装依赖 cd demo_cesium pnpm install3、安装cesium及插件 3、pnpm i cesium vite-plugin-cesium 4、修改vite-config.js import { defineConfig } from vite import vue from vitejs/plugin-vue impo…