Java面试题(一)——MySQL索引、JVM内存模型、JDBC

1、mysql使用innodb引擎,请简述mysql索引的最左前缀如何优化 order by 语句?

1.1、核心回答

  1. 首先要对sql进行分析检查必要的查询字段,过滤字段,排序字段是否按顺序创建好了索引

  2. 如果字段不在索引中可能会产生回表操作会导致filesort,降低性能

  3. 一定要有过滤字段不然不能使用索引

  4. 排序字段和索引顺序不一致会导致filesort,降低性能

  5. 多个字段排序时如果方向不一致也会导致filesort,降低性能

  6. 使用explain观察查询类型和索引利用情况

  7. 尽可能减少不必要的filesort

1.2、数据准备

向表中插入50W条数据

在做优化之前,要准备大量数据。接下来创建两张表,并往员工表里插入50W数据,部门表中插入1W条数据。

怎么快速插入50w条数据呢? 存储过程

怎么保证插入的数据不重复?函数

部门表:

  • id:自增长

  • deptName:随机字符串,允许重复

  • address:随机字符串,允许重复

  • CEO:1-50w之间的任意数字

员工表:

  • id:自增长

  • empno:可以使用随机数字,或者从1开始的自增数字,不允许重复

  • name:随机生成,允许姓名重复

  • age:区间随机数

  • deptId:1-1w之间随机数

总结:需要产生随机字符串和区间随机数的函数。

创建表

CREATE TABLE `dept` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`deptName` VARCHAR(30) DEFAULT NULL,
	`address` VARCHAR(40) DEFAULT NULL,
	ceo INT NULL ,
	PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1;

CREATE TABLE `emp` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`empno` INT NOT NULL ,
	`name` VARCHAR(20) DEFAULT NULL,
	`age` INT(3) DEFAULT NULL,
	`deptId` INT(11) DEFAULT NULL,
	PRIMARY KEY (`id`)
	#CONSTRAINT `fk_dept_id` FOREIGN KEY (`deptId`) REFERENCES `t_dept` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1;

创建函数

-- 查看mysql是否允许创建函数:
SHOW VARIABLES LIKE 'log_bin_trust_function_creators';
-- 命令开启:允许创建函数设置:(global-所有session都生效)
SET GLOBAL log_bin_trust_function_creators=1; 
-- 随机产生字符串
DELIMITER $$
CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255)
BEGIN    
	DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
	DECLARE return_str VARCHAR(255) DEFAULT '';
	DECLARE i INT DEFAULT 0;
	WHILE i < n DO  
		SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));  
		SET i = i + 1;
	END WHILE;
	RETURN return_str;
END $$

-- 假如要删除
-- drop function rand_string;
-- 用于随机产生区间数字
DELIMITER $$
CREATE FUNCTION rand_num (from_num INT ,to_num INT) RETURNS INT(11)
BEGIN   
 DECLARE i INT DEFAULT 0;  
 SET i = FLOOR(from_num +RAND()*(to_num -from_num+1));
RETURN i;  
END$$

-- 假如要删除
-- drop function rand_num;

 创建存储过程

-- 插入员工数据
DELIMITER $$
CREATE PROCEDURE  insert_emp(START INT, max_num INT)
BEGIN  
	DECLARE i INT DEFAULT 0;   
	#set autocommit =0 把autocommit设置成0  
	SET autocommit = 0;    
	REPEAT  
		SET i = i + 1;  
		INSERT INTO emp (empno, NAME, age, deptid ) VALUES ((START+i) ,rand_string(6), rand_num(30,50), rand_num(1,10000));  
		UNTIL i = max_num  
	END REPEAT;  
	COMMIT;  
END$$
 
