面试内容整理

内存溢出

  • 栈:
    StackOverflowError(方法调用层次太深,内存不够新建栈帧;或者线程栈设置太小导致的)
    解决方法:
    1、改为非递归调用,递归中的非静态变量改为静态变量
    2、通过-Xss增加线程栈大小,即增加递归深度

  • 堆:
    OutOfMemoryError:java heap space(内存泄露:对象未及时回收;内存溢出:大对象-SQL)
    ** 排查方法(Eclipse MAT工具排查,Java 启动参数增加 -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=/data/log/dump/ 然后进行压力测试)**
    Eclipse MAT 安装及使用

  • 持久带/元空间
    java.lang.OutOfMemoryError: PermGen space(代码热部署以及代理使用较多)

GC

  • 内存分为一块较大的Eden和两块较小的Survivor1、Survivor2,JVM默认分配是8:1:1
  • Eden空间不足时,触发Minor GC,这时会把存活的对象转移进Survivor区

GC ROOT

  • System Class,由系统类加载器加载的类,例如rt.jar内的类,自定义类加载器加载的类不在此范围
  • JNI Local,JNI(Java native interface)方法的local变量或参数
  • JNI Global,全局JNI引用
  • Thread,活着的线程
  • Static,方法区中静态变量\常量引用的对象
  • Java Local,虚拟机栈(栈中的本地变量表)中引用的对象
  • Monitor Used,用于同步的监控对象

Java 8 新特性

  • Lambda表达式(自带了并行处理parallel,多核服务器有用)
  • 函数式接口
  • 接口的默认方法(fastJson bug)
  • Stream
  • 内存模型的变化,去掉了永久带,增加了元空间(本地内存分配,默认无上限,每个classLoader分配一片内存),
    代码热部署以及代理使用较多可能会导致永久带内存溢出,现在把类信息存储在计算机本地,而不是堆内存,这个内存就会很大,不太用担心溢出问题,可以用MaxMetaspaceSize参数,设置元空间的大小

Dubbo

  • 多版本(但是不好用,一旦改版本,调用者处也要改,会改很多地方)
  • 服务分组
  • 路由管理(dubboKeeper)
  • 异步调用

  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表

单例模式5种

  • 单线程(不推荐)
  • 懒汉式(直接加同步锁,效率低)
  • 懒汉式(双重if判断,内部加同步锁,只有if判断为null时才会加同步锁,所以只会加一次锁,效率高,但是复杂,易出错)
  • 饿汉式,静态初始化(会先加载,占用内存)
  • 静态内部类(达到了懒汉式的效果,而且加单)

并发

  • 有三个线程T1,T2,T3,怎么确保它们按顺序执行?
    在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。你可以查看这篇文章了解更多。

Maven

  • Parent中dependencies和dependencyManagement的区别:
      dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
      dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

Mysql

  • int(11)和int(4)的区别:
    11和4不影响字段的存储长度,只是在该字段设置了unsigned zerofill属性时,他们才有区别,int(11)表示在该字段数值不足11位时,前面用0补足到11位显示,但是unsigned使得该字段无法存储负值,计算结果也不能为负数,所以不建议增加这个属性。
  • 作为索引,为何采用B+Tree而不是B Tree

JDK动态代理和CGLIB代理的区别

  • JDK动态代理只能对实现了接口的类生成代理,而不能针对类
  • CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承),由于是继承方式,如果是 static方法、private方法、final方法等描述的方法是不能被代理的

分布式中的CAP和BASE

Redis集群

Zookeeper选举算法

Redis与Memcached的区别

Nginx 多进程模型是如何实现高并发的

如何减少Full GC

Redis速度快的原因

Innodb和MyISAM引擎的区别

Linux基本命令 - awk

你可能感兴趣的:(面试内容整理)