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

社招又来学习 Java 啦,这次选了何昊老师的程序员面试笔记作为主要资料,记录一下一些学习过程。

1.1 Java 程序初始化

Java 程序初始化遵循规则:静态变量优于动态变量;父类优于子类;成员变量的定义顺序;

具体体现为:父类静态变量 -> 父类静态代码块 -> 子类静态变量 -> 子类静态代码 -> 父类非静态变量 -> 父类非静态代码块 -> 父类构造方法 -> 子类非静态变量 -> 子类非静态代码块 -> 子类构造方法。

1.2 构造方法

- 每个类可以有多个构造方法,当没有提供时,编译器在将源代码编译为字节码的时候会提供一个默认的没有参数的构造方法。

- 仅在对象实例化时调用,不可显示调用。

- 不可以被继承,也就无法被重写。但可以被重载:重写(Override)是指子类有一个方法与其父类中的某个方法具有相同的方法名、返回类型和参数列表。然而,构造方法不能被重写,因为它们没有返回类型,并且其名称必须与类名相同,这使得子类无法声明一个与父类构造方法签名相同的方法。Java设计者选择不允许构造方法被继承或重写,主要是为了避免构造过程中的复杂性和潜在的错误。构造方法的调用必须明确无误,以确保对象在使用前被正确初始化。

- 子类可以通过 super 关键字显式调用父类的构造方法;实例化对象时,首先会调用父类的构造方法再执行子类的构造方法;

1.3 clone 方法的作用

Java 在处理基本数据类型时采用值传递的方式,其他类型都是按引用传递。clone 提供从某个已有的对象创造出一个和此对象相同状态的对象的方法。

clone 的类继承 cloneable 接口(实际无任何接口方法,仅为标识),重写 Object 类中的 clone 方法,在 clone 方法里调用 super.clone()(最终都会调用到 object 的 clone 方法,这个方法返回 object 对象的一个拷贝),最终将浅拷贝的引用指向对象新的克隆体。

默认的 clone 方法仅提供了浅克隆,实现深克隆通常比实现浅克隆更复杂,因为深克隆需要递归地复制对象的所有引用对象。以下是实现深克隆的一些方法:

  1. 重写clone()方法:如果你的类中的对象引用了其他对象,并且你想要复制这些对象,你需要重写clone()方法,并在这个方法中确保所有引用的对象也被复制。

  2. 使用序列化:一种实现深克隆的简单方式是使用对象序列化机制。通过将对象序列化到一个字节数组,然后再从该字节数组反序列化,可以创建对象的一个完整副本。

  3. 复制构造函数:创建一个复制构造函数,它接受一个原对象作为参数,并使用该对象的值来初始化新对象。这种方法需要确保所有引用的对象也通过复制构造函数被复制。

  4. 复制工厂方法:类似于复制构造函数,但使用一个静态方法来创建对象的副本。

  5. 使用Apache Commons Lang:如果你使用Apache Commons Lang库,可以使用SerializationUtils.clone()方法来实现深克隆。

在Java中,数组的克隆行为取决于数组的维度:

  1. 一维数组:当克隆一维数组时,会进行浅克隆。这意味着克隆操作会创建一个新的数组对象,但数组中的元素不会被克隆。如果数组元素是引用类型,那么克隆后的数组将引用与原始数组相同的对象。

  2. 多维数组:对于多维数组,克隆行为取决于每个维度的数组。每个维度的数组都是作为一个单独的一维数组来克隆的,因此每个维度的数组都是浅克隆的。这意味着,如果克隆一个二维数组,你会得到一个新的二维数组对象,但每个子数组仍然是原始子数组的引用。

如果你需要对数组进行深克隆,即数组及其所有元素都是全新的独立副本,你需要手动实现这一过程。对于一维数组,你可以创建一个新数组并复制每个元素;对于多维数组,你需要递归地复制每个子数组。

1.3 补充 - 访问级别

在Java中,publicprotectedprivate是访问修饰符,它们控制类成员(包括字段、方法和构造函数)的访问级别。以下是这三个访问修饰符的区别:

  1. public(公共的)

    • 成员可以被任何其他类访问,不受限制。
    • 无论是同一个包中的类还是不同包中的类,都可以访问public成员。
  2. protected(受保护的)

    • 成员可以被同一个包中的其他类访问,也可以被不同包中的子类访问。
    • 访问级别比public更受限,因为不同包中的非子类不能访问protected成员。
  3. private(私有的)

    • 成员只能在其所在的类内部访问。
    • private成员不能被同一个包中的其他类访问,也不能被子类访问(即使子类在同一包中)。
    • private是访问级别最受限的修饰符。

