Java面试整理一

小米一面

1 集合类图

Java面试整理一_第1张图片
Java面试整理一_第2张图片

2 .class文件魔数、版本

java编译生成固定格式的字节码(.class文件)供JVM使用,是因为字节码文件由十六进制值组成,而JVM以两个十六进制值为一组,即以字节为单位进行读取
Java面试整理一_第3张图片
魔数的固定值为:0xCAFEBABE(咖啡宝贝),魔数之后的4个字节为 次版本号与主版本号 例子(“00 00 00 34”) 转化为十进制为52,对应的主版本号为1.8

3 查看jvm进程内的线程状态

  1. 查看java的pid:ps –ef|grep java
  2. 查看进程的所有线程的资源消耗情况 top -H -p pid
  3. 找到CPU负载高的线程pid, 把这个数字转换成16进制,(10进制转16进制,用linux命令: printf %x pid)。
  4. 用jstack dump 线程的信息 jstack 6396 >6396.dump
  5. 用vim,搜索“16进制pid”,就是搜一下16进制显示的线程id。搜到后,下面的堆栈就是这个线程打出来的

4 jdk1.8.0_161\bin目录下的工具

  1. jconsole
    • 一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。
  2. jstack
    • Java堆栈跟踪工具,主要用于打印指定Java进程、核心文件或远程调试服务器的Java线程的堆栈跟踪信息。
  3. jmap
    • Java内存映射工具(Java Memory Map),主要用于打印指定Java进程、核心文件或远程调试服务器的共享对象内存映射或堆内存细节。
  4. jstat
    • JVM统计监测工具(JVM Statistics Monitoring Tool),主要用于监测并显示JVM的性能统计信息,包括gc统计信息。
  5. jvisualvm 1.6,1.7,1.8自带,能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的).

5 synchronized锁原理、重入锁

点击进入

线程状态,java.lang.Thread.State枚举表示,为什么将ready和running合并为runnable
1、NEW(新建)2、RUNNABLE(可运行)3、BLOCKED(阻塞)4、WAITING(无限期等待)5、TIMED_WAITING(限期等待)6、TERMINATED(结束)
javadoc 中说

处于 runnable 状态下的线程正在 Java 虚拟机中执行,但它可能正在等待来自于操作系统的其它资源,比如处理器。

当线程调用阻塞式 API,线程进入休眠状态,这里指的是操作系统层面的。从 JVM 层面,Java 线程状态依然处于 RUNNABLE 状态。JVM 并不关心操作系统线程实际状态。从 JVM 看来等待 CPU 使用权(操作系统线程状态为可运行状态)与等待 I/O (操作系统线程状态处于休眠状态)没有区别,都是在等待某种资源,所以都归入 RUNNABLE 状态。

6 HashMap&ConcurrentHashMap

HashMap & ConcurrentHashMap

7 hashCode、equals

1.equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。(生成hash值得公式可能存在的问题))

8 线程池,线程内部抛异常会不会影响其他线程,怎么回收不活跃的线程

在线程池中,一个线程出现问题不会导致其他线程的正常执行。会调用ThreadPoolExecutor.runWorker()方法最后面的finally中的processWorkerExit(),会将此线程remove,并重新addworker()一个线程

工作线程回收需要满足三个条件:

  1. 参数allowCoreThreadTimeOut为true
  2. 该线程在keepAliveTime时间内获取不到任务,即空闲这么长时间
  3. 当前线程池大小 > 核心线程池大小corePoolSize

或者 executor.shutdown();

9 mysql隔离级别、脏读、不可重复读、幻读(删除数据算不算幻读),可重复读RR 怎么解决幻读

点击查看 ,在 InnoDB 下
在快照读读情况下,mysql通过mvcc来避免幻读。
select * from t where a=1;属于快照读

在当前读读情况下,mysql通过next-key来避免幻读。
select * from t for update (lock in share mode);属于当前读

索引类型,BTree和hash的特点
一:B-tree索引 相当于金字塔大树分支 例如1000条数据 也就10多行 那么查询也只需要10多次。独立索引只能用一个。

二:hash索引 一对一主键 不利于范围查询 无法利用前缀查询

10 mysql主从不一致解决方案

  1. 检测不一致原因,是否因为跨机房binlog网络延迟,
  2. 配置不一致, max_allowed_packet设置不一致,同步参数 未设置sync_binlog=1或者innodb_flush_log_at_trx_commit=1,mysql版本不一致,
  3. …查看

11 spring+mybatis多数据源

这里

12 递增有序数组,计算哪些位置的和为100

Java面试整理一_第4张图片

小米二面

13 redis分布式session

14 redis分布式锁

这里

15 xxl-job分布式定时任务原理

这里

16 dubbo使用zookeeper分布式协调

这里

17 mysql大字符串建立索引

最左边前缀索引

18 主键索引与非主键索引区别

这里

19 AQS原理

这里

前端有没有做过

20 算法题,2 3 3 3 5 9 一些数据,找出出现次数大于等于n/2的数

如果那个数字的出现次数大于等于数组长度的一半,那么你把这个数组排序,中间的数就是我们要找的数。

小米四面

21 redis主从架构

这里

22 redis数据类型

这里

