华为OD面试,技术一面问什么?包含工厂模式,full gc
华为 OD 面试流程
- 机试:三道算法题,关于机试,橡皮擦已经准备好了各语言专栏,可以直接订阅。
- 性格测试:机试
- 技术一面
- 技术二面
- 主管面试
- 定级定薪发 offer
- 体检入职
本专栏的所有博客,将为大家整理技术一面二面中【面试官问到的题】,并提供大家答案。
所有问题都来自通过华为 OD 机考 通过人员 反馈信息。
每篇博客会涉及 7 个面试题,题目和答案仅供参考~
一、说一下常见的工厂模式
-
工厂模式是一种创建对象的设计模式,它提供了一种方法来创建对象,而不必直接实例化该对象。Java 中常见的工厂模式包括以下几种:
-
简单工厂模式:简单工厂模式是一种通过一个工厂类来创建不同类型的对象的模式。这种模式的核心是工厂类,它根据参数的不同返回不同类的实例。
-
工厂方法模式:工厂方法模式是一种定义一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法让类的实例化延迟到其子类中进行。
-
抽象工厂模式:抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定它们的类。这种模式通过一组工厂方法来创建所有相关的对象。
-
单例模式:单例模式是一种保证一个类仅有一个实例,并提供一个全局访问点的模式。这种模式通常在需要限制某个类的实例化数量时使用。
-
原型模式:原型模式是一种通过复制现有对象来创建新对象的模式。它使用 clone() 方法来复制现有对象并创建一个新的实例。
二、mysql 数据库优化
-
数据库设计优化:合理设计数据库表结构、字段类型、索引等,可以有效地提高查询性能。
-
硬件优化:选择合适的硬件配置,如 CPU、内存、硬盘等,可以减少瓶颈,提高系统整体性能。
-
SQL 优化:优化 SQL 语句可以提高查询效率。如避免全表扫描、合理使用索引、避免大量的子查询和 Join 等。
-
适当分区:对大型表进行分区可以提高查询效率和数据的管理效率。
-
内存优化:通过调整 MySQL 的缓存参数,如 key_buffer_size、innodb_buffer_pool_size 等,可以提高查询效率。
-
使用缓存技术:使用缓存技术,如 Memcached 或 Redis,可以减轻数据库的负载,提高系统整体性能。
三、zookeeper 的选举机制
ZooKeeper 的选举机制是保证 ZooKeeper 集群中只有一个 Leader 的核心机制。
ZooKeeper 集群中的每个节点都可以成为 Leader,但是为了保证数据的一致性和可靠性,ZooKeeper 只允许一个 Leader,其他节点作为 Follower 来对外提供服务。
以下是 ZooKeeper 的选举机制:
-
每个节点都可以投票。当一个节点发现当前的 Leader 宕机或失去联系时,它会发起选举过程。
-
节点在选举中分为两种角色:候选者和选民。一开始,每个节点都是候选者,并向其它节点发送投票请求。
-
节点需要收到集群中过半的选民投票才能成为 Leader。如果没有任何节点收到过半选票,那么重新发起选举,直到某个节点收到过半选票为止。
-
在选举中,每个节点会给投票请求中的候选者分配一个 ID,ID 最大的节点将成为 Leader。如果节点的 ID 相同,则比较其事先确定的选举顺序,例如 IP 地址或者启动时间等,来决定哪个节点成为 Leader。
-
当一个节点成为 Leader 后,它会向其它节点发送心跳信号,以维持自己的领导地位。
四、jvm 内存模型
👋 JVM 内存模型是 Java 虚拟机管理的内存结构,它定义了 Java 程序中对象如何在内存中分配、访问和操作的规范。
JVM 内存模型主要分为以下几个部分:
-
🧠 堆内存:用于存储对象实例,包括新生代、老年代等区域。
-
💻 栈内存:用于存储局部变量、方法参数、返回值等数据,以及程序执行过程中的方法调用栈信息。
-
🗃 方法区:用于存储类的元信息,如类名、方法名、字段名、访问修饰符等。
-
🔧 本地方法栈:用于支持本地方法调用。
-
🧬 常量池:用于存储编译时期生成的字面量和符号引用。
五、出现 full gc 定位问题的步骤
出现 Full GC 一般是由于堆内存中的对象无法被回收,导致堆内存空间不足而触发的。
定位 Full GC 问题的步骤:
🔍 1. 查看 GC 日志:GC 日志中会有 Full GC 的信息,通过分析 GC 日志可以找到哪些对象无法被回收、哪些对象占用了大量内存等信息。
🔍2. 使用内存分析工具:如 jmap、jstat、jvisualvm 等工具可以帮助我们查看堆内存的使用情况,找出哪些对象占用了大量内存。
🔍 3. 排查代码中可能存在的问题:如代码中是否存在内存泄漏、是否存在大对象、是否存在频繁创建对象等问题。
🔍 4. 调整 JVM 参数:如调整堆内存大小、调整 GC 策略、调整 Eden 区大小等参数,以减少 Full GC 的频率。
六、年轻代和老年代 gc 的区别,底层实现
👋 年轻代和老年代都是 JVM 堆内存中的一部分,但它们在 GC 的时候有一些不同的处理方式。
🔍 年轻代: 年轻代分为三个部分:Eden 区和两个 Survivor 区。大多数新创建的对象都会被分配到 Eden 区,在进行 Minor GC(新生代 GC)时,Eden 区中的对象会被标记并进行回收,而其中一部分存活下来的对象会被移动到 Survivor 区。当 Survivor 区满了之后,会触发一次 Minor GC,将其中存活下来的对象移动到另一个 Survivor 区。当某个对象经过多次 Minor GC 后仍然存活下来,那么它会被移到老年代。
🔍 老年代: 老年代主要用于存放大对象和长期存活的对象。在进行 Full GC(全局 GC)时,会对老年代中的对象进行回收。
🔍 底层实现: 年轻代和老年代的 GC 实现方式也不同。年轻代采用的是复制算法,即将存活的对象复制到 Survivor 区,并清除 Eden 区和上一个 Survivor 区中的对象。而老年代则采用标记-清除算法或标记-整理算法。其中,标记-清除算法会造成内存碎片,而标记-整理算法则需要对存活对象进行移动,会增加额外的复杂度。
七、priorityQueue 底层原理
👋 PriorityQueue 是 Java 中的一个基于优先级的队列,可以自动维护队列中元素的顺序,使得每次取出的元素都是当前队列中优先级最高的元素。
🔍 PriorityQueue 的底层实现是使用堆(Heap)数据结构。 PriorityQueue 内部维护了一个完全二叉树,即堆。这个堆有两个特性:
- 堆是一个完全二叉树;
- 每个节点的值都不小于(或不大于)其子节点的值,这个特性也被称为堆序性。
🔍 PriorityQueue 的插入操作会将新元素插入到堆的底部,然后通过堆的自我调整,保证堆序性的特性。当插入完新元素后,如果发现堆顶的元素的优先级比新元素低,那么就需要将新元素和堆顶的元素进行交换,以保证堆顶元素始终是队列中优先级最高的元素。
🔍 PriorityQueue 的删除操作会删除堆顶的元素,并将堆的最后一个元素放到堆顶,然后再通过堆的自我调整,保证堆序性的特性。这样可以保证每次取出的元素都是当前队列中优先级最高的元素。
#华为##华为机试##华为OD##华为OD机试#华为OD面试问题【有问必答】,整理面试全流程中的常见疑问,细节答疑 专栏涉及:od面试如何准备,od面试技巧,常见八股考点,必背细节 每天21:00~23:00 在线为你解答OD面试过程中的各种问题。