以下是一些额外的考虑:

  • 默认访问级别:如果既不使用publicprotected,也不使用private修饰,类成员具有默认访问级别。默认访问级别意味着成员只能被同一个包中的其他类访问,但不能被子类访问(即使子类在同一包中)。

  • 访问控制:访问修饰符是Java实现封装的一种方式。通过限制对类成员的访问,可以隐藏类的内部实现细节,只暴露必要的操作界面。

  • 继承和访问级别:当子类继承父类时,只能继承publicprotected成员。private成员不能被继承,因为它们不可见。

  • 类访问:类本身也可以使用这些访问修饰符。public类可以被任何其他类访问,而private类只能在定义它的类加载器中访问。

1.4 反射

反射机制是指对于处在运动状态的类,都可以获取到这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法及访问他的属性。具体为对任何一个类都可以得到对应的 Class 实例,通过 Class 实例就可以获取类或者对象的所有信息。

  1. 设计原则:反射的使用应该遵循Java的设计原则,即封装应该被尊重。滥用反射来访问私有成员可能会破坏类的封装性,使代码难以理解和维护。

  2. 使用场景:反射通常用于框架和库的开发,例如依赖注入框架、ORM(对象关系映射)框架等,这些框架需要访问目标类的私有成员以实现其功能。

1.5 Lambda 表达式

Lambda 表达式允许把函数作为一个方法的参数,即匿名函数。

1.6 多态的实现机制

多态意为同一个操作作用在不同的对象的时候会出现不同的语义,例如"+" 的操作。主要表现形式为

- 重载:同一个类中不同参数列表的同名方法,在编译时决定调用。

- 重写:子类可以重写父类的方法,运行时才计算用哪个方法。

1.8 抽象类与接口的异同

一个类中包含抽象方法即为抽象类;抽象类在使用时不能被实例化。其设计思想为继承,is - a 关系。

接口是方法的集合,可以设置默认实现;强调功能的实现,has a 关系

1.8 补充 - final 对象

在Java中,final变量表示一旦变量被初始化赋值之后,就不能再给它赋新的值。final变量可以是类的成员变量,也可以是局部变量。以下是final变量的一些关键特性:

  1. 不可变性final变量的值是不可变的。这意味着一旦给final变量赋了初值,就不能再修改它。

  2. 必须初始化final变量必须在声明时或者在构造器中被初始化。对于类的成员变量,如果它们是final的,并且在声明时没有显示初始化,那么它们必须在每个构造器中被初始化。

  3. 引用的不变性:如果final变量是一个引用,那么这个引用一旦指向一个对象,就不能指向另一个对象。但是,被引用的对象本身的字段是可以被修改的(除非对象本身是不可变的)。

  4. 局部变量:在方法中,你可以使用final来声明一个局部变量,表示这个方法不会改变这个变量的值。

  5. 参数:方法的参数也可以是final的,这表示方法内部不会改变参数的值。

  6. 匿名内部类:在使用匿名内部类时,如果外部类的成员变量是final的,那么这些变量可以在匿名内部类中安全使用,因为它们不会被改变。

  7. 常量:通常使用final来声明常量,因为常量的值不应该被改变。

  8. 性能优化:由于final变量的不可变性,编译器和运行时环境可以对它们进行优化。

1.8 补充 - 静态方法

静态方法(Static Method)是与类本身相关联,而非与类的任何特定对象相关联的方法。在Java中,静态方法使用static关键字进行声明。以下是静态方法的一些关键特性:

  1. 调用方式:静态方法可以通过类名直接调用,而不需要创建类的实例。例如:ClassName.methodName()

  2. 类级别:静态方法属于类级别,这意味着它们与类的所有实例共享,而不是与单个对象关联。

  3. 访问类变量:静态方法可以访问类的静态变量,但它们不能直接访问类的非静态成员变量或方法,除非通过对象引用。

  4. 构造函数:静态方法不能被重写(Override),因为它们不属于类的实例,但可以被再次声明(Overload)。

  5. 实例化:静态方法在类加载时即被初始化,不需要类实例化。

  6. 工厂模式:静态方法常用于实现工厂模式,用于创建类的实例,例如:return new Constructor()

  7. 工具类:静态方法常用于工具类(Utility Class),提供一组静态工具方法,这些方法通常执行通用操作,与类的实例无关。

  8. 单例模式:静态方法在实现单例模式时也非常重要,用于控制实例的创建。

  9. 静态初始化块:静态方法可以与静态初始化块(Static Initializer Block)一起使用,以执行类加载时的初始化操作。

