12种基学习器,评价指标为RMSE、MAE、MAPE和R2,最终选定Catboost和LightGBM
论文:Xception: Deep Learning with Depthwise Separable Convolutions (CVPR 2017)
源码:Keras开源代码
Very Deep Convolutional Networks for Large-Scale Image Recognition
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LSXqaK4S-1681986884287)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20230419190536360.png)]
JPA和Mybatis区别
前端服务器Nginx,后端服务器Tomcat,开发前端内容时,可以把前端的请求通过前端服务器转发给后端(称为反向代理)
用户信息明文存储在数据库中,不安全
shiro
三大概念
四大功能
Spring Security和Shiro的区别?
项目中redis用什么客户端部署?
Java 访问 Redis 主要是通过 Jedis 和 Lettuce 两种由不同团队开发的客户端(提供访问、操作所需的 API),Jedis 比较原生,Lettuce 提供的能力更加全面。
本项目用Spring Data Redis,Spring Data Redis是在 Lettuce 的基础上做了一些封装,与 Spring 生态更加贴合,使用起来也更简便。
延时双删:先清除缓存,在更新数据库后,等一段时间,再去第二次执行删除操作。
原子性
Java实现:synchronized
、各种 Lock
以及各种原子类
synchronized
和各种 Lock
可以保证任一时刻只有一个线程访问该代码块,因此可以保障原子性。各种原子类是利用 CAS (compare and swap) 操作(可能也会用到 volatile
或者final
关键字)来保证原子操作。
可见性
含义:一个线程对共享变量进行修改,另外的线程立即可以看到修改后的最新值。
Java实现:synchronized
、volatile
以及各种 Lock
有序性
含义:代码的执行顺序未必就是编写代码时候的顺序。
Java实现:volatile
关键字可以禁止指令进行重排序优化
volatile
**关键字volatile
,这就指示 JVM,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。volatile
关键字能保证数据的可见性,但不能保证数据的原子性。synchronized
关键字两者都能保证。用 **volatile
**关键字
如果我们将变量声明为 volatile
,在对这个变量进行读写操作的时候,会通过插入特定的 内存屏障 的方式来禁止指令重排序。
volatile使用场景:双重校验锁实现对象单例(线程安全)
public class Singleton {
private volatile static Singleton uniqueInstance;//volatile修饰!
private Singleton() {}
public static Singleton getUniqueInstance() {
if (uniqueInstance == null) {//没有实例化过才进入加锁代码
synchronized (Singleton.class) {//类对象加锁
if (uniqueInstance == null) {
/*这句话分三步进行:
1.为 uniqueInstance 分配内存空间
2.初始化 uniqueInstance
3.将 uniqueInstance 指向分配的内存地址
JVM指令重排,可能变成1->3->2,因此需要volatile*/
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
synchronized
、Lock
或者AtomicInteger
synchronized
主要解决的是多个线程之间访问资源的同步性,可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。
1. 修饰实例方法(锁当前对象实例)
synchronized void method() {
//业务代码
}
2. 修饰静态方法(锁当前类)
synchronized static void method() {
//业务代码
}
3. 修饰代码块(锁指定对象/类)
synchronized(this) {
//业务代码
}
注意:构造方法不能用synchronized修饰!(构造方法本身就线程安全)
底层依赖于JVM
synchronized
同步语句块的实现使用的是 monitorenter
和 monitorexit
指令,其中 monitorenter
指令指向同步代码块的开始位置,monitorexit
指令则指明同步代码块的结束位置。
在执行**monitorenter
**时,会尝试获取对象的锁,如果锁的计数器为 0 则表示锁可以被获取,获取后将锁计数器设为 1 也就是加 1。
对象锁的的拥有者线程才可以执行 monitorexit
指令来释放锁。在执行 monitorexit
指令后,将锁计数器设为 0,表明锁被释放,其他线程可以尝试获取锁。
如果获取对象锁失败,那当前线程就要阻塞等待,直到锁被另外一个线程释放为止。
synchronized
修饰的方法并没有 monitorenter
指令和 monitorexit
指令,取得代之的确实是 ACC_SYNCHRONIZED
标识,该标识指明了该方法是一个同步方法。JVM 通过该 ACC_SYNCHRONIZED
访问标志来辨别一个方法是否声明为同步方法,从而执行相应的同步调用。
如果是实例方法,JVM 会尝试获取实例对象的锁。如果是静态方法,JVM 会尝试获取当前 class 的锁。
同步语句块用monitorenter
指令和 monitorexit
指令,修饰方法用**ACC_SYNCHRONIZED
** 标识,不过两者的本质都是对对象监视器 monitor 的获取
synchronized
和 volatile
是互补的存在,区别有四点:
volatile
关键字是线程同步的轻量级实现,性能比synchronized好volatile
只能用于变量,synchronized
可以修饰方法以及代码块volatile
能保证数据的可见性,但不能保证数据的原子性。synchronized
关键字两者都能保证volatile
主要用于解决变量在多个线程之间的可见性,而 synchronized
关键字解决的是多个线程之间访问资源的同步性ReentrantLock
实现了 Lock
接口,是一个可重入且独占式的锁AbstractQueuedSynchronizer
)
ReentrantLock
里面有一个内部类 Sync
,Sync
继承 AQS,添加锁和释放锁的大部分操作实际上都是在 Sync
中实现的Sync
有公平锁 FairSync
和非公平锁 NonfairSync
两个子类
ReentrantLock
默认)Lock
实现类,包括synchronized
关键字锁都是可重入的ReentrantLock
增加了三点高级功能:
ReentrantLock
可以指定是公平锁还是非公平锁(默认非公平)synchronized
只能是非公平锁synchronized
关键字与wait()
和notify()
/notifyAll()
方法相结合可以实现等待/通知机制ReentrantLock
类需要借助于Condition
接口与newCondition()
方法实现线程池就是管理一系列线程的资源池,有任务处理->线程池拿线程->处理完不销毁->线程等待下一个任务
提供限制和管理资源的方式 && 维护一些基本统计信息
ThreadPoolExecutor
构造函数Executor
框架的工具类 Executors
线程达到最大数量,队列也被放满了任务,ThreadPoolExecutor.
定义的策略:
.AbortPolicy
:抛出异常拒绝新任务的处理。.CallerRunsPolicy
:调用自己的线程运行任务。.DiscardPolicy
:不处理新任务,直接丢弃。.DiscardOldestPolicy
:丢弃最老未处理的任务请求。新任务到来->当前运行线程数==核心线程数?->√->新任务放队列
不同线程池用不同的阻塞队列
LinkedBlockingQueue
(无界队列):队列永远不会被放满SynchronousQueue
(同步队列):没有容量,不存储元素。DelayedWorkQueue
(延迟阻塞队列):内部采用“堆”太大->增加上下文切换成本
太小->大量请求/任务堆积
CPU密集型任务(N+1):线程数设置为 N(CPU核心数)+1
I/O密集型任务(2N)
垃圾:不再被使用的对象,死亡的对象
哪些垃圾需要回收?
引用计数法:每个对象添加一个引用计数器,当为0时,就表示死亡;
可达性分析算法:以根对象集合(GC Roots)为起点,分析GC Roots连接的对象是否可达,解决了循环引用问题。
GC Roots:就是对象!
问题:多线程下更新了访问过的对象的引用
误报:原被引用的对象不再被引用。影响较小,顶多减少GC次数。
漏报:将已被访问过的对象设置为未被访问过。影响较大,可能会使引用对象被GC,导致jvm崩溃。
什么时候回收?
Serial的多线程版本,stw, 复制算法
新生代标记-复制,老年代标记-整理
实际线程默认和cpu数量相同
优点:有效利用cpu
缺点:和Serial一样
场景:Sever模式下的新生代,和CMS配合
新生代收集器、复制算法,多线程
与ParNew不同点:追求和精确控制高吞吐量,而ParNew尽可能缩短用户线程的停顿时间;
场景:注重高效利用CPU
Serial的老年代版本,标记整理算法
场景:client、单核。与PS收集器搭配
Parallel Scavenge的老年代版本,多线程,标记整理算法
JDK7,8默认老年代收集器
Concurrent Mark Sweep
多线程、标记清除算法
特点:获取最短回收停顿时间
步骤;
1、Minor GC
7种收集器关系
如果两个收集器之间存在连线,就说明它们可以搭配使用
收集器 | 串/并行/并发 | 新/老 | 收集算法 | 目标 | 场景 |
---|---|---|---|---|---|
Serial | 串行 | 新 | 复制 | 响应速度优先 | 单CPU环境下的Client模式 |
Serial Old | 串行 | 老 | 标记-整理 | 响应速度优先 | 单CPU环境下的Client模式、CMS的后备预案 |
ParNew | 并行 | 新 | 复制 | 响应速度优先 | 多CPU环境时在Server模式下与CMS配合 |
Parallel Scavenge | 并行 | 新 | 复制 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
Parallel Old | 并行 | 老 | 标记-整理 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
CMS | 并发 | 老 | 标记-清除 | 响应速度优先 | 集中在互联网站或B/S系统服务端上的Java应用 |
G1 | 并发 | both | 标记-整理+复制算法 | 响应速度优先 | 面向服务端应用,将来替换CMS |
懒汉式 - 线程不安全
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
懒汉式 - 线程不安全
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
双重检验锁
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){ // single check
synchornized(Singleton.class){
if(instance == null){ //double check
instance = new Singleton();
}
}
}
return instance;
}
}
饿汉式 - static final field
public class Singleton{
//类加载时就初始化
private static final Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
静态内部类 - static nested class
public class Singleton{
private static class SingletonHolder(){
private static final Singleton instance = new Singleton();
}
private Singleton(){}
public static final Singleton getInstance(){
return SingletonHolder.instance;
}
}
枚举 - Enum
public class Singleton{
private Singleton(){}
/**
*枚举类型是线程安全的,并且只会装载一次
*/
public enum SingletonEnum{
INSTANCE;
private final Singleton instance;
SingletonEnum(){
instance = new Singleton();
}
private Singleton getInstance(){
return instance;
}
}
public static Singleton getInstance(){
return SingletonEnum.INSTANCE.getInstance();
}
}
MySQL 支持哪些存储引擎
存储引擎架构
MyISAM 和 InnoDB 区别(7点)
常见的索引结构有: B 树, B+树 和 Hash、红黑树。在 MySQL 中,无论是 Innodb 还是 MyIsam,都使用了 B+树作为索引结构。
优点 :
缺点 :
为啥不用哈希表做MySQL索引数据结构?
SELECT * FROM tb1 WHERE id < 500;
,树直接遍历比 500 小的叶子节点就够了;哈希还要把1-499数据hash计算一遍来定位B树和B+树区别?(3点)
B+树比B树的优势
1.单一节点存储更多的元素,使得查询的IO次数更少;
2.所有查询都要查找到叶子节点,查询性能稳定;
3.所有叶子节点形成有序链表,便于范围查询。
原子性(Atomicity
) : 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
一致性(Consistency
): 执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
隔离性(Isolation
): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
持久性(Durability
): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是手段,C 是目的!
脏读(Dirty read)
某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的
丢失修改(Lost to modify)
在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。
不可重复读(Unrepeatable read)
在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
幻读(Phantom read)
在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
悲观控制模式
乐观控制模式
多版本并发控制(MVCC,Multiversion concurrency control) 在 MySQL 中实现所依赖的手段主要是: 隐藏字段、read view、undo log。
读取未提交(READ-UNCOMMITTED) : 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
读取已提交(READ-COMMITTED) : 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
可重复读(REPEATABLE-READ) : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
可串行化(SERIALIZABLE) : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
在事务隔离级别 RC
和 RR
(InnoDB 存储引擎的默认事务隔离级别)下,InnoDB
存储引擎使用 MVCC
(非锁定一致性读),但它们生成 Read View
的时机却不同
在 RC 隔离级别下的 每次select
查询前都生成一个Read View
(m_ids 列表)
在 RR 隔离级别下只在事务开始后 第一次select
数据前生成一个Read View
(m_ids 列表)
1、高性能
2、 高并发
5 种基础数据结构 :String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。
3 种特殊数据结构 :HyperLogLogs(基数统计)、Bitmap (位存储)、Geospatial (地理位置)。
一次握手:客户端发送带有 SYN(SEQ=x) 标志的数据包 -> 服务端,然后客户端进入 SYN_SEND 状态,等待服务器的确认;
二次握手:服务端发送带有 SYN+ACK(SEQ=y,ACK=x+1) 标志的数据包 –> 客户端,然后服务端进入 SYN_RECV 状态
三次握手:客户端发送带有 ACK(ACK=y+1) 标志的数据包 –> 服务端,然后客户端和服务器端都进入ESTABLISHED 状态,完成TCP三次握手。
第一次挥手 :客户端发送一个 FIN(SEQ=X) 标志的数据包->服务端,用来关闭客户端到服务器的数据传送。然后,客户端进入 FIN-WAIT-1 状态。
第二次挥手 :服务器收到这个 FIN(SEQ=X) 标志的数据包,它发送一个 ACK (SEQ=X+1)标志的数据包->客户端 。然后,此时服务端进入CLOSE-WAIT状态,客户端进入FIN-WAIT-2状态。
第三次挥手 :服务端关闭与客户端的连接并发送一个 FIN (SEQ=y)标志的数据包->客户端请求关闭连接,然后,服务端进入LAST-ACK状态。
第四次挥手 :客户端发送 ACK (SEQ=y+1)标志的数据包->服务端并且进入TIME-WAIT状态,服务端在收到 ACK (SEQ=y+1)标志的数据包后进入 CLOSE 状态。此时,如果客户端等待 2MSL 后依然没有收到回复,就证明服务端已正常关闭,随后,客户端也可以关闭连接了。
UDP 一般用于即时通信,比如: 语音、 视频 、直播等等。
TCP 用于对传输准确性要求特别高的场景,比如文件传输、发送和接收邮件、远程登录等等。
IoC(Inversion of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。
为什么叫控制反转?
AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
项目:不动产估值系统
java:
类加载机制
垃圾回收机制
数据库:
redis和mysql有什么不同?为啥用redis做缓存?
redis数据结构?
算法:
上海[180.65.28.0, 186.75.28.0]
重庆[101.0.0.0,101,255,255,255]
…一共十万行
然后给ip地址(字符串),返回城市名称,没有对应城市返回""
反问:什么部门?做什么?跨境电商 海外业务 推荐搜索
项目:
爬虫策略 数据量
用过大数据挖掘吗?spark这些?
MySQL:
介绍索引
B树和B+树区别
还有别的索引吗?都用的B+树吗?
聚簇索引 非聚簇索引
主键索引 非主键索引
java:
垃圾回收算法
java的锁synchronize,lock
介绍线程池
强引用 弱引用
算法:2. 两数相加 - 力扣
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead=new ListNode(-1);
ListNode p=dummyHead;
int add=0;
while(l1!=null||l2!=null||add>0){
int a=l1==null?0:l1.val;
int b=l2==null?0:l2.val;
int ans=a+b+add;
p.next=new ListNode(ans%10);
add=ans/10;
p=p.next;
if(l1!=null)
l1=l1.next;
if(l2!=null)
l2=l2.next;
}
return dummyHead.next;
}
}
图书项目
抵押品项目
怎么构建的数据集?
java
static和final什么时候用?为什么要用?
Object常用hashCode()和equals(),什么时候需要重写?
1)当我们需要重新定义两个对象是否相等的条件时,需要进行重写。比如通常情况下,我们认为两个不同对象的某些属性值相同时就认为这两个对象是相同的。
例如:我们在HashMap中添加元素时,我们认为当key相同时,两个元素就相同,但是默认的Object中的equals(),只是单纯的比较两个元素 的内存地址是否相同,不能满足我们的要求,所以需要重写。
2)当我们自定义一个类时,想要把它的实例保存在集合时,就需要重写equals()和hashCode()方法
ArrayList的底层数据结构
HashMap的底层数据结构?
HashMap数组中怎么存的?
哈希冲突是什么?
synchronize怎么用?啥时候用?
synchronized(object)
表示进入同步代码库前要获得 给定对象的锁。synchronized(类.class)
表示进入同步代码前要获得 给定 Class 的锁算法(口述)
押品项目
java
保证线程安全的办法?(答锁,问我还有其他吗,没答出来
说说对锁的了解(答乐观锁和悲观锁
乐观锁实现:版本号orCAS
悲观锁实现:synchronized
和Lock
等独占锁就是悲观锁
悲观锁用什么实现?(答synchronized和ReentrantLock
synchronized和其他独占锁底层是怎么实现的?
java为什么会存在线程安全的问题?底层原因是什么?(答并发,跟我说是表象,问更深层是什么原因
java本身jvm或者内存什么样的设计特点决定它存在这样的问题?(答线程共享堆和方法区资源,同时修改会发生安全问题,他还问更深层的是什么
线程共享:方法区,堆(有线程安全问题)
线程独享:栈、本地方法栈、计数器(不存在线程安全问题)
了解java内存模型吗?新增一个线程,线程里的变量存在于什么地方?(答栈
这个栈空间是共享的还是独享的?(答共享的,纠正我有一部分共享一部分独享,共享function,独享变量
变量独享,做复制,拷贝到工作内存,更改完需要回刷,产生XXx操作,是问题的根本原因
ConcurrentHashMap的源码了解(答了一下初始化源码
mysql
redis
Spring boot
动态加载和动态配置化为开发带来了哪些便利?
你在开发中用到了什么动态加载和动态配置化?
(答spring用xml,sb用配置类,纠正:Spring也可以用注解不用xml配置,动态加载和用不用配置没啥关系
算法
其他
工作和学习中做的最有挑战或者最有成就感的一件事是什么?
押品项目
图书项目
Java
java异常机制的了解
在 Java 中,所有的异常都有一个共同的祖先 java.lang
包中的 Throwable
类。
设计一个java线程池
Integer a=128; Integer b=128; System.out.println(a==b);
结果是啥?(应该是true,我答的false,他问我不是有常量池吗
public static void main(String[] args) {
Integer numValue=new Integer(1);
int a=1;
int b=2;
Integer nullValue=null;
if(a==1)
b=nullValue;
else if(b==2)
a=nullValue;
System.out.println(numValue);
System.out.println(nullValue);
System.out.println(a);
System.out.println(b);
}
结果是啥?(代码大概是这样,结果是编译错误T_T,int型(b)不能为null,Integer可以为null
类加载机制?
知道哪些类加载器(ClassLoader)?
BootstrapClassLoader
(启动类加载器) :最顶层的加载类,主要用来加载 JDK 内部的核心类库
ExtensionClassLoader
(扩展类加载器) :主要负责加载 %JRE_HOME%/lib/ext
目录下的 jar 包和类以及被 java.ext.dirs
系统变量所指定的路径下的所有类。
AppClassLoader
(应用程序类加载器) :面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。
垃圾回收机制的了解?(答回收算法,纠正我分代收集不算一种算法
哪几种收集器用的标记-整理?哪几种用的复制?
操作系统
构造一个死锁
public class DeadLock {
private class Running1 implements Runnable {
/*
* This method request two locks, first String and then Integer
*/
@Override
public void run() {
while (true) {
synchronized (String.class) {
System.out.println("Thread1 Aquired lock on String.class object");
synchronized (Integer.class) {
System.out.println("Thread1 Aquired lock on Integer.class object");
}
}
}
}
}
private class Running2 implements Runnable {
/*
* This method also requests same two lock but in exactly
* Opposite order i.e. first Integer and then String
* This creates potential deadlock, if one thread holds String lock
* and other holds Integer lock and they wait for each other, forever
*/
@Override
public void run() {
while (true) {
synchronized (Integer.class) {
System.out.println("Thread2 Aquired lock on Integer.class object");
synchronized (String.class) {
System.out.println("Thread2 Aquired lock on String.class object");
}
}
}
}
}
public static void main(String[] args) {
DeadLock deadLock = new DeadLock();
Running1 r1 = deadLock.new Running1();
Running2 r2 = deadLock.new Running2();
Thread thread1 = new Thread(r1);
Thread thread2 = new Thread(r2);
thread1.start();
thread2.start();
}
}
在上面这个例子中,我们有两个线程,以相反的顺序去获取两个锁,最后陷入了Thread1持有String锁,等待Integer锁,Thread2持有Integer锁,等待String锁的无限等待,即死锁情景
MySQL
InnoDB和MyISAM的区别(7点
为什么InnoDB的性能更强大?
为什么要主键自增?
redis
说说对redis的了解(答高性能和高并发
redis为什么用单线程?
哪几种底层数据结构?每种数据结构的使用场景?
String
存储常规数据
计数
分布式锁
List
信息流展示
消息队列
Set
存放的数据不能重复(点赞…
获取多个数据源交集、并集和差集(共同好友、音乐推荐…
随机获取数据源中的元素(抽奖系统…
Hash
Zset
随机获取数据源中的元素根据某个权重进行排序(朋友圈的微信步数排行榜…
存储的数据有优先级或者重要程度(优先级任务队列
io多路复用是怎么复用的?
目的:让单线程(进程)的服务端应用同时处理多个客户端的事件
含义:**“多路”指的是多个网络连接客户端,“复用”**指的是复用同一个线程(单进程)。
I/O 多路复用其实是使用一个线程来检查多个Socket的就绪状态,在单个线程中通过记录跟踪每一个socket(I/O流)的状态来管理处理多个I/O流。
算法
sql:student表里找成绩第二的
有序数组,遍历一次找出所有a+b=m的数字(要运行)
追问:数组是空怎么办?数组是[2,2,5,5]怎么办?
反问:对校招生的建议(告诉我美团注重基础
thread1.start();
thread2.start();
}
}
在上面这个例子中,我们有两个线程,以相反的顺序去获取两个锁,最后陷入了Thread1持有String锁,等待Integer锁,Thread2持有Integer锁,等待String锁的无限等待,即死锁情景
**MySQL**
1. InnoDB和MyISAM的区别(7点
2. **为什么InnoDB的性能更强大?**
- MyISAM 因为读写不能并发,它的处理能力跟核数没关系。
- 在读写混合模式或者只读模式下,随着 CPU 核数的增加,InnoDB 的读写能力呈线性增长。
3. **为什么要主键自增?**
- 1.数据记录本身被存于主索引的叶子节点上
- 2.mysql会根据其主键将其插入适当的节点和位置
- 3.表使用自增主键,在每次插入新的记录时,记录会顺序添加到当前索引节点的后续位置
**redis**
1. 说说对redis的了解(答高性能和高并发
2. **redis为什么用单线程?**
- 单线程编程容易并且更容易维护;
- Redis 的性能瓶颈不在 CPU ,主要在内存和网络;
- 多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能。
3. 哪几种底层数据结构?每种**数据结构的使用场景?**
- **String**
- 存储常规数据
- 计数
- 分布式锁
- **List**
- 信息流展示
- 消息队列
- **Set**
- 存放的数据不能重复(点赞...
- 获取多个数据源交集、并集和差集(共同好友、音乐推荐...
- 随机获取数据源中的元素(抽奖系统...
- **Hash**
- 对象数据存储(用户信息、文章信息...
- **Zset**
- 随机获取数据源中的元素根据某个权重进行排序(朋友圈的微信步数排行榜...
- 存储的数据有优先级或者重要程度(优先级任务队列
4. **io多路复用是怎么复用的?**
- 目的:让单线程(进程)的服务端应用同时处理多个客户端的事件
- 含义:**“多路”**指的是多个网络连接客户端,**“复用”**指的是复用同一个线程(单进程)。
I/O 多路复用其实是使用一个线程来检查多个Socket的就绪状态,在单个线程中通过记录跟踪每一个socket(I/O流)的状态来管理处理多个I/O流。
![在这里插入图片描述](https://img-blog.csdnimg.cn/c831c3aee0434cda8b9c6a0449e3b97b.png)
**算法**
1. sql:student表里找成绩第二的
2. 有序数组,遍历一次找出所有a+b=m的数字(要运行)
追问:数组是空怎么办?数组是[2,2,5,5]怎么办?
**反问**:对校招生的建议(告诉我美团注重基础