【Java核心能力】美团优选后端一面:Java 八股文相关内容

欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!

在我后台回复 「资料」 可领取编程高频电子书
在我后台回复「面试」可领取硬核面试笔记

文章导读地址:点击查看文章导读!

感谢你的关注!

美团优选后端一面:Java 八股文相关内容

美团优选后端一面中关于 Java 中的八股文主要考察了深拷贝、JVM、抽象类、MySQL 相关的内容,都是比较常见的八股文

回答抽象类和接口区别时可以结合设计模式的模板方法模式来进行介绍,讲解一下抽象类在这个设计模式中扮演什么职责,以及什么时候会使用接口、什么时候会使用抽象类!

深拷贝和浅拷贝?Java 里如何实现?

深拷贝和浅拷贝的区别为:

  • 深拷贝: 完全复制一个新的对象出来,对象中的属性如果是引用类型,就再创建一个该类型的变量赋值给拷贝对象
  • 浅拷贝: 在堆中创建一个新的对象,对象中的属性如果是引用类型,就直接将该属性的引用赋值给拷贝对象,那么此时原对象和拷贝对象共享这个引用类型的属性了

浅拷贝实现:

Java 中实现浅拷贝通过实现 Cloneable 接口来实现,从输出可以发现原 Student 对象和新 Student 对象中的引用属性 Address 的地址相同,说明是浅拷贝:

public class Student implements Cloneable {
    public Address address;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Student student = (Student) super.clone();
        student.setAddress((Address) student.getAddress().clone());
        return student;
    }

    @Override
    public String toString() {
        return "Student{" +
                "address=" + address +
                '}';
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Address getAddress() {
        return address;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student();
        student.setAddress(new Address());
        Student clone = (Student) student.clone();
        System.out.println(student);
        System.out.println(clone);
        System.out.println(student == clone);
        /**
         * 输出:
         * Student{address=com.example.springbootpro.DeepCopy.Address@6f539caf}
         * Student{address=com.example.springbootpro.DeepCopy.Address@6f539caf}
         */
    }
}

public class Address {}

深拷贝实现:

实现深拷贝的话,只需要修改 Student 的 clone() 方法,在该方法中对 Address 对象也进行克隆就好了,Address 对象也需要实现 Cloneable 接口

public class Student implements Cloneable {
    public Address address;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Student student = (Student) super.clone();
        student.setAddress((Address) student.getAddress().clone());
        return student;
    }

    @Override
    public String toString() {
        return "Student{" +
                "address=" + address +
                '}';
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Address getAddress() {
        return address;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student();
        student.setAddress(new Address());
        Student clone = (Student) student.clone();
        System.out.println(student);
        System.out.println(clone);
        System.out.println(student == clone);
        /**
         * 输出:
         * Student{address=com.example.springbootpro.DeepCopy.Address@6f539caf}
         * Student{address=com.example.springbootpro.DeepCopy.Address@79fc0f2f}
         * false
         */
    }
}

public class Address implements Cloneable{
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

JVM 的类加载过程?

采用双亲委派机制进行加载,JVM 在加载类的 class 文件时,Java虚拟机采用的是 双亲委派机制 ,即把请求交给父类加载器去加载

工作原理:

  1. 如果一个类加载器收到了类加载请求,他并不会自己先去加载,而是把这个请求委托给父类的加载器去执行
  2. 如果父类加载器也存在其父类加载器,则继续向上委托
  3. 如果父类加载器可以完成类加载任务,就成功返回;如果父类加载器无法完成类加载任务,则会由自家在其尝试自己去加载

优势:

  1. 避免类的重复加载
  2. 保护程序安全,防止核心API被篡改(例如,如果我们自定义一个java.lang.String类,然后我们去new String(),我们会发现创建的是jdk自带的String类,而不是我们自己创建的String类)

1702216110216

扩展:哪里打破了双亲委派机制?为什么要打破?

  • 在实际应用中,可能存在 JDK 的基础类需要调用用户代码,例如:SPI 就打破双亲委派模式(打破双亲委派意味着上级委托下级加载器去加载类)
    • 比如,数据库的驱动,Driver 接口定义在 JDK 中,但是其实现由各个数据库的服务上提供,由系统类加载器进行加载,此时就需要 启动类加载器 委托子类加载器去加载 Driver 接口的实现

JVM运行时数据区?

运行时数据区主要包含:方法区、堆、栈,如下图:

1702361654299

这里只要讲清楚各个区域存储哪些对象就好了,是 JVM 中比较基础的内容,这里就不写太详细了

抽象类和接口的区别?

抽象类和接口之间最明显的区别:抽象类可以存在普通成员函数(即可以存在实现了的方法),而接口中的方法是不能实现的

接口设计的目的: 是对类的行为进行约束,约束了行为的有无,但不对如何实现进行限制

抽象类的设计目的: 是代码复用,将不同类的相同行为抽象出来,抽象类不可以实例化

接下来举一个例子更好理解,在常用的设计模式 模板方法模式 中,就会用到抽象类,在抽象类中可以对外暴露出一个方法的调用入口,这个方法中规定了需要执行哪些步骤,之后再将这些步骤的实现延迟到子类,那么不同的子类就可以有不同的实现了

如下,假设有一个制作饮料的过程,那么对外暴露一个方法 prepareRecipe() 供外界调用,该方法规定了制作饮料需要哪些步骤,将这些步骤定义为抽象方法,交由子类来实现,那么不同子类(制作柠檬水、制作咖啡)就可以对这些步骤进行定制化操作了

public abstract class Beverage {
    // 模板方法,定义算法的框架
    public void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    abstract void brew();  // 由子类提供具体实现