1.9 break \ continue \ return

break:强制跳出当前循环;仅终止当前嵌套;

continue:停止当前循环,进入下次循环;

return:从方法返回;

1.10 switch 

仅支持枚举常量:int \ Integer \ byte \ short \ char(可以隐式的转换为 int 类型)。Java 7 后支持 String,本质是将其进行hash,得到一个int 类型的 hash值进行比较,匹配成功后还会调用 String.equals 方法进行判断。

1.11 volatile

volatile 的使用是为了线程安全但不保证线程安全。线程安全的三个要素:可见性、有序性和原子性。

  1. 原子性(Atomicity)

    • 原子性是指一个操作或者一系列操作要么全部执行,要么全部不执行,不会出现中间状态。
    • 在多线程环境中,为了确保操作的原子性,通常需要使用同步机制,如synchronized关键字、锁(Lock接口及其实现类)、原子变量类(如AtomicInteger)等。
  2. 可见性(Visibility)

    • 可见性是指当一个线程修改了共享变量的值,其他线程能够立即看到这个修改。
    • Java内存模型(JMM)规定了变量的修改和访问规则。为了确保可见性,可以使用volatile关键字、锁、以及一些并发API,如ThreadLocal
  3. 有序性(Ordering)

    • 有序性是指程序执行的顺序需要符合逻辑上的先后关系。
    • 在多线程环境中,由于编译器优化、处理器乱序执行等原因,指令重排序可能导致线程安全问题。为了确保有序性,可以使用volatile关键字来禁止指令重排序,或者使用synchronized和锁来保证代码块的执行顺序。

可以解决:缓存副本、指令重排序,但不可解决原子性问题(当一个线程执行写的时候才会修改标记)。synchoronized 关键字可以解决多线程的原子操作问题。

以下场景不需要保证原子性,仅需要提供可见性和有序性:

  1. 状态标志:如果一个变量仅用作标志,以指示某个状态或条件,而这个状态或条件的变更本身不涉及复杂的操作。

  2. 监控变量:在某些监控系统中,可能需要记录某个事件发生的次数或状态,而这些记录操作不需要复合操作的原子性。

  3. 控制变量:用于控制线程行为的变量,如启动标志、停止标志等,这些标志的状态改变不需要复杂的同步操作。

  4. 观察者模式:在观察者模式中,观察者的状态可能需要立即被主题所知,而不需要执行复合的原子操作。

  5. 日志记录:在多线程应用中,日志记录可能使用volatile变量来确保日志信息的可见性,尽管写入操作本身可能不是原子的。

  6. 简单的状态通知:当一个变量用于在线程间传递简单的状态信息,而不需要执行复合操作时。

  7. 非核心数据:对于那些不会引起严重后果的非核心数据,即使出现偶尔的数据不一致,也可以接受。

1.12 Java 基本数据类型

基本类型的数据变量在声明之后就会立刻在栈上分配内存空间,除以上类型外,其余都是引用类型。

1.14 值传递和引用传递的区别

值传递:方法调用中实参把值传给形参。形参仅是一个临时变量。

引用传递:传递对象的地址,形参和实参指向同一个存储单元,因此对形参的修改会影响实参的值。

1.16 字符串

JVM 中存在一个字符串常量池,可以被共享使用。从 JDK 1.7 开始字符串常量池从 Perm 移动到堆区了。

- 直接通过双引号声明的对象会放在常量池中;

- 通过 String 提供的 intern 方法会放入常量池中;

1.16 补充 - 内存泄露

通常指认为一个对象会被垃圾回收期收集,但是由于某种原因垃圾回收期器无法回收这个对象。eg: 1.6 版本之前的 substring 方法。

1.17 == \ equals \ hashCode

==:比较变量对应的内存中存储的数值是否相同。对于基础类型可以直接比较,对于引用类型只能判断是否指向同一块存储空间。

equals: 没有复写的情况下等于 ==;用于自定义两个类何时是相同的。

hashCode:Object类提供的将内存地址转换成一个int值,所以当没有重写时,任何对象的 hashcode 都不相同。一般覆盖 equals 也需要覆盖 hashcode 

1.18 String \ Stringbuffer \ StringBuilder \ StringTokenizer

String :不可变类。适用于共享。修改时会首先创建一个 StringBuilder。

