【Java校招面试】实战面经(三)

news2024/10/5 22:21:30

目录

  • 前言
  • 一、简历中项目的难点及解决方案
  • 二、讲讲分布式锁的实现
  • 三、AQS(Abstract Queued Synchronizer)的原理
  • 四、ConcurrentHashMap的原理
  • 五、MySQL InnoDB存储引擎中的MVCC解决了什么问题,MVCC的实现原理
  • 六、平时怎么创建线程?为什么用线程池,线程池有什么好处?
  • 七、创建线程池需要的关键参数有哪些?
  • 八、线程池有哪几种任务拒绝策略?
  • 九、Redis是什么?Key的删除的原理
  • 十、如何保证Redis的高可用性?
  • 十一、SQL分组求和排序
  • 十二、CAS的原理,如何保证内存的可见性,会产生什么问题?
  • 十三、Java内存模型中的8个操作
  • 十四、有哪几种类加载器,双亲委派机制是什么?
  • 十五、什么情况下不应该建立索引?
  • 十六、RPC
  • 后记


前言

“实战面经”是本专栏的第二个部分,本篇博文是第二篇博文,如有需要,可:

  1. 点击这里,返回本专栏的索引文章
  2. 点击这里,返回上一篇《【Java校招面试】实战面经(二)》

一、简历中项目的难点及解决方案

我在Artanis那个工程中遇到过一个Bug,就是DAO里的方法调用之后都没有效果,而且Service里调用了DAO之后的流程都不会执行。那时候不会用log4J这类的日志工具,然后就通过插桩缩小范围到sessionFactory.getCurrentSession()这个函数,后来仔细翻了翻tomcat的日志,发现了报错信息,按图索骥,查到Hibernate的getCurrentSession这个函数必须在事务里调用,否则就需要用createSession,于是把这个DAO切入到事务切面里,问题得以解决。之后也立即学习了Log4J的用法,在后面的工程里把日志打好。

二、讲讲分布式锁的实现

分布式锁的实现可以通过数据库RedisZooKeeper

1. 数据库: 创建一个表,通过唯一性约束来确保每次只有一个线程可以获得锁。
缺点: 没有锁失效机制

2. Redis: Redis方法的主要问题是原子性问题,可以通过Lua脚本来实现。如果使用Spring的RedisTemplate可以调用SetIfAbsent函数的包含过期时间的那个重载。
缺点: 没有解决可重入的问题

3. ZooKeeper: 不太熟悉ZooKeeper

4. Redis的实现:
  1) 加锁:

	public boolean lock(String key, String value, long expire) {
		Object result = redisTemplate.opsForValue().setIfAbsent(key, value, expire, TimeUnit.SECONDS);
		return "OK".equals(result);
	}

  2) 解锁:

    public boolean unLock(List<String> keys, String... args) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del',      KEYS[1]) else return 0 end";
        Object result = redisTemplate.execute(script, keys, args);
        return "OK".equals(result);
    }

三、AQS(Abstract Queued Synchronizer)的原理

AQS是一个基于队列的用于实现线程同步的类的框架,用一个int类型的变量state表示同步状态,并提供了一系列的CAS操作来管理这个同步状态。ReentrantLock就是基于AQS实现的,用法是通过继承AQS实现其模版方法,然后将子类作为同步组件的内部类。

AQS定义了两种资源共享方式: 独占(Exclusive)共享(Share)


四、ConcurrentHashMap的原理

  • 锁分段技术: 首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

  • HashtableSynchronizedMap中采用的锁机制是一次锁住整个hash表,从而在同一时刻只能由一个线程对其进行操作。而ConcurrentHashMap中则是一次锁住一个桶,所以并发效率会有指数级的提升。


五、MySQL InnoDB存储引擎中的MVCC解决了什么问题,MVCC的实现原理

在这里插入图片描述

MVCC(Mutil-Version Concurrency Control),就是多版本并发控制。MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问。Mysql的InnoDB引擎中,在RC和RR这两种隔离级别下,通过Undo日志实现当前读。这样就实现了读-写的并发执行,提升了系统的性能。