-- 删除
-- DELIMITER ;
-- drop PROCEDURE insert_emp;
-- 插入部门数据
DELIMITER $$
CREATE PROCEDURE insert_dept(max_num INT)
BEGIN  
	DECLARE i INT DEFAULT 0;   
	SET autocommit = 0;    
	REPEAT  
		SET i = i + 1;  
		INSERT INTO dept ( deptname,address,ceo ) VALUES (rand_string(8),rand_string(10),rand_num(1,500000));  
		UNTIL i = max_num  
	END REPEAT;  
	COMMIT;  
END$$
 
-- 删除
-- DELIMITER ;
-- drop PROCEDURE insert_dept;

 调用存储过程

-- 执行存储过程,往dept表添加1万条数据
CALL insert_dept(10000); 

-- 执行存储过程,往emp表添加50万条数据,编号从100000开始
CALL insert_emp(100000,500000); 

批量删除表索引 

-- 批量删除某个表上的所有索引
DELIMITER $$
CREATE PROCEDURE `proc_drop_index`(dbname VARCHAR(200),tablename VARCHAR(200))
BEGIN
	DECLARE done INT DEFAULT 0;
	DECLARE ct INT DEFAULT 0;
	DECLARE _index VARCHAR(200) DEFAULT '';
	DECLARE _cur CURSOR FOR SELECT index_name FROM information_schema.STATISTICS WHERE table_schema=dbname AND table_name=tablename AND seq_in_index=1 AND index_name <>'PRIMARY'  ;
	DECLARE CONTINUE HANDLER FOR NOT FOUND set done=2 ;      
	OPEN _cur;
		FETCH _cur INTO _index;
		WHILE  _index<>'' DO 
			SET @str = CONCAT("drop index ",_index," on ",tablename ); 
			PREPARE sql_str FROM @str ;
			EXECUTE sql_str;
			DEALLOCATE PREPARE sql_str;
			SET _index=''; 
			FETCH _cur INTO _index; 
		END WHILE;
	CLOSE _cur;
END$$

1.3、最左前缀法则示例 

假设index(a,b,c)

Where语句索引是否被使用
where a = 3Y,使用到a
where a = 3 and b = 5Y,使用到a,b
where a = 3 and b = 5 and c = 4Y,使用到a,b,c
where b = 3 或者 where b = 3 and c = 4 或者 where c = 4N
where a = 3 and c = 5使用到a, 但是c不可以,b中间断了
where a = 3 and b > 4 and c = 5使用到a和b, c不能用在范围之后,b断了
where a is null and b is not nullis null 支持索引 但是is not null 不支持,所以 a 可以使用索引,但是 b不一定能用上索引(8.0)
where a <> 3不能使用索引
where abs(a) =3不能使用 索引
where a = 3 and b like 'kk%' and c = 4Y,使用到a,b,c
where a = 3 and b like '%kk' and c = 4Y,只用到a
where a = 3 and b like '%kk%' and c = 4Y,只用到a
where a = 3 and b like 'k%kk%' and c = 4Y,使用到a,b,c

一般建议:

Ø 对于单键索引,尽量选择过滤性更好的索引(例如:手机号,邮件,身份证)

Ø 在选择组合索引的时候,过滤性最好的字段在索引字段顺序中,位置越靠前越好。

Ø 选择组合索引时,尽量包含where中更多字段的索引

Ø 组合索引出现范围查询时,尽量把这个字段放在索引次序的最后面

Ø 尽量避免造成索引失效的情况

1.4、实验测试

-- 创建索引
CREATE INDEX idx_age_deptid_name ON emp (age,deptid,NAME);

1.4.1、无过滤不索引

EXPLAIN SELECT * FROM emp ORDER BY age,deptid; 
EXPLAIN SELECT * FROM emp ORDER BY age,deptid LIMIT 10; 

-- 增加过滤条件,使用上索引了。
EXPLAIN SELECT age FROM emp where age>1000 ORDER BY age,deptid,name;

1.4.2、查询条件和筛选条件 

-- const查询排序后回表操作,不会filesort
EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY age,deptid,NAME; 