    abstract void addCondiments();  // 由子类提供具体实现

    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}

class Tea extends Beverage {
    void brew() {
        System.out.println("Steeping the tea");
    }

    void addCondiments() {
        System.out.println("Adding lemon");
    }
}

class Coffee extends Beverage {
    void brew() {
        System.out.println("Dripping Coffee through filter");
    }

    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}

个人认为抽象类的功能是包含了接口的功能的,也就是抽象类功能更多,那么在使用时如何来选择呢,到底使用接口还是使用抽象类?

可以从这个方面进行考虑,Java 是 单继承、多实现 的,因此继承抽象类的话,只能继承 1 个,而实现接口可以实现多个,因此在工程设计中,如果只是需要规定一个实现类中需要实现哪些方法,这个功能对于接口和抽象类都具有,那么毫无疑问使用接口,这样就可以将继承的机会给留出来,毕竟很宝贵

而如果需要使用模板方法模式,也就是要定义一些方法的执行流程,并且将这些流程延迟到子类实现,那只能使用抽象类,因为接口并不具备该功能

我们现在一般使用自增作为主键,为什么要这样做?

这个要从 MySQL 如何存储来讲了,MySQL 的数据在底层是通过 B+ 树索引进行存储的,根据 主键值 来建立聚集索引

在向表里插入数据时,如果 主键自增 ,那么插入的每一条新数据都在上一条数据的后边,当达到页的最大填充因子,下一条记录就会被写入新的页中

如果不自增的话, 选择 UUID 作为主键 ,那么每一条数据插入的位置是随机的,因此新插入的数据很大概率会落在已有数据的中间位置,存在以下问题:

1、写入的目标页可能已经刷到磁盘上并从内存中删除,或者还没有被加载到内存中,那么 InnoDB 在插入之前,需要先将目标页读取到内存中。这会导致大量随机 IO

2、写入数据是乱序的,所以 InnoDB 会频繁执行页分裂操作

3、由于频繁的页分裂,页会变得稀疏并且被不规则地填充,最终数据会有碎片

关于乐观锁和悲观锁,MySQL 是怎么实现的?

MySQL 中的乐观锁通过 版本号 来实现,如下面 SQL

UPDATE table_name SET column1 = new_value, version = version + 1 WHERE id = some_id AND version = old_version;

如果 version 未被修改,则允许更新;如果 version 已被修改,则拒绝更新操作

乐观锁适用于并发冲突较少的场景,因为它避免了在读取数据时加锁,从而减少了锁的开销

但是在高并发环境中,如果冲突频繁,乐观锁可能导致大量的重试操作,从而影响性能。在这种情况下,可能需要考虑使用悲观锁或其他并发控制策略

悲观锁的话,MySQL 中有行锁、表锁来保证共享数据资源的并发访问安全,行级锁又分为了记录锁、间隙锁、临键锁、插入意向锁,各个锁之间的职责不同

扩展:可以了解一下 MySQL 中的行级锁

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

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

相关文章

基于分布式鲁棒性的多微网电氢混合储能容量优化配置——1

Optimal configuration of multi microgrid electric hydrogen hybrid energy storage capacity based on distributed robustness A B S T R A C T 储能与微电网相结合是解决分布式风能、太阳能资源不确定性、降低其对大电网安全稳定影响的重要技术路径。随着分布式风电和太阳…

Web自动化测试进阶:网页中难点之等待机制 —— 强制等待,隐式等待

为什么要添加等待 避免页面未渲染完成后操作,导致的报错 经常会遇到报错:selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":&q…

架构设计参考项目系列主题:新零售SaaS架构:客户管理系统架构设计

什么是客户管理系统? 客户管理系统,也称为CRM(Customer Relationship Management),主要目标是建立、发展和维护好客户关系。 CRM系统围绕客户全生命周期的管理,吸引和留存客户,实现缩短销售周期、降低销售成本、增加销售收入的目的,从而提高企业的盈利能力和竞争力。 …

java-spring 图灵 02 手写spring

01.idea中创建一个maven管理的空项目 02.模拟创建出spring容器类,这里叫wzpApplicationContext,创建的时候会自动加载配置类的数据 public class wzpApplicationContext {private Class configClass;public wzpApplicationContext(Class configClass) …

Selenium+TestNG学习笔记

------------------TestNG-------------------- 1.层级 suite -》test-》class-》method 建议层级 class对应一个测试用例,suite对应一个测试集 2. testNG中的PO模式 3.运行多个测试类的测试用例 通过suite来进行管理;suite在testNG中可以通过xml 来进行编写管理…

多媒体互动装置如何助力智慧城市展厅的信息化建设?

随着现代化科技技术的发展,智慧城市的建设概念与实施也日益成熟,其中智慧城市展厅便是用于展示智慧城市理念、技术和规划的重要平台,而应用在其中的多媒体互动装置,更是起着重要的作用,它们能够让观众更直观地了解和体…

浅述.Net中的Hash算法(顺带对称、非对称算法)

【写在前面】 对称加密算法(只有一个私钥,比如DES【不推荐】、AES); 非对称加密算法(公钥与私钥,比如RSA); Hash算法也称为散列函数算法,任意长度的数据都转换为固定长度的字符串&#xff08…

关闭 SPI 会导致 WRPERR 错误的问题分析

1. 引言 在 STM32 的应用中,SPI 算是用的比较多的外设了,也是单片机最常见外设之一。客户说它执行了关闭 SPI 的代码,竟然会导致 Flash 中的 WRPERR 标志置位,致使应用碰到一些问题。这就奇怪了,SPI 和内部 Flash 看起…

中仕公考:三支一扶期满后有编制吗?

三支一扶两年的期限到达之后,会自动获得编制吗? 完成三支一扶项目的服务期限后,参与人员必须通过正式的考试才能获得编制,而并不是期满后自动获得编制。但是,三支一扶服务期满人员在参加公务员考试中可依照其身份享受加分的优惠…

h5应用如何适配移动端(干货总结)

h5应用如何适配移动端总结 前言一、简单场景搭建二、从哪些方面进行适配?1.对html中的meta标签进行适配2.清除默认样式3.使用全局变量去控制采用css值4.绝对单位相对化 前端必备工具推荐网站(免费图床、API和ChatAI等实用工具): http://luckycola.com.cn/ 前言 H5应用的开发是…

基于springboot实现视频网站管理系统【项目源码+论文说明】计算机毕业设计

基于springboot实现视频网站管理系统演示 摘要 使用旧方法对视频信息进行系统化管理已经不再让人们信赖了,把现在的网络信息技术运用在视频信息的管理上面可以解决许多信息管理上面的难题,比如处理数据时间很长,数据存在错误不能及时纠正等问…

AndroidAutomotive模块介绍(一)整体介绍

前言 Android Automotive 是一个基本 Android 平台,可运行 IVI 系统中预安装的 Android 应用以及可选的第二方和第三方 Android 应用。 本系列文档将会系统的介绍 Android Automotive 的功能、架构、逻辑等。模块逻辑将从 应用api接口、系统服务、底层服务&#x…

2024.4.12每日一题

今天上午参加了蓝桥杯,只会暴力,还需努力学习 LeetCode 找到冠军 || 题目链接:2924. 找到冠军 II - 力扣(LeetCode) 题目描述 一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。每支队伍也是 有向无环图…

泰坦尼克号幸存者预测

泰坦尼克号幸存者预测 1、特征工程概述2、数据预处理3、特征选择与提取4、建模与预测 1、特征工程概述 在上篇 泰坦尼克号幸存者数据分析 中,我们对泰坦尼克号的幸存者做了数据分析,通过性别、年龄、船舱等级等不同维度对幸存者进行了分类统计&#xff0…

Traefik的前世今生

Traefik 是一款现代的反向代理和负载均衡器,它的设计专门针对微服务架构和容器技术,如 Docker 🐳 和 Kubernetes 🎯。自从其首次发布以来,Traefik 已经迅速成为云原生生态系统中不可或缺的一部分。在这篇文章中&#x…

上位机图像处理和嵌入式模块部署(qmacvisual缺失的颜色检测)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 在图像处理当中,对颜色的处理是非常重要的。当然,这要建立在拍摄图片是彩色图片的基础之上。工业上面,虽然是黑…

第三次作业

创建了一个教务管理系统的登录页面,其中包含左侧的图片以及右侧的表单容器,当鼠标悬停在表单容器上时,会稍微变大,并且图片容器会相应的缩小,是通过css的transition以及fiex属性实现。 表单容器包含用户名和密码的输入…

基于linux进一步理解核间通讯

芯片架构分为同构和异构: 如下图TC397: 如下图TDA4: 如下图STM32MP157: 非对称多处理结构(AMP): AMP 结构是指每个内核运行自己的 OS 或同一 OS 的独立实例&#

番茄 abogus rpc调用

声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!wx a15018601872 本文章…

生产者和消费者模型 | 阻塞队列 | 信号量 | 环形队列

文章目录 1.生产者和消费者模型2.生产者和消费者模型优点3.阻塞队列4.POSIX信号量5.基于环形队列的生产消费模型 本文完整的代码放在了这: Gitee链接 1.生产者和消费者模型 生产者和消费者模型,概括起来其实是一个321原则:3是:三…