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

news2024/11/18 0:49:56

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.coloradmin.cn/o/1882487.html

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

相关文章

【技巧】ArcGIS Pro设置自动保存数据编辑内容

一、工程文件自动保存 ArcGIS Pro软件的工程也可以自动保存备份。默认备份时间是5分钟,您可以在【工程】→【选项】→【常规】→【工程恢复】中调整自动备份时间。 二、数据编辑自动保存 操作方法:【工程】→【选项】→【编辑】→【会话】,勾…

安卓app开发-基础-本地环境安装android studio且配置参数

安卓app开发-基础-本地环境安装android studio且配置参数!今天为大家介绍一下,如何在自己本地电脑安装android ,studio和启动一个简单的java版本的项目。 第一步,去下面的地址,下载一个安装文件。 地址:AndroidDevToo…

Stable Diffusion 商业变现与绘画大模型多场景实战

前言 ai绘画软件Stable Diffusion是一种通过模拟扩散过程,将噪声图像转化为目标图像的文生图模型,具有较强的稳定性和可控性,可以将文本信息自动转换成高质量、高分辨率且视觉效果良好、多样化的图像。在日常工作中,ai绘画软件St…

(3)Java 8 实战第二版——使用流和Lambda进行高效编程

集合工厂 List<String> friends Arrays.asList("Raphael", "Olivia"); friends.set(0, "Richard"); friends.add("Thibaut"); ←---- 抛出一个UnsupportedModificationException异常通过工厂方法创建的Collection的底层…

加载数据到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;

中霖教育怎么样?税务师通过率高吗?

中霖教育怎么样?税务师通过率高吗? 我们在税务师考试培训方面有着不错的成绩&#xff0c;这都是老师与学员共同努力的结果。 采用小班教学模式&#xff0c;确保每位学员都能得到足够的关注和指导&#xff0c;在学习过程中针对学员的薄弱环节进行专项突破。 因为大部分学员…

《昇思25天学习打卡营第4天|数据集 Dataset》

文章目录 前言&#xff1a;今日所学&#xff1a;1. 数据集加载2. 数据集迭代3. 数据集常用操作与自定义数据集 前言&#xff1a; 今天学习的是数据集的内容。首先&#xff0c;数据是深度学习的基石&#xff0c;高质量的数据输入能够在整个深度神经网络中发挥积极作用。MindSpo…

ATA-7015铁电仪高压放大器的作用是什么

铁电仪高压放大器是科学实验和工业应用中的一种重要设备&#xff0c;主要用于放大铁电仪测量中产生的微弱信号。铁电仪是一种用于测量材料电介质中铁电性质的仪器&#xff0c;其工作原理基于材料在电场中表现出的电极化现象。高压放大器在铁电仪中的作用是将由被测材料产生的微…

Golang-slice理解

slice golang-slice语雀笔记整理 slicego为何设计slice&#xff1f;引用传递实现扩容机制 go为何设计slice&#xff1f; 切片对标其他语言的动态数组&#xff0c;底层通过数组实现&#xff0c;可以说是对数组的抽象&#xff0c;底层的内存是连续分配的所以效率高&#xff0c;可…

qt结合vs2022安装

进入清华大学开源软件&#xff1a; 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 下载完成后&#xff0c;双击进行安装&#xff1a; 进入邮箱进行验证&#xff1a; 可能是因为网络问题&#xff0c;无法安装。 重新安装5.12.12版本。 安装后启动失败&#xff0c;重新…

tauri使用github action实现跨平台编译并解决编译错误,mac已损坏,无法打开,你应该将它移到废纸篓解决办法

正常编译为跨平台结果就像上面的&#xff0c;有mac/windows/linux的安装程序&#xff0c;直接下载就可以安装使用&#xff0c;我的这个livebox桌面端仓库地址&#xff1a;GitHub - Sjj1024/LiveBox: livebox&#xff0c;里面有编译文件可以参考。今天主要讲一下遇到的问题。 官…