-- range查询,Using index condition 没有完全使用索引
EXPLAIN SELECT * FROM emp WHERE age>45 ORDER BY age,deptid,NAME;
-- range查询,Using where; Using index 完全使用索引
EXPLAIN SELECT age FROM emp WHERE age>45 ORDER BY age,deptid,NAME;

1.4.3、顺序错 filesort 

-- 正常情况
EXPLAIN SELECT age FROM emp WHERE age>45 ORDER BY age,deptid,NAME;
-- order by顺序变化会导致filesort
EXPLAIN SELECT age FROM emp WHERE age>45 ORDER BY deptid,age,NAME;

1.4.4、order by非最左 filesort  

EXPLAIN SELECT age FROM emp WHERE age>45 ORDER BY deptid,NAME;

1.4.5、 方向反 必排序

-- 8.0为Backward index scan 倒序索引
EXPLAIN SELECT age FROM emp WHERE age>45 ORDER BY age desc,deptid desc,NAME desc

-- 方向反 产生filesort
EXPLAIN SELECT age FROM emp WHERE age>45 ORDER BY age desc,deptid desc,NAME asc;

2、JVM 内存模型中,为什么要区分新生代和年老代,对于新生代,为什么又要区分eden 区survial区?

 2.1、核心回答

  1. 主流垃圾回收器 cms、g1都使用了分代收集算法

  2. 正常系统运行时会有海量临时对象产生,这些对象短期内大部分就会失效,对于这些对象我们把他们临时放到新生代

  3. 新生代满了之后需要清理垃圾对象,我们会把有效对象复制到老年代,以便后续继续使用

  4. 为了更有效的区分哪些对象应该被复制到老年代,所以在新生代划分出了eden去和s0,s1区域

  5. 细化后的新生代内部被再次划分以便保证高速读写同时内存连续

    1. 新对象会被保存到eden区(开始是空的所以内存连续),eden区满了会把有效对象复制到s0(s0也是空的所以也是连续空间)

    2. 清空eden区(再次写入时又是连续空间)

    3. s0 和 s1 在命名上互换 原来的s1等待写入(空的)

    4. eden区再次满了,重复上面步骤

  6. eden区通过复制/清除算法保证了读写连续性(因为新生代的对象产生和销毁非常频繁,所以才采用了清空的方式)

3、典型的JDBC程序按什么顺序编写?

3.1、核心回答

  1. 注册 JDBC Driver
  2. 获得与数据库的物理连接
  3. 创建不同类型的 Statement
  4. 执行SQL命令
  5. 如果有结果集处理结果集
  6. 释放资源

4、请编写一个Java类Testjava,求出100以内既能被2 除又能被3 除的数,并输出到控制台上

public class Test01 {
    public static void main(String[] args) {
        for (int i = 1; i <= 100; i++) {

            if (i % 2 == 0 && i % 3 ==0){

                System.out.println(i);
            }
        }
    }
}

5、A 系统远程调用 B 系统的接口,A 系统在完成调用之后,需要更新A 系统本地表

5.1、常见的远程调用有哪几种?

核心回答

  1. 自定义协议实现C/S RPC调用(实现复杂,需解决的问题多)

  2. UDP广播类型(常见用于即时通讯类,速度快,但需要二次确认)

  3. 目前主流的基于http协议调用(Restful风格的api,springcloud微服务调用使用的就是http)

  4. dubbo协议(阿里出品,长连接,二进制封装数据,性能较高)

  5. soap协议(古老的webservice系列框架,基于xml实现数据封装,http协议传输)

  6. 异步响应式(WebFlux+Spring Data Reactive)

  7. 服务器推(不主动调用,常见系统通知类) 

关键点:

  1. 网络协议与封装,所有的网络请求都是基于TCP或UDP协议的

  2. 常用框架

  3. 长短连接(复用)

5.2、对于有这些外部衔接的方法需要注意哪些问题?请写出注意问题及伪代码

1、写好接口文档,方便后续维护和团队协作

2、统一化的报文结构

3、标准化的服务状态码

status_code 200;//请求成功