六、平时怎么创建线程?为什么用线程池,线程池有什么好处?

通过线程池来创建线程。使用线程池可以:

1. 复用线程,避免大量创建销毁线程造成的CPU资源浪费。

2. 管理线程,便于监控线程的状态。


七、创建线程池需要的关键参数有哪些?

1. corePoolSize: 核心线程数
2. maxPoolSize: 最大线程数
3. workQueue: 等待队列
4. handler: 线程数大于maxPoolSize时需要执行的策略


八、线程池有哪几种任务拒绝策略?

1. AbortPolicy: 直接抛出异常,默认策略;
2. CallerRunsPolicy: 用调用者所在的线程来执行;
3. DiscardOldestPolicy: 丢弃队列中最靠前的任务,并执行当前任务;
4. DiscardPolicy: 直接丢弃任务。


九、Redis是什么?Key的删除的原理

1. Redis(REmote DIctionary Server),字面意思是远程字典服务器,它提供了字符串、哈希表、集合、排序集合和列表这5种数据类型供使用。

2. Key可以通过手动删除,一般是设定一个过期时间,过期策略定时删除定期删除惰性删除,当内存不足以分配给新创建的Key时,会触发淘汰策略,包括:
  1) 直接抛出异常;
  2) 对全部键进行LRU;
  3) 对设置了过期时间的键进行LRU
  4) 对全部键进行随机删除
  5) 对设置了过期时间的键进行随即删除
  6) 对设置了过期时间的键选择最早过期的删除


十、如何保证Redis的高可用性?

考虑使用Redis集群,见《实战面经(二)》第四题


十一、SQL分组求和排序

Artanis日报系统 为例,求每个组的成员数量,按从小到大排序

SELECT
    GroupId AS `group_id`,
    count(*) AS `member_count`
FROM
    member
GROUP BY
    GroupId
ORDER BY
    member_count ASC;

十二、CAS的原理,如何保证内存的可见性,会产生什么问题?

1. CAS(Compare And Swap),在对一个对象赋予新值之前,先比较它现在的值和执行CAS之前的值,如果相同,就认为没有其他的线程改过它的值,就给它赋予新值,否则重试直到修改成功;

2. Atomic包下的原子操作类的内存可见性是通过volatile关键字实现的(见面经总结2-9);

3. CAS会产生ABA问题和自旋消耗资源的问题:

  1) ABA问题: 即线程1把一个对象的值由A改为B,然后又改为A,这样线程2 会认为这个对象的值没有变,就会执行CAS,这在一定情境下会造成问题。
  解决方案: 用版本号机制实现乐观锁

  2) 自旋消耗资源问题: 自旋次数过多会消耗大量的CPU资源。
  解决方案: 设置最大的自选次数,超过这个次数就放弃修改。


十三、Java内存模型中的8个操作

1. lock: 作用于主内存,它把一个变量标记为一条线程独占状态;

2. read: 作用于主内存,它把变量值从主内存传送到线程的工作内存中,以便随后的load动作使用;

3. load: 作用于工作内存,它把read操作的值放入工作内存中的变量副本中;

4. use: 作用于工作内存,它把工作内存中的值传递给执行引擎,每当虚拟机遇到一个需要使用这个变量的指令时候,将会执行这个动作;

5. assign: 作用于工作内存,它把从执行引擎获取的值赋值给工作内存中的变量,每当虚拟机遇到一个给变量赋值的指令时候,执行该操作;

6. store: 作用于工作内存,它把工作内存中的一个变量传送给主内存中,以备随后的write操作使用;

7. write: 作用于主内存,它把store传送值放到主内存中的变量中。

8. unlock: 作用于主内存,它将一个处于锁定状态的变量释放出来,释放后的变量才能够被其他线程锁定;
在这里插入图片描述


十四、有哪几种类加载器,双亲委派机制是什么?

1. 类加载器包括:
  1) Bootstrap ClassLoader
  2) Ext ClassLoader
  3) App ClassLoader

