> 文章列表 > 八股+面经

八股+面经

八股+面经

文章目录

  • 项目介绍
  • Java基础
    • Map
      • HashMap v.s Hashtable(5点)
      • ConcurrentHashMap v.s Hashtable(2点)
      • 代理模式
        • 1. 静态代理
        • 2. 动态代理
        • 2.1 JDK 动态代理机制
        • 2.2 CGLIB 动态代理机制
  • Java并发
    • 线程
    • volatile
    • synchronized
    • 线程池
  • JVM
    • 加载机制
    • 垃圾回收(GC)
      • 1. 引用类型
      • 2. 垃圾收集
      • 3. 垃圾回收算法(内存回收方法论)
      • 4. 垃圾收集器(内存回收具体实现)
        • **Serial:**
        • **ParNew:**
        • **Parallel Scavenge:**
        • **Serial Old**
        • **Parallel Old**
        • **CMS**
        • **G1**(Garbage-First)
  • 设计模式
    • 单例模式
  • MySQL
    • 存储引擎
    • 索引
      • 1. 优缺点
      • 2. 底层数据结构
        • B&B+树
      • 3. 索引类型总结
    • 事务
      • 1. ACID
      • 2. 并发事务问题
      • 3. 并发事务控制方式
        • MVCC
      • 4. 隔离级别
    • 锁机制
    • MVCC
      • RC和RR下 MVCC 的差异
  • Redis
    • 为什么用redis做mysql缓存?
    • 缓存读写策略
      • 1. 旁路缓存模式
      • 2. 读写穿透
      • 3. 异步缓存写入
    • 数据结构
  • 计算机网络
    • HTTP与HTTPS
    • 三次握手(建立TCP连接)
    • 四次挥手(断开TCP连接)
    • TCP v.s UDP
  • 操作系统
  • Spring
    • IoC
    • AoP
  • 面试题目
    • 拼多多 3.23
    • 美团-履约 3.24
    • 联想 3.27
    • 蚂蚁-数金 3.28

项目介绍

用户信息明文存储在数据库中,不安全

shiro

三大概念

  • Subject:负责存储与修改当前用户的信息和状态
  • SecurityManager:安全相关的操作实际上是由她管理的
  • Realms:负责从数据源中获取数据并加工后传给 SecurityManager

四大功能

  • Authentication(认证)
  • Authorization(授权)
  • Session Management(会话管理)
  • Cryptography(加密)

Java基础

Map

HashMap v.s Hashtable(5点)

八股+面经

ConcurrentHashMap v.s Hashtable(2点)

  1. 底层数据结构不同

八股+面经

  1. 实现线程安全方式不同

八股+面经

代理模式

1. 静态代理

2. 动态代理

  • 2.1 JDK 动态代理机制

  • 2.2 CGLIB 动态代理机制

Java并发

线程

volatile

synchronized

synchronized 是 Java 中的一个关键字,翻译成中文是同步的意思,主要解决的是多个线程之间访问资源的同步性,可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。

线程池

线程池就是管理一系列线程的资源池

JVM