4、统一化请求日志记录,及异常记录

GlobalExceptionHandler...

logger.error("服务异常",exception);

5、当请求延迟过高,可以快速失败

6、重试机制

// 服务列表
serverList = {ser1,ser2,ser3}
retrycount = 0;
retrymax=10;
maxrequesttime = 200ms;
getxxoo(){

    try{
    // 尝试请求数据
    calldata(serverList)

    }catch (请求失败 500类异常 || 请求超时 calldata的网络请求方法中){

 //   拦截器记录日志
    serverList.remove(刚才请求的服务器)
 //   重试次数过多
    if (retrycount == retrymax)
    return "当前访问不可用稍后再试"
    
    retrycount ++;
    递归调用本方法

    }
}

7、事务问题,可回滚

getData(){
        分布式事务开启

        get1();
        get2();
        get3();
        事务结束
        要么全成功 要么全失败
        修改数据时使用 tryModify() 临时保存数据或通过Seata类似的框架实现
}

8、数据一致性问题

有并发修改数据时,如果需要保证一致性,需要使用分布式锁
修改方法
modifyxx(){
// 尝试加锁
boolean haslock = tryLock(id)

if(haslock){
httppost(url,data)
releaseLock(id)
}
else{

// 提示用户一会再试试
// 尝试再次获取锁
}

}

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

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

相关文章

Linux环境下配置HTTP代理服务器教程

大家好&#xff0c;我是你们可爱的Linux小助手&#xff01;今天&#xff0c;我将带你们一起探索如何在Linux环境下配置一个HTTP代理服务器。请注意&#xff0c;这不是一次火箭科学的实验&#xff0c;而是一次简单而有趣的冒险。 首先&#xff0c;我们需要明确什么是HTTP代理服…

TOP100 二叉树(三)

11.114. 二叉树展开为链表 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺…

IoC原理

Spring框架的IOC是基于Java反射机制实现的&#xff0c;那具体怎么实现的&#xff0c;下面研究一下 反射 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法…

JenkinsGitLab完成自动化构建部署

关于GitLab安装:GitLab安装-CSDN博客 Docker中安装GitLab:Docker下安装GitLab-CSDN博客 安装JenKins Jenkins官网:Jenkins 中文版:Jenkins 安装时候中文页面的war包下不来 在英文页面 记得装JDK8以上 JenKins使用java写的 运行JenKins需要JDK环境 我这里已经装好了 将下…

网神 SecGate 3600 防火墙 route_ispinfo_import_save 文件上传漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

问题:重热现象可使多级汽轮机的理想焓降增加,重热系数越大,多级汽轮机的内效率就越低。 #学习方法#微信#媒体

问题&#xff1a;重热现象可使多级汽轮机的理想焓降增加&#xff0c;重热系数越大&#xff0c;多级汽轮机的内效率就越低。 参考答案如图所示

代码随想录算法训练营第二十五天 |216.组合总和III,17.电话号码的字母组合(已补充)

剪枝操作讲解&#xff1a;&#xff08;已观看&#xff09; 带你学透回溯算法-组合问题的剪枝操作&#xff08;对应力扣题目&#xff1a;77.组合&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩_bilibili 216.组合总和III&#xff08;已观看&#xff09; 1、题目链接&#xf…

Pinia介绍和使用

1. pinia是什么 Pinia 是一个基于 Vue.js 的状态管理库&#xff0c;用于管理应用程序的数据。它提供了一种简单、直观且可扩展的方式来组织和访问应用程序的状态&#xff0c;下面是详细介绍 基于 Vue 3&#xff1a;Pinia 是专门为 Vue 3 开发的状态管理库&#xff0c;充分利用…

推理系统学习笔记

一些学习资料 最近对MLsys比较感兴趣&#xff0c;遂找些资料开始学习一下 https://fazzie-key.cool/2023/02/21/MLsys/https://qiankunli.github.io/2023/12/16/llm_inference.htmlhttps://dlsyscourse.orghttps://github.com/chenzomi12/DeepLearningSystem/tree/main/04Infe…