分别用于加载Java核心库(如java.lang)、ext文件夹下的类和应用程序的类。

2. 双亲委派机制: 即一个类加载器在加载类时先判断这个类是否已经加载了,如果没有就调用父加载器去加载。双亲委派机制解决了类加载的安全性问题,比如我们自己写一个恶意的java.lang.Integer类,让App ClassLoader来加载,它会调用Ext ClassLoader去加载,Ext又会调用Bootstrap,Bootstrap发现这个类已经加载过了,就不会再记载这个恶意的了。


十五、什么情况下不应该建立索引?

1) 数据量小的表不需要建立索引,建立会增加额外的索引开销;
2) 频繁变更的字段上不应该建立索引,会增加索引的维护成本。


十六、RPC

在这里插入图片描述

远程过程调用(RPC,Remote Procedure Call) 是一种允许在一台计算机(客户端)上调用另一台计算机(服务器)上的过程或方法的技术。RPC 使用请求-响应模式,客户端发起请求并等待响应。服务器接收请求,处理请求,返回结果给客户端。

在 Java 中,可以使用RMI(Remote Method Invocation)实现RPC。以下是一个简单的示例:
1. 定义接口: 创建一个要在远程服务器上执行的接口。
Calculator.java:

	import java.rmi.Remote;
	import java.rmi.RemoteException;
	
	public interface Calculator extends Remote {
	    int add(int a, int b) throws RemoteException;
	}

2. 实现接口: 为接口创建一个实现类。
CalculatorImpl.java:

	import java.rmi.RemoteException;
	import java.rmi.server.UnicastRemoteObject;
	
	public class CalculatorImpl extends UnicastRemoteObject implements Calculator {
	    public CalculatorImpl() throws RemoteException {
	        super();
	    }
	
	    public int add(int a, int b) {
	        return a + b;
	    }
	}

3. 服务端: 创建一个 RMI 服务器,用于注册远程对象。
Server.java:

	import java.rmi.registry.LocateRegistry;
	import java.rmi.registry.Registry;
	
	public class Server {
	    public static void main(String[] args) {
	        try {
	            Calculator calculator = new CalculatorImpl();
	            Registry registry = LocateRegistry.createRegistry(1099);
	            registry.rebind("Calculator", calculator);
	            System.out.println("Calculator Server is ready.");
	        } catch (Exception e) {
	            System.err.println("Server exception: " + e.toString());
	            e.printStackTrace();
	        }
	    }
	}

4. 客户端: 创建一个客户端,用于从远程获取对象并调用方法。
Client.java:

	import java.rmi.registry.LocateRegistry;
	import java.rmi.registry.Registry;
	
	public class Client {
	    public static void main(String[] args) {
	        try {
	            Registry registry = LocateRegistry.getRegistry("localhost", 1099);
	            Calculator calculator = (Calculator) registry.lookup("Calculator");
	            System.out.println("1 + 2 = " + calculator.add(1, 2));
	        } catch (Exception e) {
	            System.err.println("Client exception: " + e.toString());
	            e.printStackTrace();
	        }
	    }
	}

5. 要运行此示例,请进行以下操作:

  1) 编译所有 .java 文件。
  2) 运行 Server 类,以启动 RMI 服务器。
  3) 在另一个命令窗口中,运行 Client 类。你应该会看到输出:“1 + 2 = 3”。

这是实现 Java RPC 的一个基本示例。实际应用场景可能更加复杂,可以考虑使用gRPC等现代框架。


后记

同样,有部分题目链接到了前面的面经中,这部分重复考的题目也应该多加重视。

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

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

相关文章

Red Hat Enterprise Linux (RHEL) 8.8 正式版发布

红帽企业 Linux 8.8 发布 Red Hat Enterprise Linux (RHEL) 8.8 (x86_64, aarch64) Release 请访问原文链接&#xff1a;https://sysin.org/blog/rhel-8/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 2023年 5月 16日&…

Java学习路线(5)——数组