类加载机制

  • 类加载器:通过类的全限定性类名(带包路径,如java.lang.String)获取该类的二进制字节流
    • Bootstrap:加载java核心库(如$JAVA_HOME/jre/lib/rt.jar)
      • 好处:不需要太多的安全检查,提升性能
    • Extension:加载拓展库($JAVA_HOME/jre/lib/ext/*.jar)
    • AppClass:根据java的类路径加载类,一般的java应用的类($CLASSPATH)
    • 用户自定义:
  • 加载方式:双亲委派机制
    • 过程:
      • 收到类加载请求,不会自己加载,而是逐级向上委托,最终到达顶层的Bootstrap;
      • 如果父类加载器完成,则返回;否则,交给子类尝试。
    • 好处:
      • 避免类的重复加载:java类由于加载机制,形成了优先级的层次关系
      • 防止核心类被篡改:防止下层的同名类篡改核心API库
    • 打破这个机制
      • 意义:由于类加载器受到加载范围的限制,某些情况下父类加载器无法加载需要的类(不属于其加载范围,但根据机制只能其加载),所以需要子类加载器加载。
      • 方法:使用自定义加载器
      • 如何:
        • 1、找到ClassLoader类的loadClass()方法,拷贝
        • 2、写自定义加载器类,粘贴
        • 3、删去loadClass()中的双亲委派机制的部分
        • 4、判断类是否为系统类,是的话使用双亲委派机制,否则自己的方法加载。
      • 应用:
        • Tomcat:webappClassLoader加载自己目录下的class文件,目的;1、隔离每个webapp下的class和lib;2、使用单独的加载器以免被恶意破坏;3、热部署(修改文件不用重启自动重新装载)

垃圾回收(GC)

1. 引用类型

八股+面经

2. 垃圾收集

  • 垃圾:不再被使用的对象,死亡的对象

  • 哪些垃圾需要回收?

    • 引用计数法:每个对象添加一个引用计数器,当为0时,就表示死亡;

      • 问题:循环引用,不可回收造成内存泄露;空间占用
    • 可达性分析算法:以根对象集合(GC Roots)为起点,分析GC Roots连接的对象是否可达,解决了循环引用问题。

      八股+面经

      • GC Roots:就是对象!

        • 1、虚拟机栈中的栈帧中的局部变量所引用的对象;
        • 2、java本地方法栈中(java本地接口)引用的对象;
        • 3、方法区中静态变量引用的对象;(全局对象)
        • 4、方法区中常量引用的对象(全局对象)
      • 问题:多线程下更新了访问过的对象的引用

        • 误报:原被引用的对象不再被引用。影响较小,顶多减少GC次数。

        • 漏报:将已被访问过的对象设置为未被访问过。影响较大,可能会使引用对象被GC,导致jvm崩溃。

          • 解决方法:Stop-the-world,等所有线程到达安全点,再进行Stop-the-world。
            • Stop-the-world:用户运行至安全点(safe point)或者安全区域之后,就会挂起,进入暂停状态。
  • 什么时候回收?

    • Minor GC:young gc,发生在年轻代的gc
    • Major GC:olg gc,发生在老年代的gc
    • **Full GC:**回收整个堆的内存
      • 触发条件:
        • System.gc()
        • 通过Minor GC进入老年代的平均大小 > 老年代的可用内存
        • 老年代空间不足;

3. 垃圾回收算法(内存回收方法论)

八股+面经

4. 垃圾收集器(内存回收具体实现)

各收集器关系:

八股+面经

  1. Serial:

    • 单线程,所有线程stw,

    • 新生代标记-复制,老年代标记-整理

    • 缺点:需要停止所有工作线程,效率低

    • 场景:对应用的实时性要求不高的client级别(桌面应用)的默认方式,单核服务器

      八股+面经

  2. ParNew:

    • Serial的多线程版本,stw, 复制算法

    • 新生代标记-复制,老年代标记-整理

    • 实际线程默认和cpu数量相同

    • 优点:有效利用cpu

    • 缺点:和Serial一样

    • 场景:Sever模式下的新生代,和CMS配合

  3. Parallel Scavenge:

  • 新生代收集器、复制算法,多线程

  • 与ParNew不同点:追求和精确控制高吞吐量,而ParNew尽可能缩短用户线程的停顿时间;

    • 高吞吐:线程运行时间/线程运行时间 + 垃圾回收时间
    • 例子:PS就是100秒回收一次垃圾,持续10秒,吞吐量为90%;PN就是50秒回收一次垃圾,持续7秒,吞吐量为86%。
  • 场景:注重高效利用CPU

  1. Serial Old

    • Serial的老年代版本,标记整理算法

    • 场景:client、单核。与PS收集器搭配

  2. Parallel Old

    • Parallel Scavenge的老年代版本,多线程,标记整理算法

    • JDK7,8默认老年代收集器

  3. CMS

    • Concurrent Mark Sweep

    • 多线程、标记清除算法

    • 特点:获取最短回收停顿时间

八股+面经

  • 流程:
    • 1、初始标记:GC Roots直接关联的对象,需要Stw
    • 2、并发标记:与用户线程并发,不需要Stw,执行Gc Roots Tracing
    • 3、重新标记:修正并发标记期间,发生变动的一些标记,需要Stw
    • 4、并发清除:标记清除
  • 优点:并发收集,低停顿
  • 缺点:
    • 对CPU资源敏感
    • 标记清除产生空间碎片
    • 并发清除过程中会产生新的垃圾,只能等下一次
  1. G1(Garbage-First)

    • 标记整理 + 复制

      • 特点:

        • 并行与并发
        • 分代收集:自己采用不同的收集方式去处理不同代的垃圾,不需要和其他收集器合作
        • 空间整合:无空间碎片
        • 可预测的停顿:可预测时间的停顿模型
      • 原理:

        • 将java堆分为大小相同的独立区域Region,新生代和老年代区域混合;

          八股+面经

          • 并发标记:知道哪些块基本是垃圾,就会从这些块下手(所以叫G1);
          • 停顿预测模型:
            • 根据之前垃圾回收的数据统计,估计出用户指定停顿时间内的回收块个数;
          • “尽力”满足指定的目标停顿时间,基于目标选择回收的区块数量;
    • 步骤;

      • 1、Minor GC

        • 复制算法、并行、stw
        • 动态调整年轻区大小:根据历史数据,和用户指定的停顿时间目标
        • 2、老年代收集
        • 初始标记:stw,伴随young gc,对Gc Roots直接关联对象进行标记
        • 扫描根引用区:即survivor区的对象直接到老年代对象的引用。(因为进行了YGC,新生代中只有survivor区存在对象)
        • 并发标记:寻找整个堆的存活对象,并发执行,可以被YGC中断
          • 如果整个region都是垃圾,直接被回收
          • 标记的同时计算region活性比例
        • 重新标记:stw,完成最后的标记,使用了STAB算法
          • 由于用户线程同时进行,需要修正之前的标记
          • 采用了比CMS更快的初始快照法:SATB算法
        • 清理:stw,复制算法。计算各个region的存活对象和垃圾比例,排序,识别可以混合回收的区域 。
        • 并发清理:识别并清理全是垃圾的老年代region
        • 3、混合式收集:
        • 除了整个年轻代收集, 还有上个阶段标记出的老年代的垃圾最多的区块;
        • 持续回收所有被标记的分区
        • 恢复到年轻代收集,进行新的周期
        • 必要时的Full Gc:
          • G1的初衷就是避免Full GC

设计模式

单例模式

  1. 懒汉式 - 线程不安全

    public class Singleton{private static Singleton instance;private Singleton(){}public static Singleton getInstance(){if(instance == null){instance = new Singleton();}return instance;}
    }
    
  2. 懒汉式 - 线程不安全

    public class Singleton{private static Singleton instance;private Singleton(){}public static synchronized Singleton getInstance(){if(instance == null){instance = new Singleton();}return instance;}
    }
    
  3. 双重检验锁

    public class Singleton{private static Singleton instance;private Singleton(){}public static Singleton getInstance(){if(instance == null){		// single checksynchornized(Singleton.class){if(instance == null){		//double checkinstance = new Singleton();}}}return instance;}
    }
    
  4. 饿汉式 - static final field

    public class Singleton{//类加载时就初始化private static final Singleton instance = new Singleton();private Singleton(){}public static Singleton getInstance(){return instance;}
    }
    
  5. 静态内部类 - 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;}
    }
    
  6. 枚举 - 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

存储引擎

  • MySQL 支持哪些存储引擎

    • MySQL 5.5.5 前:默认MyISAM;后:默认InnoDB
    • 只有 InnoDB 是事务性存储引擎,也就是说只有 InnoDB 支持事务。
  • 存储引擎架构

    • 插件式架构,支持多种存储引擎(不同数据库表可以设置不同搜索引擎)
    • 存储引擎是基于表的,而不是数据库
  • MyISAM 和 InnoDB 区别(7点)

    • MyISAM 性能还行,特性不错,但不支持事务和行级锁,最大的缺陷就是崩溃后无法安全恢复。

    八股+面经

索引

常见的索引结构有: B 树, B+树 和 Hash、红黑树。在 MySQL 中,无论是 Innodb 还是 MyIsam,都使用了 B+树作为索引结构。

1. 优缺点

优点

  • 使用索引可以大大加快 数据的检索速度(大大减少检索的数据量), 这也是创建索引的最主要的原因。
  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性

缺点

  • 创建索引和维护索引需要耗费许多时间。当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。
  • 索引需要使用物理文件存储,也会耗费一定空间

2. 底层数据结构

B&B+树

  • 为啥不用哈希表做MySQL索引数据结构?

    • Hash 索引不支持顺序和范围查询,并且,每次 IO 只能取一个。
    • 试想,SELECT * FROM tb1 WHERE id < 500;,树直接遍历比 500 小的叶子节点就够了;哈希还要把1-499数据hash计算一遍来定位
  • B树和B+树区别?(3点)

    八股+面经

3. 索引类型总结

八股+面经

事务

1. ACID

原子性Atomicity) : 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;

一致性Consistency): 执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;

隔离性Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;

持久性Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是手段,C 是目的!

八股+面经

2. 并发事务问题

  • 脏读(Dirty read)

    某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的

  • 丢失修改(Lost to modify)

  • 不可重复读(Unrepeatable read)

    在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

  • 幻读(Phantom read)

    在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

3. 并发事务控制方式

悲观控制模式

  • 共享锁(S 锁) :又称读锁,事务在读取记录的时候获取共享锁,允许多个事务同时获取(锁兼容)。
  • 排他锁(X 锁) :又称写锁/独占锁,事务在修改记录的时候获取排他锁,不允许多个事务同时获取。如果一个记录已经被加了排他锁,那其他事务不能再对这条记录加任何类型的锁(锁不兼容)。

MVCC

乐观控制模式

多版本并发控制(MVCC,Multiversion concurrency control) 在 MySQL 中实现所依赖的手段主要是: 隐藏字段、read view、undo log

  • undo log : undo log 用于记录某行数据的多个版本的数据。
  • read view 和 隐藏字段 : 用来判断当前版本数据的可见性。

4. 隔离级别

  1. 读取未提交(READ-UNCOMMITTED) : 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

  2. 读取已提交(READ-COMMITTED) : 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

  3. 可重复读(REPEATABLE-READ) : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  4. 可串行化(SERIALIZABLE) : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

八股+面经

锁机制

MVCC

RC和RR下 MVCC 的差异

在事务隔离级别 RCRR (InnoDB 存储引擎的默认事务隔离级别)下,InnoDB 存储引擎使用 MVCC(非锁定一致性读),但它们生成 Read View 的时机却不同

  • 在 RC 隔离级别下的 每次select 查询前都生成一个Read View (m_ids 列表)

  • 在 RR 隔离级别下只在事务开始后 第一次select 数据前生成一个Read View(m_ids 列表)

Redis

为什么用redis做mysql缓存?

1、高性能

  • MySQL从硬盘读取,慢。将用户缓存数据存在redis中,下次直接从缓存获取,相当于直接操作内存。
  • 为啥这么快?
    • 基于内存,访问速度是磁盘的上千倍
    • 基于reactor模式设计开发了一套高效事件处理模型,主要是单线程事件循环和io多路复用
    • 内置多种优化后的数据结构实现

2、 高并发

  • 单台设备的Redis的QPS(Query Per Second,每秒钟处理完请求的次数) 是 MySQL 的10倍
  • 直接访问 Redis 能够承受的请求远远大于直接访问 MySQL

缓存读写策略

1. 旁路缓存模式

  • 适用:读请求比较多的场景
  • 服务端同时维系 db 和 cache,以 db 的结果为准
  • 缓存读写步骤:
    • 写:
      • 先更新 db
      • 然后直接删除 cache
    • 读:
      • 从 cache 中读取数据,读取到就直接返回
      • cache 中读取不到的话,就从 db 中读取数据返回
      • 再把数据放到 cache 中

2. 读写穿透

  • 适用:读请求比较多的场景

3. 异步缓存写入

  • 适用:读请求比较多的场景

数据结构

5 种基础数据结构 :String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。

3 种特殊数据结构 :HyperLogLogs(基数统计)、Bitmap (位存储)、Geospatial (地理位置)。

计算机网络

HTTP与HTTPS

  • 区别
    • 传输安全:HTTP 是明文传输,存在安全风险的问题;HTTPS加密传输
    • 连接方式:HTTP是TCP;HTTPS是TCP基础上进行SSL/TLS
    • 端口号不同:HTTP 是 80;HTTPS是 443
    • 数字证书:HTTPS需要向CA申请数字证书
  • HTTPS解决了HTTP哪些问题?
    • 信息加密:交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
    • 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
    • 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。

三次握手(建立TCP连接)

八股+面经

一次握手:客户端发送带有 SYN(SEQ=x) 标志的数据包 -> 服务端,然后客户端进入 SYN_SEND 状态,等待服务器的确认;

二次握手:服务端发送带有 SYN+ACK(SEQ=y,ACK=x+1) 标志的数据包 –> 客户端,然后服务端进入 SYN_RECV 状态

三次握手:客户端发送带有 ACK(ACK=y+1) 标志的数据包 –> 服务端,然后客户端和服务器端都进入ESTABLISHED 状态,完成TCP三次握手。

四次挥手(断开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 后依然没有收到回复,就证明服务端已正常关闭,随后,客户端也可以关闭连接了。

TCP v.s UDP

  • 七点不同:

八股+面经

  • UDP 一般用于即时通信,比如: 语音、 视频 、直播等等。

  • TCP 用于对传输准确性要求特别高的场景,比如文件传输、发送和接收邮件、远程登录等等。

操作系统

Spring

IoC

IoC(Inversion of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。

为什么叫控制反转?

  • 控制 :指的是对象创建(实例化、管理)的权力
  • 反转 :控制权交给外部环境(Spring 框架、IoC 容器)

八股+面经

AoP

AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

面试题目

拼多多 3.23

项目:不动产估值系统

  • 学到了什么?提到scrapy理论,问原理

八股+面经

  • 多源异构数据集?数据类型是什么?
  • 机器学习算法怎么实现的?用了哪些特征?
  • 评估指标是啥(准确率)?r2的含义是什么?
    • R2_score直观且不受量纲影响。其数值大小反映了回归贡献的相对程度,即在因变量Y的总变异中,回归关系所能解释的百分比,其值越高,说明模型的解释性越好。
  • 还用过其他评估指标吗?还知道其他评估指标吗?
    • 平均绝对误差、均方误差、均方根差、均方根百分误差、决定系数R2
    • 前四种问题:量纲不同时,难以衡量模型效果好坏,并且可读性较差

八股+面经

  • 训练集和测试集怎么划分的?为什么这么划分?(这么划分结果最好
  • 为什么其他划分方式结果不好?有分析吗?
  • 训练集测试集划分比例有什么影响?过拟合是什么意思?
  • 个人能力比较突出的是什么?
  • 华融实习都是自己做的吗?
  • 遇到过什么问题?怎么解决?印象比较深花时间比较多的(提到了版本不一致报错)
  • java遇到版本不一样问题怎么办?a库和b库都用到了c库

java

  1. 类加载机制

  2. 垃圾回收机制

数据库

  1. redis和mysql有什么不同?为啥用redis做缓存?

  2. redis数据结构?

算法

上海[180.65.28.0, 186.75.28.0]

重庆[101.0.0.0,101,255,255,255]

…一共十万行

然后给ip地址(字符串),返回城市名称,没有对应城市返回""

反问:什么部门?做什么?跨境电商 海外业务 推荐搜索

美团-履约 3.24

项目

  1. 爬虫策略 数据量

  2. 用过大数据挖掘吗?spark这些?

MySQL

  1. 介绍索引

  2. B树和B+树区别

  3. 还有别的索引吗?都用的B+树吗?

  4. 聚簇索引 非聚簇索引

  5. 主键索引 非主键索引

java

  1. 垃圾回收算法

  2. java的锁synchronize,lock

  3. 介绍线程池

  4. 强引用 弱引用

算法: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;}
}

联想 3.27

图书项目

  1. spring boot和spring的区别?
    • 最大的区别在于Spring Boot的自动装配原理
    • 比如:
      • 创建Web程序时:Spring-导入几个Maven依赖,Spring Boot-只需要一个Maven依赖
      • 开启功能:Spring-XML文件配置,Spring Boot-不用XML配置,只需要写一个配置类
    • Spring Boot是一个微服务框架,延续了Spring框架的核心思想IOC和AOP,简化了应用的开发和部署,是Spring的完善和扩展
  2. mysql中有几种表?分别存的数据项是什么?
    • user,book,category(图书类别),admin_role(用户角色),admin_permission(用户权限),admin_role_menu(用户角色菜单),admin_role_permission(用户角色权限)
    • book表:id,cover,title,author,date,press,abs,cid(类别做外键)
  3. 项目中redis用什么客户端部署?
    • Java 访问 Redis 主要是通过 JedisLettuce 两种由不同团队开发的客户端(提供访问、操作所需的 API),Jedis 比较原生,Lettuce 提供的能力更加全面
    • 本项目用Spring Data Redis,Spring Data Redis是在 Lettuce 的基础上做了一些封装,与 Spring 生态更加贴合,使用起来也更简便。
  4. redis用的哪种数据结构存储图书?
    • RedisTemplate是 Spring Data Redis 提供的一个完成 Redis 操作、异常转换和序列化的类
    • String类型key,Set keys,List< Book >存图书列表
  5. List存取的api了解吗?
    • append,get
  6. redis缓存是所有图书都存进去吗?
  7. 数据库组建怎么实现的?
  8. mysql中事务是怎么添加的?
    • 步骤1:开启事务
      set autocommit=0;
      start transaction;可选的
    • 步骤2:编写事务中的sql语句(select、insert、update、delete)
      语句1;
      语句2;
    • 步骤3:结束事务
      commit;提交事务
      rollback;回滚事务
  9. 一个mapper两个update怎么保证事务不冲突?(答锁,纠正我锁是保证数据一致性的
    • MVCC
      • undo log
      • 隐藏字段
      • ReadView

抵押品项目

怎么构建的数据集?

java

  1. static和final什么时候用?为什么要用?

    • static
      • 加载:类加载时初始化(加载)完成
      • 可修饰:内部类、方法、成员变量、代码块
      • 不可修饰:外部类、局部变量
      • 作用:方便调用没有创建对象的方法/变量
    • final
      • 加载:final可以在编译(类加载)时初始化,也可以在运行时初始化,初始化后不能被改变
      • 可修饰:成员变量、方法、类以及本地变量
      • 一旦你将引用声明作 final,你将不能改变这个引用了,保证数据安全性
    • static final
      • 可修饰:成员变量、方法、内部类
      • 被static final修饰意义如下
        • 成员变量:属于类的变量且只能赋值一次。
        • 方法:属于类的方法且不可以被重写。
        • 内部类:属于外部类,且不能被继承。
  2. Object常用hashCode()和equals(),什么时候需要重写?

    • 1)当我们需要重新定义两个对象是否相等的条件时,需要进行重写。比如通常情况下,我们认为两个不同对象的某些属性值相同时就认为这两个对象是相同的。

      例如:我们在HashMap中添加元素时,我们认为当key相同时,两个元素就相同,但是默认的Object中的equals(),只是单纯的比较两个元素 的内存地址是否相同,不能满足我们的要求,所以需要重写。

    • 2)当我们自定义一个类时,想要把它的实例保存在集合时,就需要重写equals()和hashCode()方法

  3. ArrayList的底层数据结构

    • Object[]数组
  4. HashMap的底层数据结构?

    • jdk1.8之前:数组+链表(链表散列)
    • jdk1.8之后:链表长度>阈值(默认8),将其转化为红黑树,减少搜索时间
  5. HashMap数组中怎么存的?

    • 存的hash值,链表中存键值对

    八股+面经

  6. 哈希冲突是什么?

  7. synchronize怎么用?啥时候用?

    • 修饰实例方法:进入同步代码前要获得 当前对象实例的锁
    • 修饰静态方法:进入同步代码前要获得 当前 class 的锁
    • 修饰代码块
      • synchronized(object) 表示进入同步代码库前要获得 给定对象的锁
      • synchronized(类.class) 表示进入同步代码前要获得 给定 Class 的锁

算法(口述)

  • 两个数组找交集,令时间复杂度最小(答用set 时间复杂度是多少?
    • 排序 + 双指针:初始时,两个指针分别指向两个数组的头部。每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位,如果两个数字相等,且该数字不等于 pre ,将该数字添加到答案并更新 pre 变量,同时将两个指针都右移一位。当至少有一个指针超出数组范围时,遍历结束。

蚂蚁-数金 3.28

押品项目

  1. 从哪些维度对数据进行挖掘?得到什么样的结果?哪些对算法模型有决定性作用
  2. 系统开发后端是不是增删改查这些?用的什么数据库

java

  1. 保证线程安全的办法?(答锁,问我还有其他吗,没答出来

    • 互斥同步:synchronized是最常用的
    • 非阻塞同步
    • 无同步方案
  2. 说说对锁的了解(答乐观锁和悲观锁

  3. 悲观锁用什么实现?(答synchronized和ReentrantLock

  4. synchronized和其他独占锁底层是怎么实现的?

  5. java为什么会存在线程安全的问题?底层原因是什么?(答并发,跟我说是表象,问更深层是什么原因

  6. java本身jvm或者内存什么样的设计特点决定它存在这样的问题?(答线程共享堆和方法区资源,同时修改会发生安全问题,他还问更深层的是什么

  7. 了解java内存模型吗?新增一个线程,线程里的变量存在于什么地方?(答栈

  8. 这个栈空间是共享的还是独享的?(答共享的,纠正我有一部分共享一部分独享,共享function,独享变量

    变量独享,做复制,拷贝到工作内存,更改完需要回刷,产生XXx操作,是问题的根本原因

  9. ConcurrentHashMap的源码了解(答了一下初始化源码

mysql

  1. 索引结构(答b+树
  2. b+树特点
  3. b+树每一层都是链表(我说只有叶子是,纠正我mysql不是标准b+树,是变种
  4. 查询语句建索引,abc三个字段,有一条语句“a=?,c=?”,“?”是占位符,这个语句能不能用到abc复合索引?(答能,问原因不会

redis

  1. 读数写数单线程,那为什么性能那么好?(三点

Spring boot

  1. 动态加载和动态配置化为开发带来了哪些便利?

  2. 你在开发中用到了什么动态加载和动态配置化?

    (答spring用xml,sb用配置类,纠正:Spring也可以用注解不用xml配置,动态加载和用不用配置没啥关系

算法

  1. 线程安全的单例模式
  2. 快排
  3. 有序数组找第一个大于x的元素下标

其他

​ 工作和学习中做的最有挑战或者最有成就感的一件事是什么?

  • 互斥同步:synchronized是最常用的
  • 非阻塞同步
  • 无同步方案
  1. 说说对锁的了解(答乐观锁和悲观锁

  2. 悲观锁用什么实现?(答synchronized和ReentrantLock

  3. synchronized和其他独占锁底层是怎么实现的?

  4. java为什么会存在线程安全的问题?底层原因是什么?(答并发,跟我说是表象,问更深层是什么原因

  5. java本身jvm或者内存什么样的设计特点决定它存在这样的问题?(答线程共享堆和方法区资源,同时修改会发生安全问题,他还问更深层的是什么

  6. 了解java内存模型吗?新增一个线程,线程里的变量存在于什么地方?(答栈

  7. 这个栈空间是共享的还是独享的?(答共享的,纠正我有一部分共享一部分独享,共享function,独享变量

    变量独享,做复制,拷贝到工作内存,更改完需要回刷,产生XXx操作,是问题的根本原因

  8. ConcurrentHashMap的源码了解(答了一下初始化源码

mysql

  1. 索引结构(答b+树
  2. b+树特点
  3. b+树每一层都是链表(我说只有叶子是,纠正我mysql不是标准b+树,是变种
  4. 查询语句建索引,abc三个字段,有一条语句“a=?,c=?”,“?”是占位符,这个语句能不能用到abc复合索引?(答能,问原因不会

redis

  1. 读数写数单线程,那为什么性能那么好?(三点

Spring boot

  1. 动态加载和动态配置化为开发带来了哪些便利?

  2. 你在开发中用到了什么动态加载和动态配置化?

    (答spring用xml,sb用配置类,纠正:Spring也可以用注解不用xml配置,动态加载和用不用配置没啥关系

算法

  1. 线程安全的单例模式
  2. 快排
  3. 有序数组找第一个大于x的元素下标

其他

​ 工作和学习中做的最有挑战或者最有成就感的一件事是什么?