StringBuffer:适用于一个字符串常被修改的场景。线程安全。

StringBuilder:类似 StringBuffer,线程不安全。

StringTokenizer:用于分割字符串。

1.19 finally

由于程序执行 return 时意味着当前方法的结束,任何语句只能在 return 之前执行(除开 exit),finnaly 也在 Return 之前结束且覆盖其他 return 语句。并且 return 时会复制变量的值。

- 首先执行 return 的语句但不返回,然后执行 finnally 块,最后才返回。

1.20 try with resource

在 Java 中,try-with-resources 特性可以应用于实现了 java.lang.AutoCloseable 接口或其子接口 java.io.Closeable 的对象。以下是一些常见的实现了这些接口的对象类型:文件、管道、数据库等。

1.21 补充 - 异常

Java的异常分为两大类:

  1. 编译时异常(Checked Exceptions):这些异常需要在代码中进行显式处理,通常是通过 throws 关键字在方法签名中声明,或者在方法内部使用 try-catch 块捕获并处理。
  2. 运行时异常(Runtime Exceptions):这些异常是程序逻辑错误导致的,比如空指针异常(NullPointerException)、数组越界异常(ArrayIndexOutOfBoundsException)等。它们是 RuntimeException 类的子类,不需要强制处理。

1.21 补充 - 金额

可以用 BigDecimal 来表示金额,因为 float 和 double 会存在丢失精度的问题。并且需要使用 string 类型进行调用。

1.21 补充 - 实现线程安全

方法一:使用提供了安全能力的原子变量例如 AtomicInteger;

方法二:用 sychronized 修饰方法,保证同一时刻只有一个线程调用;

方法三:手动对操作加锁解锁;

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

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

相关文章

Spring的jar包下载(最新版6.0版本)