一、数组的概念 数组是用来存储一系列同类型数据的内存区域。 二、存储数据 1、静态初始化数组 作用&#xff1a; 定义数组时直接赋值。 格式&#xff1a; 【数据类型[] 变量名 new 数据类型[]{值1,值2…,值n}】 示例&#xff1a; double[] height {172.5,170.1,145.1,152.5,…

java常用工具之Scanner类

目录 简介一、扫描控制台输入1.1nextLine1.2nextInt1.3其他方法 二、扫描文件三、查找匹配项四、小结 简介 Java 的 Scanner 类是一个方便在控制台扫描用户输入的工具类&#xff0c;虽然它也可以扫描文件内容&#xff0c;但我们通常更喜欢它扮演前面的角色&#xff0c;因为扫描…

Flink第五章:处理函数

系列文章目录 Flink第一章:环境搭建 Flink第二章:基本操作. Flink第三章:基本操作(二) Flink第四章:水位线和窗口 Flink第五章:处理函数 文章目录 系列文章目录前言一、基本处理函数(ProcessFunction)二、按键分区处理函数&#xff08;KeyedProcessFunction&#xff09;1.处理…

【Linux进阶之路】基本权限的理解

文章目录 一.用户1.分类2.su3.su-4.sudo 二.文件1.文件分类2.文件权限3.文件权限的身份4.chmod——改写文件权限第一种方式第二种方式 5.chown——改写文件拥有者身份6.chgrp ——改写文件所属组身份7.umask ——设置权限掩码8.目录权限9.粘滞位——特殊的可执行权限 一.用户 …

关于Markdown文件的处理【笔记】

关于Markdown文件的处理【笔记】 前言推荐关于Markdown文件的处理一、md文件转word文档1 准备2 打开3 转为word文档4 导出结果5 打开 二、word文档转md文件1 准备2 导入3 打开4 显示图片5 打开 三、导入到CSDN中1 选择导入2 查看 四、导入设置1 前言2 导入设置3 修改配置 最后 …

ES6之生成器

文章目录 前言一、生成器是什么&#xff1f;二、生成器总结 前言 生成器 一、生成器是什么&#xff1f; 生成器就是一个特殊的函数&#xff0c;实现异步编程。格式function *名称(){...} (这个*靠近function写&#xff0c;靠近名称写&#xff0c;或者两边空格都不靠近均正确)…

[比赛简介]Parkinson‘s Freezing of Gait Prediction

比赛链接&#xff1a;https://www.kaggle.com/competitions/tlvmc-parkinsons-freezing-gait-prediction 比赛简介 本次比赛的目标是检测步态冻结&#xff08;FOG&#xff09;&#xff0c;这是一种使人衰弱的症状&#xff0c;困扰着许多帕金森病患者。您将开发一个机器学习…

YOLO V3 SPP ultralytics 第三节:关于yolo 中cfg的网络配置信息和读取cfg配置文件

目录 1. 介绍 2. 关于yolo的cfg网络配置文件 2.1 关于卷积层 2.2 关于池化层 2.3 关于捷径分支shortcut 2.4 关于route 层 2.5 关于上采样层 2.6 关于yolo层 3. 解析cfg 文件 4. 代码 1. 介绍 根据 第二节 的步骤&#xff0c;生成了属于自己的 my_yolov3.cfg 配置…

Python 墨西哥湾流(gulf stream)可视化

背景介绍 墨西哥湾流和黑潮分别是北半球两支强大的西边界流&#xff0c;墨西哥湾流的流速还要强于黑潮&#xff0c;也是温盐环流的重要组成部分。 引入涡度的概念&#xff0c;将涡度分为两个部分&#xff1a; 1、行星涡度&#xff0c;记为 f f f&#xff0c;与地球自转有关…

【软考数据库】第十四章 数据库主流应用技术

目录 14.1 分布式数据库 14.2 Web与数据库 14.3 XML与数据库 14.4 面向对象数据库 14.5 大数据与数据库 14.6 NewSQL 前言&#xff1a; 笔记来自《文老师软考数据库》教材精讲&#xff0c;精讲视频在b站&#xff0c;某宝都可以找到&#xff0c;个人感觉通俗易懂。 14.1 …

