面试遇到的一些问题整理

1. MySQL 分库分表

为什么要分表:当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。

单库单表:单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到。

单库多表:随着用户数量的增加,user表的数据量会越来越大,当数据量达到一定程度的时候对user表的查询会渐渐的变慢,从而影响整个DB的性能。如果使用mysql, 还有一个更严重的问题是,当需要添加一列的时候,mysql会锁表,期间所有的读写操作只能等待。
可以通过某种方式将user进行水平的切分,产生两个表结构完全一样的user_0000,user_0001等表,user_0000 + user_0001 + …的数据刚好是一份完整的数据。

多库多表:随着数据量增加也许单台DB的存储空间不够,随着查询量的增加单台数据库服务器已经没办法支撑。这个时候可以再对数据库进行水平区分。

分库分表规则:设计表的时候需要确定此表按照什么样的规则进行分库分表。例如,当有新用户时,程序得确定将此用户信息添加到哪个表中;同理,当登录的时候我们得通过用户的账号找到数据库中对应的记录,所有的这些都需要按照某一规则进行。

路由:通过分库分表规则查找到对应的表和库的过程。如分库分表的规则是user_id mod 4的方式,当用户新注册了一个账号,账号id的123,我们可以通过id mod 4的方式确定此账号应该保存到User_0003表中。当用户123登录的时候,我们通过123 mod 4后确定记录在User_0003中。
CV于 MySQL 分库分表

水平分库、水平分表、垂直分库、垂直分表
知乎MySQL 分库分表

水平分库分表切分规则:RANGE、MOD、地理区域、时间、HASH取模
某博客园

2. Set(集)、Map(映射)、List(列表)三种集合的差别

CV于集合的详解
在这里插入图片描述

List:继承Collection接口,定义了一个允许重复项的有序集合。
Set:继承Collection接口,是无序的,而且不允许集合中存在重复元素。因为Set接口提供的数据结构是数学意义上的集合概念的抽象,因此他支持对象的添加和删除。
Map:Java 集合框架中一部分,用于存储键值对,HashMap是用哈希算法实现Map的类。

3.MQ(Message Queue)消息队列

ActiveMQ:Apache出品,完全支持JMS规范,API丰富;性能有瓶颈,吞吐量不高。
Kafka:Apache顶级项目,高吞吐量;不支持事务,对消息的重复、丢失没有严格要求
RocketMQ:阿里,Kafka的升级版;收费
RabbitMQ:基于AMQP协议协议实现,可以与springboot框架无缝对接,对数据的一致性要求非常严格;性能略输于Kafka

4.Java中==和equal有什么区别

== 表示对内存地址进行比较,表示引用是否相同。
equals()表示对字符串的内容进行比较,表示值是否相同。
在这里插入图片描述

5.堆栈区别

  1. 申请方式的不同。栈由系统自动分配,而堆是人为申请开辟;
  2. 申请大小的不同。栈获得的空间较小,而堆获得的空间较大;
  3. 申请效率的不同。栈速度较快,而堆一般速度比较慢;
  4. 存储内容的不同。栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部用一个字节存放堆的大小,堆中的具体内容是人为安排;
  5. 底层不同。栈是连续的空间,而堆是不连续的空间。

堆和栈的区别可以引用一位前辈的比喻来看:
使用栈就像我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

 class A{
      private String a = "aa";
      public boolean methodB() {
        String b = "bb";
        final String c ="ccc";
    }
 }
 a在堆中存放  bc在栈内存放。
 a属于类所以在堆中。bc属于方法,b c为局部变量,局部变量不属于任何类或者实例,因此它总是保存在其所在方法的栈内存中!

6.继承 封装 多态

多态的理解与应用

7.redis数据类型 redis的部署方式

1.string 字符串(可以为整形、浮点型和字符串,统称为元素)
2.list 列表(实现队列,元素不唯一,先入先出原则)
3.set 集合(各不相同的元素)
4.hash hash散列值(hash的key必须是唯一的)
5.sort set 有序集合

8.java八大基本数据类型及其封装类