1.在Spring官网的projects下面点击spring-framework 2.进入github官网 3.进入github后往下滑,点击Spring Framework Artifacts 4.往下滑找到 点击 5.在左边先点击Artifacts,在右边找到 libs-snapshot,展开libs-snapshot(之前其他…

道路救援入驻派单小程序开源版开发

道路救援入驻派单小程序开源版开发 1、用户立即救援 2、后台收到救援通知,派单救援师傅. 道路救援入驻派单小程序通常会包含一系列功能,旨在方便救援服务提供商、用户和后台管理系统之间的交互。以下是一个可能的功能列表: 用户端功能&…

GPOPS-II教程(4): 多级火箭上升最优控制问题

文章目录 本篇重点问题描述动力学方程约束条件性能指标 GPOPS代码main function1. 初始参数设置2. 边界条件设置3.初值猜测4.设置GPOPS求解器参数5.求解6.画图 continuous function1. 取输入参数2. 计算过程变量3. 写动力学方程4. 给输出 endpoint function坐标转换函数位置-速…

大猫咪守护LoRA:定制你的大猫私人大猫咪宠物写真合影,某音某书流行款

🌹大家好!我是安琪!感谢大家的支持与鼓励。 大猫咪LoRA模型简介 今天应群里同学大猫咪宠物合影写真提议,为大家介绍一款来自作者 沐沐人像合成的主题为大猫咪守护的LoRAl模型:沐沐-大猫咪。这是一款当下在某音、某书…

基于FreeRTOS+STM32CubeMX+LCD1602+MCP3308(SPI接口)的8通道ADC转换器Proteus仿真

一、仿真原理图: 二、仿真效果: 三、STM32CubeMX配置: 1)、时钟配置: 2)、USART配置: 四、软件部分: 1)、主功能函数: 2)、初始化部分: /* USER CODE BEGIN Header */ /** ******************************************************************************

Apache Flink类型及序列化研读生产应用|得物技术

一、背景 序列化是指将数据从内存中的对象序列化为字节流,以便在网络中传输或持久化存储。序列化在Apache Flink中非常重要,因为它涉及到数据传输和状态管理等关键部分。Apache Flink以其独特的方式来处理数据类型以及序列化,这种方式包括它…

vscode使用Black Formatter以及Flake8实现代码格式化

vscode使用Black Formatter以及Flake8实现代码格式化(实现和pycharm相似的效果) 简单介绍一下这两个插件的功能,flake8可以实现对python代码风格的检测,对空格换行等内容都会有提示。 Black Formatter则可以实现在保存时&#x…

kafka 消费者 API 使用总结

前言 应用程序使用KafkaConsumer向Kafka订阅主题,并从订阅的主题中接收消息。不同于从其他消息系统读取数据,从Kafka读取数据涉及一些独特的概念和想法。如果不先理解这些概念,则难以理解如何使用消费者API。本文将先解释这些重要的概念&…

【乐吾乐2D可视化组态编辑器】文件

1 文件 文件:文件的新建、打开、导入、保存、另存为、下载JOSN文件、下载ZIP打包文件、导出为HTML、导出为Vue2组件、导出为Vue3组件、导出为React组件(老版将不再维护)、下载为PNG、下载为SVG 乐吾乐2D可视化组态编辑器demo:ht…

Elasticsearch 聚合查询

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…

一、安装VMware16

本篇来源:山海同行 本篇地址:https://shanhaigo.cn/courseDetail/1805875642621952000 本篇资源:以整理到-山海同行 一、VMware虚拟机下载 1. 官网下载 1. 打开官网 打开VMware官网地址:https://www.vmware.com/ 2. 选择下载产…

【研究】两千亿高碳投资:头部资管气候行动观察

在气候语境中,“棕”与“绿”是一组对立色,前者被用来描述与低碳理念不符的行动。近日资管机构的“含棕量”受到了气候倡议者的检视。 正文 国际环保机构绿色和平在与海南成美慈善基金会联合发布《中国资产管理机构气候表现研究报告》(以下简…

Pytorch实战(一):LeNet神经网络

文章目录 一、模型实现1.1数据集的下载1.2加载数据集1.3模型训练1.4模型预测 LeNet神经网络是第一个卷积神经网络(CNN),首次采用了卷积层、池化层这两个全新的神经网络组件,接收灰度图像,并输出其中包含的手写数字&…

告别模糊时代,扫描全能王带来清晰世界

模糊碑文引发的思考 上个月中旬去洛阳拜访了著名的龙门石窟,本就对碑文和文字图画感兴趣的我们,准备好好欣赏一下龙门石窟的历史文化古迹。到了地方之后,我发现石窟的高度和宽度远远超出了想象,正因如此,拍出来的文字…

NewspaceGPT带你玩系列之美人鱼图表

这里写目录标题 注册一个账号,用qq邮箱,然后登录选一个可用的Plus,不要选3.5探索GPT今天的主角是开始寻梦美人鱼图表我选第一个试一下问:重新回答上面的问题,一切都用汉语重新生成一个流程图:生成一个网站登…

OpenAI“跌倒”,国产大模型“吃饱”?

大数据产业创新服务媒体 ——聚焦数据 改变商业 在AI的世界里,OpenAI就像是一位高高在上的霸主,它的一举一动,都能引发行业里的地震。然而,就在不久前,这位霸主突然宣布了一个决定,自7月9日起,…

2024热门骨传导蓝牙耳机怎么选?超全的选购攻略附带好物推荐!

对于很多喜欢运动健身的小伙伴,在现在市面上这么多种类耳机的选择上,对于我来说的话还是很推荐大家去选择骨传导运动耳机的,相较于普通的入耳式蓝牙耳机,骨传导耳机是通过振动来传输声音的,而入耳式耳机则是通过空气传…

以Bert训练为例,测试torch不同的运行方式,并用torch.profile+HolisticTraceAnalysis分析性能瓶颈

以Bert训练为例,测试torch不同的运行方式,并用torch.profileHolisticTraceAnalysis分析性能瓶颈 1.参考链接:2.性能对比3.相关依赖或命令4.测试代码5.HolisticTraceAnalysis代码6.可视化A.优化前B.优化后 以Bert训练为例,测试torch不同的运行方式,并用torch.profileHolisticTra…

正则表达式阅读理解

这段正则表达式可以匹配什么呢? ((max|min)\\s*\\([^\\)]*(,[^\\)]*)*\\)|[a-zA-Z][a-zA-Z0-9]*(_[a-zA-Z][a-zA-Z0-9]*)?(\\*||%)?|[0-9](\\.[0-9])?|\\([^\\)]*(,[^\\)]*)*\\))(\\s*[-*/%]\\s*([a-zA-Z][a-zA-Z0-9]*(_[a-zA-Z][a-zA-Z0-9]*)?(\\*||%)?|[0-…

Charls数据库+预测模型发二区top | CHARLS等七大老年公共数据库周报(6.19)

七大老年公共数据库 七大老年公共数据库共涵盖33个国家的数据,包括:美国健康与退休研究 (Health and Retirement Study, HRS);英国老龄化纵向研究 (English Longitudinal Study of Ageing, ELSA);欧洲健康、…