算法——前缀和算法

1. 什么是前缀和算法 前缀和算法&#xff08;Prefix Sum&#xff09;是一种用于快速计算数组元素之和的技术。它通过预先计算数组中每个位置前所有元素的累加和&#xff0c;将这些部分和存储在一个新的数组中&#xff0c;从而在需要计算某个区间的和时&#xff0c;可以通过简单…

《Git 简易速速上手小册》第3章:分支管理(2024 最新版)

文章目录 3.1 创建与合并分支3.1.1 基础知识讲解3.1.2 重点案例&#xff1a;为 Python 项目添加新功能3.1.3 拓展案例 1&#xff1a;使用 Pull Requests (PRs) 在团队中合作3.1.4 拓展案例 2&#xff1a;解决合并冲突 3.2 分支策略的最佳实践3.2.1 基础知识讲解3.2.2 重点案例&…

【动态规划】【前缀和】【数学】2338. 统计理想数组的数目

作者推荐 【动态规划】【前缀和】【C算法】LCP 57. 打地鼠 本文涉及知识点 动态规划汇总 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode:2338. 统计理想数组的数目 给你两个整数 n 和 maxValue &#xff0c;用于描述一个 理想…

手把手教你玩转蓝牙模块(原理+驱动)

head: title: 手把手教你玩转蓝牙模块&#xff08;原理驱动&#xff09; description: 手把手教你玩转蓝牙模块&#xff08;原理驱动&#xff09; 作为嵌入式开发工程师&#xff0c;蓝牙模块怎能少呢&#xff1f; 蓝牙模块广泛应用在各种电子器件&#xff0c;比如手机、蓝牙耳…

2 月 3 日算法练习-数论

简单数论 思路&#xff1a;各个相邻数的差值求最大公约数得到 d&#xff0c;然后就能求出最少项数。 c17用gcd&#xff0c;c11 用_gcd #include<bits/stdc.h> using namespace std; using ll long long; const int N 1e5 10; ll a[N]; int n; int main( ){cin>>…

【网站项目】030小学生课外知识学习网站

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Vue3.3新特新和Vue3-Pinia

文章目录 1.Vue3.3新特性 - defineOptionsVue3.3新特性 - defineModel3.Pinia快速入门4.手动添加Pinia到Vue项目5.Vue3 - Pinia的基本语法6.action的异步实现7.Vue3-Pinia-storeToRefs方法8.Pinia持久化插件安装用法 1.Vue3.3新特性 - defineOptions 背景说明 有<script se…

ELAdmin后台启动

版本选择 ELAdmin官网地址&#xff1a;https://eladmin.vip/ 有 JPA 和 MyBatis两个版本&#xff0c;之前只有 JPA&#xff0c;考虑到国内复杂的业务情况增加了 MyBatis 版本。我最终也选择了使用 MyBatis版本。 代码 仓库地址&#xff1a;https://gitee.com/elunez/eladmin…

Python环境下基于辛几何模态分解的信号分解方法

基于辛几何的分析方法是一种保护相空间几何结构的新型分析方法&#xff0c;主要用于求解动力学和控制系统中矩阵或Hamilton矩阵的特征值问题&#xff0c;用来解决在动力学和控制系统理论的2n2n矩阵或哈密顿矩阵的特征值问题&#xff0c;已应用到结构损伤信号、奇异微分方程等系…

【C#】.net core 6.0 创建默认Web应用,以及默认结构讲解,适合初学者

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…

Zoho Mail 2023:回顾过去,展望未来

当我们告别又一个非凡的一年时&#xff0c;我们想回顾一下Zoho Mail如何融合传统与创新。我们迎来了成立15周年&#xff0c;这是一个由客户、合作伙伴和我们的敬业团队共同庆祝的里程碑。与我们一起回顾这段旅程&#xff0c;探索定义Zoho Mail历史篇章的敏捷性、精确性和创新性…