23 10W QPS系统架构

  1. nginx负载均衡+lua 限流+redis
  2. java程序 并发+redis+ MQ+rpc
  3. 数据库分库分表,读写分离+高可用

24 ORM框架原理

通过解析数据库配置文件获取数据库连接信息并建立连接,通过解析映射文件可以获取映射类名、属性名、表名以及字段名等信息,得到名字后通过反射机制可以得到映射类信息,调用构造方法创建对象,调用每个属性的set方法给对象设值完成数据的装载

25 mybatis优缺点

MyBatis是嘴加单的持久层框架,小巧并且简单易学。
提供映射标签,支持对象与数据库的ORM字段关系映射
提供对象关系映射标签,支持对象关系组建维护
提供xml标签,支持编写动态sql。

SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,
对开发人员编写SQL语句的功底有一定要求
SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
编写动态sql时,不方便调试,尤其逻辑复杂时。

26 索引类型,各种类型特点

这里

27 索引怎么加速查询

这里

跟谁学一面

27 zookeeper zab协议

ZooKeeper 的核心是原子广播,这个机制保证了各个 Server 之间的同步。实现这个机制的协议叫做 Zab 协议。Zab 协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步):
选主:当服务启动或者 Leader 崩溃后,Zab 就进入了恢复模式,当新的 Leader 被选举出来,且大多数 Server 完成了和 Leader 的状态同步以后,恢复模式就结束了。
同步:状态同步保证了 Leader 和 Server 具有相同的系统状态。
Zab 协议的特性:
1)Zab 协议需要确保那些已经在 Leader 服务器上提交(Commit)的事务最终被所有的服务器提交。
2)Zab 协议需要确保丢弃那些只在 Leader 上被提出而没有被提交的事务。

27 redis string数据类型实现方式

SDS(simple dynamic string,简单动态字符串)

  1. SDS中,有专门用于保存字符串长度的变量
  2. 防止缓冲区溢出.当我们需要对一个SDS 进行修改的时候,redis 会在执行拼接操作之前,预先检查给定SDS 空间是否足够(free记录了剩余可用的数据长度),如果不够,会先拓展SDS 的空间,然后再执行拼接操作。
  3. 减少扩展或收缩字符串带来的内存重分配次数,预分配策略
  4. 二进制安全,通过len这个属性判断字符串的结束

28 mybatis一、二级缓存

1、MyBatis一级缓存的生命周期和SqlSession一致。
2、MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
3、MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。

1、MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。
2、MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
3、在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。

纸币面额有 1, 2, 5, 10, 20, 50, 100,假设有一个自动售货机需要给用户找零 x 元,请打印出所有可能的找零组合。(leetcode 518. 零钱兑换 II)
动态规划

class Solution {
    public int coinChange(int[] coins, int amount) {

        // 0.因为凑成amount金额的硬币数最多只可能等于amount(全用 1 元面值的硬币),
        // 所以初始化为amount + 1就相当于初始化为正无穷,便于后续取最小值;
        int max = amount + 1;
        // 1.dp[i] = x表示,当目标金额为i时,至少需要x枚硬币
        int[] amounts = new int[amount + 1];

        Arrays.fill(amounts, max);
        // 2.这里很明显在目标金额为0的情况下, 需要0枚硬币即可;
        amounts[0] = 0;
        // 3.然后从底部向上, 也即为从目标金额为: "1"开始至"amount"来推目标状态值
        for (int i = 1; i <= amount; i++) {
            // 3.1 对于每一个金额amount, 枚举所有的硬币面值
            for (int j = 0; j < coins.length; j++) {
                // 对于不符合条件的直接剪枝;
                if (i >= coins[j]) {
                    // 3.2 利用上面推到出来的动态规划状态转移方程;
                    amounts[i] = Math.min(amounts[i], amounts[i - coins[j]] + 1);
                }
            }
        }

        return amounts[amount] > amount ? -1 : amounts[amount];
    }
}

跟谁学二面

29 DDD领域驱动设计

这里

30 业界链路压测

这里

31限流算法

  1. 固定窗口计数器;
  2. 滑动窗口计数器;
  3. 漏桶;
  4. 令牌桶。

32 创建线程的方式

/*
	corePoolSize : 线程池核心池的大小。
	maximumPoolSize : 线程池的最大线程数。
	keepAliveTime : 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
	unit : keepAliveTime 的时间单位。
	workQueue : 用来储存等待执行任务的队列。
	threadFactory : 线程工厂。
	handler  拒绝策略。
	*/
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) 

/*
阻塞队列:

ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。

LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。

PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。

DelayQueue: 一个使用优先级队列实现的无界阻塞队列。

SynchronousQueue: 一个不存储元素的阻塞队列。

LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。

LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。


拒绝策略:

ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。 (默认)
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务。(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务。
*/

26 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

青蛙简单跳台阶和变态跳台阶


/**
* 到达第 i 阶的方法总数 = 第 i -1 阶方法数 + 第 i -2 阶方法数 ,动态规划
*/
public int climbStairs3(int n) {
     if ( n == 1) {
        return 1;
    }
    int[] dp = new int[n + 1];
    dp[1] = 1;
    dp[2] = 2;
    for (int i = 3; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i -2];
    }
    return dp[n];

你可能感兴趣的:(杂记,study)