Java基本类型共有八种,基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。数值类型又可以分为整数类型byte、short、int、long和浮点数类型float、double。JAVA中的数值类型不存在无符号的,它们的取值范围是固定的,不会随着机器硬件环境或者操作系统的改变而改变。实际上,JAVA中还存在另外一种基本类型void,它也有对应的包装类 java.lang.Void,不过我们无法直接对它们进行操作。8 中类型表示范围如下:
byte: 8位,最大存储数据量是255,存放的数据范围是-128~127之间。
short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
int: 32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
long: 64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
float: 32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
boolean:只有true和false两个取值。
char:16位,存储Unicode码,用单引号赋值。

Java决定了每种简单类型的大小。这些大小并不随着机器结构的变化而变化。这种大小的不可更改正是Java程序具有很强移植能力的原因之一。下表列出了Java中定义的简单类型、占用二进制位数及对应的封装器类。
123

9.string stringbuffer stringbuilder区别

1.在字符串不经常发生变化的业务场景优先使用String(代码更清晰简洁)。如常量的声明,少量的字符串操作(拼接,删除等)。
2.在单线程情况下,如有大量的字符串操作情况,应该使用StringBuilder来操作字符串。不能使用String"+"来拼接而是使用,避免产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。如JSON的封装等。
3.在多线程情况下,如有大量的字符串操作情况,应该使用StringBuffer。如HTTP参数解析和封装等。

10.sql调优

sql调优

11.map的扩容

HashMap扩容和ArrayList的扩容源码
HashMap和ArrayList扩容倍数

12.数据库加锁方式

实现数据库锁的两种方式

13.Mysql隔离事务级别

mysql事务隔离级别案例讲解
事务隔离级别的选择
图形展示

14.数据库索引

普通索引 唯一索引 主键索引 组合索引
数据库的索引
组合索引的失效场景

15.左连接 右连接

左连接的特殊用法

16.mybatis-plus插件保存后如何返回数据id

会直接赋值给入参,故可直接操作入参。

17.线程守护方式!! 多线程!!

多线程详解+四种实现方式+ 守护线程+优先级+死锁+案例
Java四种多线程实现方式以及守护线程

18.垃圾回收机制

JVM的4种垃圾回收算法、垃圾回收机制与总结
java面试之简述一下 Java 垃圾回收机制?
深入理解 JVM 垃圾回收机制及其实现原理

19.JRE、JDK、JVM 之间的区别与联系

JVM :英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。所以说,jvm 是 Java 能够跨平台的核心,具体的下文会详细说明。

JRE :英文名称(Java Runtime Environment),我们叫它:Java 运行时环境。它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。

JDK :英文名称(Java Development Kit),Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。

显然,这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM

20.使用递归调用时需要注意的问题

1.若递归方法中存在循环,循环中反复调用递归方法时,必须注意其循环外定义的变量,每次循环都会初始为定义的变量,所以为了动态生成其外变量,一般为循环的返回值。
2.递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出.跳出递归方法的位置一般放在循环的最开始
3.在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生栈内存溢出
4.构造方法,禁止递归

21.http协议相关

HTTP协议经典面试题整理及答案详解

22.PageHelper实现原理

在这里插入图片描述

总结:PageHelper分页的实现是在我们执行SQL语句之前动态的将SQL语句拼接了分页的语句,从而实现了从数据库中分页获取的过程。

23.MyBatis中# $的区别

1、$字符串拼接,# 参数站位相当于jdbc中的 ?号
2、$不能够防止sql注入,#可以防止sql注入的
3、$可以替换sql语句任何一个内容,#只能替换参数
4、$如果操作字符串,需要在sql中使用单引号。 #不需要(不需要判断数据类型,会自动转换)($要考虑参类型 ,#不用考虑参数类型)
总结:
#{} 解析的是占位符?可以防止SQL注入, 打印出来的语句 select * from table where id= ?
然而${} 作为字符串拼接来用,则是不能防止SQL注入打印出来的语句 select * from table where id=2 实实在在的参数 (sql注入:通过字符串拼接达到串改sql语句的目地)

24.取yml里的数

   @Value("#{'${eureka.server.allowed.address}'}")
    private String[] allowedAddress1;

    @Value("#{'${eureka.server.allowed.address}'.split(',')}")
    private List nameList1;
  
  
--------yml格式配置文件------------

test:
  application:
    properties:
      list1: aaa,bbb,ccc

25.linux 软连接 硬链接

