面试资料汇总

1. 项目

1.1. 项目介绍

1.1.1. SSO

  • 利用cookie解决跨域身份识别
  • sdk封装思路
  • 安全风险分析

1.1.2. 事件总线

  • redis pub-sub
  • 事件采集

1.1.3. Gateway

  • dsl
  • js
  • el解析规范
  • vfs

1.1.4. redis秒杀实现

  • 整体思路
  • watch流程
  • watch实现原理

1.1.5. 基础框架项目

1.1.5.1. 调用链
  • Threadlocal
  • RPC隐式传参
  • logback扩展
1.1.5.2. 国际化
1.1.5.3. JSON序列化List问题优化
  • TypeReferenceWrapper
  • code template
  • 泛型擦除问题分析
1.1.5.4. AOP事件探针方案
  • annotation
  • aop
  • threadlocalTraceId

1.1.6. 服务化改造类项目经验总结

  • 分层
  • 服务粒度
  • 事务
  • 多特性并行开发

1.2. 项目过程相关技能

1.2.1. git

1.2.1.1. 原理
1.2.1.2. 常用命令
1.2.1.3. 分支模型

1.2.2. maven

1.2.2.1. 原理
1.2.2.2. 生命周期
1.2.2.3. 常用插件

1.2.3. 单元测试

1.2.3.1. junit
  • 基础配置
    • 引入 spring-boot-test-starter,scope=test
    • @RunWith(SpringJUnit4ClassRunner.class)
    • @SpringApplicationConfiguration(classes = {ApplicationTest.class})
    • @Configuration
  • 测试代码
     @Test
     @SqlGroup({
             @Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, value = "classpath:h2/clean.sql"),
             @Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, value = "classpath:h2/init-data.sql")
     })
     ...
    
1.2.3.2. 嵌入式数据库
  • 配置 test/resources/application.properties
     spring.datasource.driver-class-name=org.h2.Driver
     spring.datasource.url=jdbc:h2:mem:test;MODE=MYSQL;
     spring.datasource.schema=classpath:h2/init-table.sql
     mybatis.mapper-locations=classpath:sql-mappers/**/*.xml
    
1.2.3.3. mockito
  • 生成mock bean,可以直接mock接口,不需要有实现类
     @Bean
     protected AppInfoCloudService appInfoCloudService() {
         return mock(AppInfoCloudService.class);
     }
    
  • mock bean调用示例
     //mock服务调用行为
     when(appInfoCloudService.getAppInfo(any(Integer.class), any(Integer.class))).thenReturn(APIResponse.success());
    

1.2.4. linux开发环境

2. 基础

2.1. JAVA SE 基础

2.1.1. StringBuilder StringBuffer

  • 线程安全
    • StringBuilder是非线程安全的,StringBuffer是线程安全的
    • 二者继承自同一个父类:AbstractStringBuilder
    • StringBuffer相比StringBuilder在很多方法上增加了synchronized关键字
  • 性能问题
    • StringBuilder默认初始化的数组大小只有16
    • 扩容时需要重新开辟一块内存(length*2+2),并拷贝原有数据
          /**
          * This implements the expansion semantics of ensureCapacity with no
          * size check or synchronization.
          */
          void expandCapacity(int minimumCapacity) {
              int newCapacity = value.length * 2 + 2;
              if (newCapacity - minimumCapacity < 0)
                  newCapacity = minimumCapacity;
              if (newCapacity < 0) {
                  if (minimumCapacity < 0) // overflow
                      throw new OutOfMemoryError();
                  newCapacity = Integer.MAX_VALUE;
              }
              value = Arrays.copyOf(value, newCapacity);
          }
      
      
    • 使用时需要考虑扩容造成的性能损失
  • 使用时机
    • 如果编译器本身能对String操作做优化,使用StringBuilder并不合算

2.1.2. NIO

2.1.2.1. 实现原理