【FFmpeg】av_write_frame函数

目录 1.av_write_frame1.1 写入pkt&#xff08;write_packets_common&#xff09;1.1.1 检查pkt的信息&#xff08;check_packet&#xff09;1.1.2 准备输入的pkt&#xff08;prepare_input_packet&#xff09;1.1.3 检查码流&#xff08;check_bitstream&#xff09;1.1.4 写入…

C++知识点总结全系列 (05):IO 类的详细总结和分析

1、基类 istream 和 ostream (1)istream A.What 输入流的抽象类&#xff0c;是所有输入流类的基类 B.Why&#xff08;输入流的作用&#xff09; 用于从数据源&#xff08;如文件、标准输入设备等&#xff09;读取数据 (2)ostream A.What 输出流的抽象类&#xff0c;是所有输…

重温react-09(高阶组件的使用方式和注意事项)

高阶组件 可以理解为vue的混入吧&#xff0c;但是没有那个方便&#xff08;个人见解&#xff09; 挂载的全局App.jsx的代码 import React from react; import LearnFunction05 from ./LearnFunction05; // 这个是高阶函数的用法 export default function boxReact() {retur…

六西格玛绿带培训的证书有什么用处?

近年来&#xff0c;六西格玛作为一套严谨而系统的质量管理方法&#xff0c;被广泛运用于各行各业。而六西格玛绿带培训证书&#xff0c;作为这一方法论中基础且重要的认证&#xff0c;对于个人和企业而言&#xff0c;都具有不可忽视的价值。本文将从多个角度深入探讨六西格玛绿…

你敢相信吗,AI绘画正在逐渐取代你的工作!

前言 在当今信息技术高速发展的时代&#xff0c;AI绘画技术的崛起已引起了广泛关注和讨论。许多人开始担心AI技术是否会逐渐取代传统绘画师的工作。人类无疑是感性的动物&#xff0c;创作出来的艺术作品常常带有浓郁的个人风格和情感。但AI绘画在某些方面的突破&#xff0c;使…

浅谈定时器之泊松随机定时器

浅谈定时器之泊松随机定时器 “泊松随机定时器”(Poisson Random Timer)&#xff0c;它允许你基于泊松分布来随机化请求之间的延迟时间&#xff0c;这对于模拟具有随机到达率的事件特别有用&#xff0c;如用户访问网站或服务的请求。 泊松分布简介 泊松分布是一种统计与概率…

大厂面试官问我:在同步binlog的时候主库是一个时间,从库是一个时间,底层是怎么解决的?【后端八股文八:Mysql日志八股文合集(2)】

本文为【Mysql日志八股文合集&#xff08;2&#xff09;】初版&#xff0c;后续还会进行优化更新&#xff0c;欢迎大家关注交流~ 大家第一眼看到这个标题&#xff0c;不知道心中是否有答案了&#xff1f;在面试当中&#xff0c;面试官经常对项目亮点进行深挖&#xff0c;来考察…

国产压缩包工具——JlmPackCore SDK说明(二)——JlmPack_Create函数说明

一、JlmPack_Create函数说明 JlmPack_Create函数是创建jlm压缩文件的核心函数&#xff0c;最大允许CATALOG_MAX_LIMIT&#xff08;请参考Config.h&#xff09;个目录&#xff0c;意思是包括文件夹和文件在内&#xff0c;遍历整个列表最大允许CATALOG_MAX_LIMIT个目录对象&#…

Zabbix HA高可用集群部署

Zabbix HA高可用集群介绍 关键基础设施通常需要高可用性 (HA)&#xff0c;因为这些基础设施几乎不会造成停机。因此&#xff0c;对于任何可能失败的服务&#xff0c;都必须有一个故障转移选项&#xff0c;以便在当前服务失败时接管。 Zabbix 提供了易于设置的本机高可用性解决…