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 方法,使用多线程进行操作。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

传输距离3000M|低延迟|48K采样音频传输模块-SA356大功率发射模块

无线音频应用中,远距离音频传输在许多领域具有广泛的应用需求,例如大型会议系统、公共广播、户外活动和音乐演出等。为了满足这些需求,音频传输模块需要具备一些关键特性,包括长距离传输能力、高音质、低延迟、稳定性以及抗干扰能…

【第11章】MyBatis-Plus条件构造器(上)

文章目录 前言一、功能详解1. allEq2. eq3. ne4. gt5. ge6. lt7. le8. between9. notBetween10. like11. notLike12. likeLeft13. likeRight14. notLikeLeft15. notLikeRight16. isNull17. in18. notIn19. inSql20. notInSql21. eqSqlSince 3.5.622. gtSql Since 3.4.3.223. ge…

【CentOS7.6】yum 报错:Could not retrieve mirrorlist http://mirrorlist.centos.org

一、报错 1.报错内容如下 在使用 yum makecache 命令时报错,在 yum install -y xxx 的时候报错等等 [roothcss-ecs-a901 yum.repos.d]# yum makecache Loaded plugins: fastestmirror Determining fastest mirrors Could not retrieve mirrorlist http://mirrorl…

【鸿蒙学习笔记】Column迭代完备

属性含义介绍 Column({ space: 10 }) {Row() {Text(文本描述).size({ width: 80%, height: 60 }).backgroundColor(Color.Red)}.width(90%).height(90).backgroundColor(Color.Yellow) } .width(100%) // 宽度 .height(200) // 高度 .backgroundColor(Color.Pink) // 背景色 .…

【深圳大学算法设计与分析】 实验六 最大流应用问题 FF -> EK -> Dinic

目录 一、实验目的: 二、内容:棒球赛问题 三、实验要求 四、提交要求 ———————— 问题分析解释: ———————— 算法简解: Ford–Fulkerson 增广 Edmonds–Karp 算法 Dinic算法 Dinic和EK的区别: …

STM32第十四课:低功耗模式和RTC实时时钟

文章目录 需求一、低功耗模式1.睡眠模式2.停止模式3.待机模式 二、RTC实现实时时钟1.寄存器配置流程2.标准库开发3.主函数调用 三、需求实现代码 需求 1.实现睡眠模式、停止模式和待机模式。 2.实现RTC实时时间显示。 一、低功耗模式 电源对电子设备的重要性不言而喻&#xff…

【程序大侠传】异步架构应用回调数据接收接口偶发NPE

前序 在这片浩瀚的代码江湖中,各大门派林立,各自修炼独门绝技,江湖中的侠士们分别担任着开发、测试、产品和运维的角色,共同守护着这片数字化的疆域。 开发门派:代码剑宗 代码剑宗的弟子们精通各种编程语言&#xff…

【嵌入式】探索嵌入式世界:在ARM上构建俄罗斯方块游戏的奇妙之旅

文章目录 前言:1. 简介2. 总体设计思路及功能描述2.1 设计思路2.2 功能描述2.3 程序流程图 3. 各部分程序功能及详细说明3.1 游戏界面函数3.1.1 游戏界面中的图片显示3.1.2 游戏开始界面3.1.3 游戏主界面3.1.4 游戏结束广告界面3.1.5 游戏界面中的触摸反馈3.1.6 游戏…

【Spring Boot】基于 JPA 开发的文章管理系统(CRUD)

基于 JPA 开发的文章管理系统(CRUD) 1.实现文章实体2.实现数据持久层3.实现服务接口和服务接口的实现类3.1 创建服务接口3.2 编写服务接口的实现 4.实现增、删、改、查的控制层 API 功能4.1 获取文章列表4.2 根据 id 获取文章对象4.3 新增4.4 保存4.5 删…

第三届环境工程与可持续能源国际会议(EESE 2024)

随着全球气候变化和环境问题日益严峻,环境工程与可持续能源领域的研究和发展显得尤为重要。第三届环境工程与可持续能源国际会议(EESE 2024)作为这一领域的重要交流平台,将于2024年10月25日至27日在湖南长沙盛大召开。本次会议将汇…

算法实验2.2、2.3

2.2主要内容 比较快速排序&#xff0c;归并排序以及堆排序算法的时间效率。了解影响算法执行时间的 主要因素以及如何降低算法的执行时间。 #include<iostream> using namespace std; #include<stdio.h> #include<malloc.h> #include<stdlib.h> #inc…

vue全局方法plugins/utils

一、在src目录下创建一个plugins文件夹 test.ts文件存放创建的方法&#xff0c;index.ts用于接收所有自定义方法进行统一处理 二、编写自定义方法 // test.ts文件 export default {handleTest(val1: number, val2: number) {// 只是一个求和的方法return val1 val2;}, };三…

MySQL数据库的主从复制与读写分离

一、MySQL数据库的主从复制 1.主从复制的概述及原理 &#xff08;1&#xff09;主从复制的意义 在实际的生产环境中&#xff0c;如果对数据库的读和写都在同一个数据库服务器中操作,无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此&#xff…

【Nvidia+AI相机】涂布视觉检测方案专注提高锂电池质量把控标准

锂电池单元的质量在多个生产制造领域都至关重要&#xff0c;特别是在新能源汽车、高端消费电子等行业。这些领域的产品高度依赖锂电池提供持续、稳定的能量供应。优质的锂电池单元不仅能提升产品的性能和用户体验&#xff0c;还能确保使用安全。因此&#xff0c;保证锂电池单元…

微信小程序template模板引入

如图&#xff1a;temp.wxml是template引入的模板 在two.wxml中&#xff1a; import&#xff1a;是引入temp的页面让template中的内容显示出来在two页面中&#xff1b; include:是显示temp页面内容不在template包裹&#xff0c;template以外的view标签文字和不在view的文字让…

探索PcapPlusPlus开源库:网络数据包处理与性能优化

文章目录 0. 本文概要1. PcapPlusPlus介绍1.1 概述1.2主要特性和功能1.3 PcapPlusPlus 主要模块关系和依赖1.4 网络协议层处理过程 2. 实例2.1 基于 PcapPlusPlus 的应用程序设计和封装流程&#xff1a;2.2 多线程示例代码2.3 代码说明&#xff1a; 3. 程序性能进一步优化3.1 避…

Golang内存分配

Go内存分配语雀笔记整理 Golang内存模型设计理念思考核心代码阅读mspanmcachemcentral中心缓存mheap分配过程 Golang内存模型设计理念思考 golang内存分配基于TCmalloc模型&#xff0c;它核心在于&#xff1a;空间换时间&#xff0c;一次缓存&#xff0c;多次复用&#xff1b;…

基于x86+FPGA+AI轴承缺陷视觉检测系统,摇枕弹簧智能检测系统

一、承缺陷视觉检测系统 应用场景 轴类零件自动检测设备&#xff0c;集光、机、软件、硬件&#xff0c;智能图像处理等先进技术于一体&#xff0c;利用轮廓特征匹配&#xff0c;目标与定位&#xff0c;区域选取&#xff0c;边缘提取&#xff0c;模糊运算等算法实现人工智能高…

Linux 高级编程——线程控制

线程控制&#xff1a;互斥与同步 概念&#xff1a; 互斥 》在多线程中对临界资源的排他性访问。 互斥机制 》互斥锁 》保证临界资源的 访问控制。 pthread_mutex_t mutex; 互斥锁类型 互斥锁变量 内核对象 框架&#xff1a; 定义互斥锁 》初始化锁 》加…