这里暂时只分析linux下的原理

  • select
    • 单个进程能够监视的文件描述符的数量存在最大限制,通常是1024(#define __FD_SETSIZE)
    • 内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销
    • select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件
  • poll
    • 数组改成链表,没有了监视文件数量的限制,但其他问题仍然存在
  • epoll
    • 采用事件机制,只处理关注的IO事件,不必遍历所有
2.1.2.2. 基本概念
  • selector 监听IO就绪状态,实现多路复用
  • buffer 高性能缓冲区
  • channel 对IO连接的封装

2.1.3. 代理

  • 静态代理
  • 动态代理,要求实现类继承接口
    • 遍历接口列表,不会大于65535
    • 生成字节码文件,可选择是否写磁盘
    • ClassLoader加载类
    • Constructor创建实例,实际会有缓存,保证单例
    • InvocationHandler.invoke
  • Cglib,子类代理,不能代理final、private

2.1.4. 注解

  • 注解的作用
     注解也叫元数据,它主要的作用有以下四方面:
     生成文档,通过代码里标识的元数据生成javadoc文档。
     编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证。
     编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。
     运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。
    
  • @Target
     表示该注解可以用于什么地方,可能的ElementType参数有:
     CONSTRUCTOR:构造器的声明
     FIELD:域声明(包括enum实例)
     LOCAL_VARIABLE:局部变量声明
     METHOD:方法声明
     PACKAGE:包声明
     PARAMETER:参数声明
     TYPE:类、接口(包括注解类型)或enum声明
    
  • @Retention
     表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
     SOURCE:注解将被编译器丢弃
     CLASS:注解在class文件中可用,但会被VM丢弃
     RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息。
    
  • @Document 将注解包含在Javadoc中
  • @Inherited 允许子类继承父类中的注解
  • 注解处理器就是通过反射机制获取被检查方法上的注解信息,然后根据注解元素的值进行特定的处理

2.2. 集合

2.2.1. HashMap

  • 使用数组加链表的结构实现
  • 插入
    • 获取要插入的key的hash
    • 与当前length求模(例如:hash&63)
    • 上一步的计算结果作为数组的index
    • 生成链表,保存到对应的index
    • 如果发生碰撞,作为当前value的next
    • 1.8优化:如果链表长度超过8,转换为红黑树
  • 扩容
    • 当使用量超过75%(loadfactor,可设置),执行扩容
    • 1.8优化:前一位为0时不做处理

2.3. 数据结构&算法

2.3.1. hash算法

  • 直接寻址法
     取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a?key + b,其中a和b为常数(这种散列函数叫做自身函数)
    
  • 数字分析法
    分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相 同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会 明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
    
  • 平方取中法
     取关键字平方后的中间几位作为散列地址。
    
  • 折叠法
     将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。
    
  • 随机数法
     选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。
    
  • 除留余数法
    取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p, p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。
    

2.4. 线程

2.5. 锁

2.6. JVM

2.6.1. 运行时数据区

2.6.1.1. PC寄存器
2.6.1.2. 虚拟机线程栈
  • 结构图

    每个栈空间的默认大小为0.5M,在1.7里调整为1M,每调用一次方法就会压入一个栈帧,如果压入的栈帧深度过大,即方法调用层次过深,就会抛出StackOverFlow,,SOF最常见的场景就是递归中,当递归没办法退出时,就会抛此异常,Hotspot提供了参数设置改区域的大小,使用-Xss:xxK,就可以修改默认大小。
    
  • 局部变量表
  • 操作数栈
  • 动态链接
2.6.1.3. 本地方法栈
2.6.1.4. 堆
2.6.1.5. 方法区(永久代)

2.6.2. 执行子系统

2.6.3. GC算法

2.6.3.1. 分类
  • 标记清除
    • 标记待回收对象
    • 回收
  • 复制
    • 存活对象移动到另一个相同大小的空闲区
    • 清空当前区
  • 标记整理
    • 标记待回收对象
    • 将存活对象向一端整理
    • 删除所有已死亡对象
  • 分代
2.6.3.2. GC算法案例
  • parallel gc
  • cms
  • g1

2.6.4. 性能优化

  • 内存占用
  • 延迟
  • 吞吐量

2.6.5. 踩坑记录

  • ParallelCMSThreads > ParallelGCThreads 会引起此崩溃
  • 线程池使用不当造成队列拥堵,引发内存溢出,dump排查

3. 核心

3.1. nginx

3.2. tomcat

3.3. mysql

3.4. redis

3.5. mongo

3.6. rabbitMq

4. 框架

4.1. spring mvc

  • 运行原理
    1、用户发送请求至前端控制器DispatcherServlet
    2、根据Request信息,匹配handler
    3、HandlerAdapter#handle 匹配session 入参 等
    4、invokeHandlerMethod
    5、Controller执行完成返回ModelAndView。
    6、ViewReslover解析后返回具体View。
    7、渲染数据,返回响应
    

4.2. spring

4.2.1. 骨骼架构

  • bean是spring操作的核心元素,是对spring管理的Object的包装,spring可以理解为面向bean的编程
  • context是IoC容器,为bean提供了生存环境
  • core实现了对bean的核心操作能力

4.2.2. Ioc

  • 原理 Ioc 容器控制对象,并注入到依赖者

4.2.3. AOP

  • 原理 利用JDK Proxy 或者Cglib,在创建代理对象时织入代码
  • 织入方式分类
    • 编译期织入 aspectj ajc编译
    • 类加载织入 agent 替换classloader
    • 运行期织入 JDK Proxy Cglib

4.2.4. spring 事务

4.2.4.1. 事务隔离级别
4.2.4.2. 事务传播属性
4.2.4.3. MVCC

4.2.5. Spring生命周期

  • 初始化对象
  • 注入依赖
  • 执行扩展点
    • initializeBean
    • ApplicationContextAware
    • BeanPostProcessor
    • BeanNameAware

4.3. mybatis

4.4. shiro

4.5. spring boot

5. 分布式技术

5.1. Dubbo

![](_paste_img/面试/2018-03-10-08-51-18.png)
>   ```
>dubbo整个框架共分10个层
>第三层 proxy、第六层Monitor是两个分界线
>三层之前,1、2层的Service和Config是直接面向用户的,用户通过注解、XML等配置服务、服务依赖、配置信息等
>三层Proxy对用户的配置进行必要的包装
>三层到六层之间,4、5层是服务化的总控,通过4层注册中心、实现整个服务化系统的互通,5层Cluster的特点是以消费端为主
>六层Monitor主要做一些信息的收集工作
>六层以下是服务调用的落地部分,包括协议、信息交换、数据传输、序列化等
>   ```

5.2. zookeeper

  • zookeeper原理
     ZooKeeper是一种为分布式应用所设计的高可用、高性能且一致的开源协调服务,它提供了一项基本服务:分布式锁服务。由于ZooKeeper的开源特性,后来我们的开发者在分布式锁的基础上,摸索了出了其他的使用方法:配置维护、组服务、分布式消息队列、分布式通知/协调等。
     ZooKeeper所提供的服务主要是通过:数据结构+原语+watcher机制,三个部分来实现的。
    
  • znode结构
    ZooKeeper命名空间中的Znode,兼具文件和目录两种特点。既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。图中的每个节点称为一个Znode。 每个Znode由3部分组成:
    ① stat:此为状态信息, 描述该Znode的版本, 权限等信息
    ② data:与该Znode关联的数据
    ③ children:该Znode下的子节点
    znode创建类型(CreateMode),有以下四种:
        PERSISTENT                持久化节点
        PERSISTENT_SEQUENTIAL     顺序自动编号持久化节点,这种节点会根据当前已存在的节点数自动加 1
        EPHEMERAL                 临时节点, 客户端session超时这类节点就会被自动删除
        EPHEMERAL_SEQUENTIAL      临时自动编号节点
    
  • 分布式锁获取过程

     客户端调用create()方法创建名为“locknode/guid-lock-”的节点,需要注意的是,这里节点的创建类型需要设置为EPHEMERAL_SEQUENTIAL。
     客户端调用getChildren(“locknode”)方法来获取所有已经创建的子节点,同时在这个节点上注册上子节点变更通知的Watcher。
     客户端获取到所有子节点path之后,如果发现自己在步骤1中创建的节点是所有节点中序号最小的,那么就认为这个客户端获得了锁。
     如果在步骤3中发现自己并非是所有子节点中最小的,说明自己还没有获取到锁,就开始等待,直到下次子节点变更通知的时候,再进行子节点的获取,判断是否获取锁。
    

6. 理论

6.1. 面向对象

6.1.1. 封装

6.1.2. 继承

6.1.3. 多态

6.2. 设计模式

6.2.1. 创建型

6.2.2. 结构型

6.2.3. 行为型

6.3. 服务化

6.3.1. 服务拆分

6.3.2. 服务治理

7. 协议&规范

7.1. http协议

7.1.1. cookie

7.1.2. session

7.1.3. status code

转载于:https://my.oschina.net/sunxinhe/blog/1632647

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值