Linux:软连接和硬链接其他须知
【硬连接】(Hard Link)硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。
【软连接】另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软连接实际上是通过名字引用另外一个文件,软连接和目标文件有着不同的inode号,说明软连接是一个独立的文件。可以理解为软连接存放的是目标文件的路径,包括目标文件的名称。
软连接我们可以想象成是windos系统下的快捷方式,可以快速访问目标文件。

通过实验加深理解
[oracle@Linux]$ touch f1 #创建一个测试文件f1
[oracle@Linux]$ ln f1 f2 #创建f1的一个硬连接文件f2
[oracle@Linux]$ ln -s f1 f3 #创建f1的一个符号连接文件f3
[oracle@Linux]$ ls -li # -i参数显示文件的inode节点信息
total 0
9797648 -rw-r–r-- 2 oracle oinstall 0 Apr 21 08:11 f1
9797648 -rw-r–r-- 2 oracle oinstall 0 Apr 21 08:11 f2
9797649 lrwxrwxrwx 1 oracle oinstall 2 Apr 21 08:11 f3 -> f1
从上面的结果中可以看出,硬连接文件f2与原文件f1的inode节点相同,均为9797648,然而符号连接文件的inode节点不同。

[oracle@Linux]$ echo “I am f1 file” >>f1
[oracle@Linux]$ cat f1
I am f1 file
[oracle@Linux]$ cat f2
I am f1 file
[oracle@Linux]$ cat f3
I am f1 file
[oracle@Linux]$ rm -f f1
[oracle@Linux]$ cat f2
I am f1 file
[oracle@Linux]$ cat f3
cat: f3: No such file or directory
通过上面的测试可以看出:当删除原始文件f1后,硬连接f2不受影响,但是符号连接f1文件无效。

总结
1).删除符号连接f3,对f1,f2无影响;
2).删除硬连接f2,对f1,f3也无影响;
3).删除原文件f1,对硬连接f2没有影响,导致符号连接f3失效;
4).同时删除原文件f1,硬连接f2,整个文件会真正的被删除。

26.Linux下/bin和/sbin的区别

简单归纳:
/bin目录(binary)是二进制执行文件目录,主要用于具体应用
/sbin目录(system binary)是系统管理员专用的二进制代码存放目录,主要用于系统管理

/bin,/sbin,/usr/bin,/usr/sbin区别
/ : this is root directory root 用户根目录
/bin : commandsin this dir are all system installed user commands 系统的一些指令
/sbin: commands in this dir are all system installedsuper user commands 超级用户指令系统管理命令,这里存放的是系统管理员使用的管理程序
/usr/bin: usercommands for applications 后期安装的一些软件的运行脚本
/usr/sbin:super user commands for applications 超级用户的一些管理程序
/usr/X11R6/bin: X application user commands
/usr/X11R6/sbin: X application super usercommands

Linux中的某些重要的目录:
•主目录:/root、/home/username
•用户可执行文件:/bin、/usr/bin、/usr/local/bin
•系统可执行文件:/sbin、/usr/sbin、/usr/local/sbin
•其他挂载点:/media、/mnt
•配置:/etc
•临时文件:/tmp
•内核和Bootloader:/boot
•服务器数据:/var、/srv
•系统信息:/proc、/sys
•共享库:/lib、/usr/lib、/usr/local/lib

每个用户都拥有一个主目录。所有用户的个人文件(配置、数据甚至应用程序)都放在其中。根的主目录为/root。大多数非根主目录包含在/home 树中,通常以用户命名。重要的二进制位于 /bin(用户二进制)以及 /sbin(系统二进制)中。不重要的二进制(如图形环境或Office 工具)安装在/usr/bin 和 /usr/sbin中。进行这种分隔是为了尽可能地缩小根分区。使用源代码编译的软件通常位于 /usr/local/bin 和/usr/local/sbin中。

27.设计模式

软件设计7大原则以及23种设计模式初识

28.线程安全的集合

Vector
Vector集合是对ArrayList集合线程安全的实现,它们两者在方法的实现上没有什么太大的区别,最大的区别就是,Vector在方法前面加上了synchronized关键字,用于保证线程安全。
Vector存在的问题:
1、它的add()和get()方法都能够获取当前Vector对象的对象锁,但是有可能会发生读读互斥。
2、当threadA在1下标处添加一个元素,threadB在2下标处修改一个元素时,同样有可能会发生互斥现象
因此,我们可以看出Vector所存在的锁的粒度是非常大的,这也就会导致在多线程情况下,程序执行的效率有可能会十分低下。

