面试要点(上)
本文最后更新于 2024-11-21,文章内容可能已经过时。
1-Java面向对象是什么,解释一下三大特性
封装:把对象的属性和行为结合成为独立的一个整体,对外隐藏内部的细节。言外之意就是,把不想或不能告诉给别人的隐藏起来,把可以告诉的公开。
继承:子类继承父类的数据属性和行为,并且可以按照需求自行进行扩展。
多态:不同对象对同一消息做出回应,言外之意就是同一消息可以由发送对象的不同从而采用不同的方式。多态的应用:重写和重载。
2-io的几种方式
BIO:同步阻塞式,传统io,简单易用但是并发低。
NIO:同步非阻塞式,BIO的升级,客户端与服务端通过通道channel通讯,实现了多路复用。
AIO:异步非阻塞,NIO的升级,该方式主要是基于事件和回调机制。
3-Java的一部网络框架
SpringMVC,Mybatis
4-Java哈希表的实现
通过hashmap和hashset实现
5-解释一下hashmap
底层原理是:JDK1.8之前是数组+链表,JDK1.8之后是数组+链表或者数组+红黑树,主要是为了提高查找效率。
刚开始元素少的时候,用的是链表,当链表中元素数超过8个以后会转化为红黑数,当元素数为6个以下时会退化为链表。
6-hashmap的默认因子
默认负载因子是0.75,数组大小为16,当hashmap元素超过16*0.75=12个以后,数组扩大到2*16=32,相当于扩大一倍。
7-hashmap和hashset的区别
HashMap:存储键值对的双例集合,无序,key不可重复,value可重复,支持键值排序操作,适用于键值对存储的场景:缓存、数据库索引,常用方法为:put,remove,get等方法;
HashSet:存储单例集合无序,唯一,不可重复,更快的RUAD,适用于元素去重:统计文章单词出现频次,常用方法:add,remove,contains等方法。
8-springboot和以前(spring)的区别
springboot相比于之前spring框架,主要是对于spring框架进行了一些优化与改善,进而大大提高开发效率,缩短开发时间。
最大的优点有:
版本锁定,起步依赖,自动配置以及内置tomcat。
9-依赖注入的原理和优点
原理:依赖注入是ioc控制反转的一种实现方式,也就是说应用程序在运行时所依赖的ioc容器来动态注入对象所需要的外部资源。从而实现对象之间的解耦。
优点:降低组件之间的耦合度,提高代码的可维护性、可测试性和灵活性。
10-mvc指的是什么(为什么要把mvc这三个提出来做个单独的服务器)
mvc是一个软件设计模式,主要是将应用程序分为:model(负责处理应用程序的核心数据)、view(负责用户界面的展示)以及controller(作为模型和视图之间的中介),通过分离业务逻辑、数据和用户界面,提高了软件的可维护性和可扩展性。
11-用spring哪个版本
4版本,成熟且稳定,主要支持JDK8和lambda表达式
12-用spring的时候出现了什么问题
无法注入Bean问题:检查配置,作用域;
循环依赖;
配置错误;
性能问题。
13-SpringBoot和SpringCloud的区别
SB:解决Spring配置冗余问题,简化开发;可以独立开发。
SC:解决微服务之间的协调、配置问题,远程调用问题以及负载均衡;必须集成SB。
14-springcloud对于springboot多了哪些东西
注册中心,网关,负载均衡,远程调用,熔断器。
15-创建线程的方式
继承thread类,重写run方法(不可继承其他类);
继承Runnable接口,实现run方法(避免单线程局限性);
继承Callable接口,实现call方法(可以抛出异常);
使用线程池创建。
16-内部线程的生命周期
新建状态-就绪状态-运行状态-阻塞状态-死亡状态
17-内部线程的通信方式
共享内存;
wait/notify机制;
锁机制;
提供了java.util.concurrent.Exchange类实现线程之间的消息传递。
18-redis的数据类型
String,Hash,List,Set,Sorted Set
19-为什么要用Redis,MySQL是没法满足吗?
纯内存操作,每秒可以处理超过10万次读写操作;
支持事物化,持久化;
单线程操作;
采用了AIO机制,实现多路复用。
言外之意,主要是用了高性能,高并发场景中。
20-三种数据库分别存储在什么地方
redis存储在内存中,mysql存储在磁盘中,mongodb则存储在内存+磁盘中。
(md先访问内存中数据,没有再访问磁盘)
21-关系型数据库和mongodb的区别
关系型数据库:database>table>行,列>主键
mongodb:database>collection>文档,字段>主键,默认为_id
22-视频在mongodb的格式
BSON(二进制格式)
23-zookeeper是协调什么的
分布式协调服务,协调dubbo
24-数组和集合的区别:
数组:长度固定,只能存储一种数据类型;
集合:长度可变,存储的是对象,一个对象内可以有多种数据类型。
25-进程和线程的区别:
线程是CPU调度和分派的基本单位;
进程是操作系统调度和分派的基本单位,一个进程可以有多个线程。
26-解释一下注册中心
生产者先向注册中心注册服务,消费者向注册中心进行服务订阅,然后消费者可以从注册中心进行服务的拉取,最后直接进行调用。
27-git中rebase和merge的区别
他两都是用来合并代码的。
rebase:它则是提取当前分支的修改,然后将这些修改复制到目标分支的最新提交后面。 它会丢弃之前的commit,生成一个新的提交;会改变提交历史;适用于保持提交历史线性和整洁场景,个人开发者可以减少不必要的合并提交;有冲突,必须处理完使用命令git rebase --continue,继续操作。
merge:会将两个分支的最新快照以及它们最近的共同祖先进行三方合并,并生成一个新的提交;会创建一个新的提交,记录了合并过程中两个分支产生的冲突以及解决办法。 保留两个分支的完整历史;适用于保留完整历史记录场景。在合并过程中,如果出现冲突,会暂停,等到处理完继续。
28-git中合并代码
更新本地仓库:git pull
切换到目标分支:git checkout
合并分支:git merge
产生冲突,git会提示解决冲突
解决后,标记已解决:git add
提交:git commit
推送:git push origin +仓库名
29-mongodb超过500万会有什么缺点
查询性能下降,写入延迟增加,内存压力,
备份和恢复时间长,数据迁移困难,存储压力,管理和维护力度大
30-数组和链表的区别
数组:O(1),支持随机访问;连续存储增删慢,需要移动大量数据,尤其是中间的;不可扩展。
链表:O(n),每次访问从头查询;存储分散增删快,不需要移动大量数据,只需要修改指针节点;可扩展,多用于存放在cpu缓存中更高效在内存中。
31-项目中消息的转发怎么进行转发的
通过rocketmq
32-jwt的token需要续期吗
需要。
项目中:获取请求头token时判断token是否存在,如果不存在,就创建token保存在redis中,如果存在,就从redis中获取token进行续签(Duration.hours(1))。
一般常用方法:
每次刷新jwt,太暴力不常用;
只要快过期的时候刷新jwt,一样不常用;
完善refrwsh token,给客户端一个rt,让自己刷新jwt;
使用redis。
33-linux指令
34-redis如何持久化
rdb:快照;
aof:将redis执行过的所有指令记录下来,每次重启都执行一遍。
35-各个数据库存储在哪儿
mysql:存储在磁盘中,以表格形式存储;
redis:存储在内存中,键值对存储;
mongodb:存储在内存+磁盘,文档型数据库。
36-String、StringBuffer、StringBuilder的区别
String:通过final修饰字符串数组,字符串常量,线程安全,操作少量数据;
StringBuffer:字符串变量,线程不安全,多线程操作大量数据;
StringBuilder: 字符串变量,线程不安全,单线程操作大量数据。
37-synchronized关键字
保证线程之间同步互斥的,言外之意就是在方法或者代码块运行时,在同一时刻只允许一个线程访问数据,还保证了共享变量的内存可见性。
如何加锁:
普通方法,锁是当前实例对象;
静态方法,锁是当前类的class对象;
同步代码块,锁是括号里的对象。
38-实现一个递归阶乘
public class Factorial {
// 递归方法计算阶乘
public static long factorial(int n) {
// 基本情况:0! = 1 和 1! = 1
if (n <= 1) {
return 1;
} else {
// 递归情况:n! = n * (n-1)!
return n * factorial(n - 1);
}
}
public static void main(String[] args) {
int number = 5; // 你可以改变这个值来测试不同的输入
long result = factorial(number);
System.out.println("Factorial of " + number + " is: " + result);
}
}