Springcloud1---->openFeign

目录 简介快速入门导入依赖开启Feign配置Feign客户端接口Feign使用小结feign feign配置负载均衡feign配置Hystix支持 简介 Feign可以把Rest的请求进行隐藏&#xff0c;伪装成类似SpringMVC的Controller一样。你不用再自己拼接url&#xff0c;拼接参数等等操作&#xff0c;一切…

WebSocket 详解,以及用QWebSocket 实现服务端和客户端(含代码例子)

目录 1、WebSocket 诞生背景 2、WebSocket的特点&#xff1a; 3、 WebSocket 简介 4、WebSocket 优点 5、QWebSocket通讯—客户端&#xff1a; 6、QWebSocket通讯—服务端&#xff1a; 1、WebSocket 诞生背景 早期&#xff0c;很多网站为了实现推送技术&#xff0c;所用的技术都…

初始Linux发展

目录 前言 Linux概念&#xff1a; 一.Linux发展历史 二.Linux的发展现状 三.发行版本 四.Linux 环境的搭建方式 主要有三种 : 4.6下载方式&#xff1a; 五.XShell软件 前言 Linux概念&#xff1a; Linux&#xff0c;全称GNU/Linux&#xff0c;是一套免费使用和自由传播的…

python中的对象和变量的关系

这里写目录标题 对象简介对象的结构变量和对象 对象简介 Python是一门面向对象的编程语言&#xff01; 一切皆对象&#xff01; 程序运行当中&#xff0c;所有的数据都是存储到内存当中然后再运行的&#xff01; 对象就是内存中专门用来存储指定数据的一块区域 对象实际上就是…

《计算机网络—自顶向下方法》 Wireshark实验(九):DHCP 协议分析

DHCP&#xff08;Dynamic Host configuration protocol&#xff09;动态主机配置协议&#xff0c;它可以为客户机自动分配 IP 地址、子网掩码以及缺省网关、DNS 服务器的 IP 地址等 TCP/IP 参数&#xff0c; 简单来说&#xff0c;就是在 DHCP 服务器上有一个数据库&#xff0c;…

Go开发PaaS平台核心功能

Go开发PaaS平台核心功能 1 云原生PaaS平台介绍 随着云计算的发展&#xff0c;越来越多的企业逐步的把IT资源迁移到云上。PaaS平台作为基础设施基座&#xff0c;可以帮助企业快速构建功能丰富的容器云平台&#xff0c;提升交付效率&#xff0c;降低成本。 [1.1] 云原生平台使…

【SpringMVC框架】--01.简介、入门、@RequestMapping、获取请求参数、域对象共享数据、视图、RestFul

文章目录 SpringMVC1.简介1.1 什么是MVC1.2 什么是SpringMVC1.3 SpringMVC的特点 2.编写HelloWorld2.1 创建maven工程2.2 配置web.xml2.3 创建请求控制器2.4 创建springMVC的配置文件2.5测试HelloWorld2.6总结 3.RequestMapping注解3.1 RequestMapping注解的功能3.2 RequestMap…

Java自定义类:打造属于自己的编程世界

&#x1f9d1;‍&#x1f4bb;CSDN主页&#xff1a;夏志121的主页 &#x1f4cb;专栏地址&#xff1a;Java核心技术专栏 目录 一、自定义类示例 二、隐式参数与显式参数 三、封装的优点 自定义类是Java中最基本、也是最重要的组成部分之一&#xff0c;使用者可以根据需求创建…

【Go微服务开发】gin+grpc+etcd 重构 grpc-todolist 项目

写在前面 最近稍微重构了之前写的 grpc-todolist 模块 项目地址&#xff1a;https://github.com/CocaineCong/grpc-todoList 1. 项目结构改变 与之前的目录有很大的区别 1.1 grpc_todolist 项目总体 1.1.1 改变前 grpc-todolist/ ├── api-gatway // 网关模块 ├── ta…