HashTable
HashTable集合是对HashMap集合线程安全的实现,它们两者在方法的实现上没有什么太大的区别,最大的区别就是,HashTable在方法前面加上了synchronized关键字,用于保证线程安全。
HashTable存在的问题:
由于HashTable和Vector在本质上都是在方法前面加上synchronized关键字,因此,它们两个存在的问题也是同样相同的,均有可能发生互斥现象。
由此可知,HashTable所存在的锁的粒度也是非常大的,也同样会导致在多线程情况下,程序执行的效率有可能会十分低下。
为了解决Vector集合和HashTable集合效率低下的问题,我们在选取线程安全的集合时一般会选择CopyOnWriteArrayList集合和ConcurrentHashMap集合,它的锁的粒度相较于Vector和HashTable更小,因此能够高效率的解决Vector和HashTable所存在的问题。

29.springboot的优点,如何管理依赖的

1.快速进行开发和部署
2.内嵌Tomcat,可直接启动
3.提供了大量的自动配置,约定优于配置

30.数据回滚时,MySQL数据库的操作

MySQL–事务回滚机制与原理

31.java对数据库事务的调用

void reject(@Param("costId")Integer costId,@Param("userId") Integer userId,@Param("auditComment") String auditComment);
 
 <select id="reject" statementType="CALLABLE" >
    {call resettingBill
         (
             #{costId,mode=IN},
             #{userId,mode=IN},
             #{auditComment,mode=IN}
         )
    }
  </select>

32.AOP的具体用法及注解执行顺序

aop注解执行顺序
结论
1.在一个方法只被一个aspect类拦截时,aspect类内部的 advice 将按照以下的顺序进行执行:around.pjp.proceed()前半部分->before->方法->around.pjp.proceed()后半部分(上一步方法抛错,不执行此步)->After->AfterReturning(AfterThrowing)
2.在一个方法被多个aspect类拦截时,@Order是值越小的 aspect 越先执行。

33.如何查MySQL的各种语句执行用时

慢查询

34.事务的四大特征

ACID,原子性(Atomicity)、一致性(Correspondence)、隔离
性(Isolation)、持久性(Durability)
事务及事务的四大特征

35.redis和数据库的一致性问题的解决方案

先删除缓存,再更新数据库,在查询时,发现缓存已经不存在,去数据库查询之后,同步到redis缓存。
redis和数据库的一致性问题的解决方案

36.依赖注入和控制反转

依赖注入和控制反转含义相同,它们是从两个角度描述的同一个概念。
当某个 Java 实例需要另一个 Java 实例时,传统的方法是由调用者创建被调用者的实例,而使用 Spring 框架后,被调用者的实例不再由调用者创建,而是由 Spring 容器创建,这称为控制反转。
Spring 容器在创建被调用者的实例时,会自动将调用者需要的对象实例注入给调用者,这样,调用者通过 Spring 容器获得被调用者实例,这称为依赖注入。
依赖注入与控制反转

37.ArrayList与LinkList对比

1.ArrayList是实现了基于动态数组的数据结构,而LinkedList是基于链表的数据结构;
2.对于随机访问元素,Array获取数据的时间复杂度是O(1),但是要删除数据却是开销很大的,因为这需要重排数组中的所有数据。ArrayList想要get(int index)元素时,直接返回index位置上的元素,而LinkedList需要通过for循环进行查找,虽然LinkedList已经在查找方法上做了优化,比如index < size / 2,则从左边开始查找,反之从右边开始查找,但是还是比ArrayList要慢。
3.对于添加和删除操作add和remove,LinkedList是更快的。
ArrayList与LinkList对比

38.主从库相关

1、读写分离,缓解数据库压力(主数据库用于数据写入,数据库用于数据读取),提高性能瓶颈。
2、一主多从,系统可扩展性和可用性高。
3、数据备份容灾,异地双活,保证主库异常随时切换,提高系统容错能力。
主从库搭建

39.JVM类加载机制

40.threadlocal

41.常见异常

42.springboot常用注解

43.怎么实现负载均衡

44.三个应用内存如何同步

45.序列化怎么实现

46.redis持久化 以及常用方法

47.redis分布式锁

48.Linux常用命令

49.线程start和run的区别

50.maven package和install的区别

51.wait sleep的区别

52.数据库的事务

53.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值