面试笔记

面试笔记

跨域问题

因为同源策略, 当客户端和服务端不再同一域下时, 要解决请求的跨域问题

一般有两种方法 1) JSONP  2) CORS

JSONP仅限于GET请求,有一定的局限性

CORS可以满足多种方法的请求, 需要做的是对response的响应头改写, 处理方式可以用Filter过滤指定范围的请求

简单请求和非简单请求

CORS请求分为简单请求和非简单请求

简单请求要满足以下条件

  1. 请求方法在这三个以内: HEAD \ GET \ POST
  2. 头部不超过以下几种字段:   AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type(只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)

非简单请求时指对服务器有特殊要求的请求

比如PUT \ DELETE方法, Content-Type是application/json的请求

非简单请求会先发送一个预检请求, 用OPTION方法.

RPC是什么

Remote Procedure Call \ 远程过程调用 : 一个计算机通讯协议, 可以实现像调用本地服务一样调用远程服务, 并且让网络通讯过程透明. 一般使用IDL接口定义语言, 方便跨平台远程过程调用.

如阿里巴巴的hsf、dubbo(开源)、Facebook的thrift(开源)、Google grpc(开源)、Twitter的finagle(开源)等都是基于RPC的框架.

RPC做到让中间的网络通讯过程透明化, 一般选择动态代理的方式实现.

  1. 确定消息数据结构, 对消息进行序列化
  2. 进行网络通讯, 一般要支持BIO和NIO两种方式, 可以1) 自己开发JAVA NIO方式 2) 基于MINA 3) 基于Netty
  3. 消息里面有requestID是因为解决多条线程异步请求服务时, 回调能保证给正确的线程.

序列化

序列化是将数据结构或者对象转化成二进制串, 也就是编码的过程.

反序列化是将二进制串转换成数据结构或者对象的过程.

序列化是为了 进行网络传输

反序列化是为了 后续对其处理

Netty

Netty是一款基于NIO开发的网络通信框架, 对比于BIO, 他的并发性能得到很大提高.

很多RPC框架是基于Netty这一IO通信框架, 比如阿里的HSF, Dubbo, Twitter的finagle等.

RPC和HTTP的区别

RPC是基于TCP/IP协议的 , HTTP是基于HTTP协议的 , 传输效率RPC效率更高一些 .

代理模式

结构性模式,不是创建型模式

我们创建具有现有对象的对象, 并向外界提供功能接口. 以解决直接访问对象时带来的问题, 比如访问情景多样化, 直接访问会给使用者或者系统结构带来很多麻烦, 所以在访问此对象时, 加上一个对此对象的访问层.

代理模式是指 一个公共接口,一个实现类,一个代理类,代理类持有实现类实例,代理执行实例方法。 执行过程中不直接访问实体对象,而是通过代理对象访问。

代理过程中可以加上一些其他的用途。Spring的AOP面向切面编程是基于动态代理, 切入的点就是一个个被代理的类.

静态代理

代理类和实体类已经确定, 在编译之前已经完成.

动态代理

在程序执行过程中创建代理类是动态代理. 可以统一的管理代理类.

java.lang.reflect包下的Proxy类用来动态创建一个代理对象的类

并且需要实现InvocationHandler这个接口,让每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用

  1. 定义接口
  2. 定义实现类
  3. 实现InvocationHandler接口, 可以在invoke方法中加入预处理和后处理
  4. Proxy.newProxyInstance创建对应的代理对象

什么是RESTful

 RESTful是一种架构风格, REST意思是表示层状态转化(Representation state transfer)

REST的特点是

  1. 面向资源  一般使用json或者xml的形式
  2. URI 唯一定位标识符  至少有一个URI定位到资源
  3. 统一接口  用HTTP的方法表示CRUD操作
  4. 无状态  可以直接定位, 和其他资源没有前置关系

依赖注入

 

异步同步

同步

程序同步执行 , 当代码A执行完之后再执行B , 如果A没有执行完 , B要等待 .

异步

程序异步执行 , 当代码A执行中 , B不需要等待A执行完再执行 , 可以进入就绪状态准备执行 . 

回调函数

在A代码片段中 , 会执行B , 当B执行完 , B会执行A的callback函数 . 这是一种机制 . 可以将A和B抽象成接口 , 易于扩展 .

Spring 核心功能

Spring core 

核心功能 , 核心容器提供IoC

Spring AOP

面向切面编程

Spring web

提供了针对web开发的特性

Spring Dao

集成了JDBC , 简化了DAO的开发步骤

Spring ORM

整合了第三方持久层框架

Spring MVC

提供了web的MVC实现

响应式编程 

根据数据流和变化做出响应 , 通过异步和回调的方式 .

如何在上下文中获取bean

  1. ContextLoader
  2. new FileSystemXmlApplicationContext("applicationContext.xml");
  3. WebApplicationContextUtils

TCP和UDP的区别

TCP需要建立连接,UDP不需要建立连接 TCP的数据是可靠的,UDP不可靠 TCP的采用流的形式,UDP是报文的形式

对比Vector、ArrayList、LinkedList有何区别?

Vector和ArrayList都是数组形式的集合,Vector是线程安全的,ArrayList不是. ArrayList读取比较快,增删比较慢, LinkedLIst不是线程安全的,是链表形式的,他的增删比较快,但是读取慢 ArrayList初始容量是10,当有数组添加时才真正的分配容量 每次都是通过copyOf的方式扩容到之前的1.5倍

关于索引

索引的数据结构是:B+树 B-树 散列表 索引是放在内存中的,可以实现快速查询,但是会降低更新表的速度。 索引不走like,但是‘xx%’会走 索引列不能有null值

SQL优化

尽量在经常用的where和order by上建索引 尽量不要用in not in ,会扫描全表 尽量少用or ,会放弃索引

SOA

面向服务的架构 , 松耦合 位置透明 可在异构平台复用 便于测试

dubbo和Spring cloud

Dubbo是一个开源的SOA治理方案,是一个分布式服务框架。 注册中心严重依赖第三方zookeeper或者redis,组件出现问题,服务会中断 Dubbo只支持RPC调用 SpringCloud有自己的注册组件Eureka 支持RESTfulAPI 消息组建是Stream 集成了MQ和Apache kafka

ThreadLocal

线程本地副本 每个线程都会有一个副本,ThreadLocal创建的副本是存在线程的ThreadLocals里面 应用在数据库连接 session管理方面 解决了线程安全问题 线程可以随时访问 适用set/get方法。

Serializable序列化

java支持序列化机制,将一个对象表示为一个字节序列

callable和runable的区别

callable的方法是call(),runnable的方法是run() Callable执行方法有返回值 Runnable的执行方法没有返回值 Callable返回一个Future对象,可以通过get获取结果

volatile关键字

具有可见性,就是被修饰的变量,一旦被其他线程修改,会立即同步给主存,让其他线程知道 没有原子性 因为被修饰的变量可以被多线程修改

线程池

频繁的创建和销毁线程会降低工作效率 提高线程利用率 常用参数 corePoolSize(线程池大小) maximumPoolSize(最大线程数) keepAliveTime(可空闲时间) 执行顺序 1. 当前线程小于核心线程数,创建线程 2. 当前线程大于核心线程数,进入任务队列 3. 任务队列满了,核心线程数小于最大线程数,创建线程 4. 抛出异常

Integer的缓存范围

-127~128

synchronized和锁(ReentrantLock) 区别

synchronized最慢 synchronized和lock是实现同步锁(原子性)的两种方式 Lock提供了更广泛,更优雅的方式. synchronized在执行完后会自动释放,lock要手动释放 synchronized是jvm里面的,是java的关键字,lock是一个类 synchronized会让等待的线程一直等待,lock会尝试获得锁

如何保证集合是线程安全的

ConrurentHashMap做了什么 线程安全:Vector HashTable StringBuffer 线程不安全:ArrayList LinkedList HashMap HashSet TreeMap TreeSet StringBuilder Collections.synchronizedMap()可以使集合线程安全 ConrurentHashMap是线程安全的HashMap

对比HashTable HashMap TreeMap

谈谈你对HashMap的掌握 HashMap不是线程安全的,以数组方式存储Key-value构成的Entry对象,无限量扩容,扩容时要重新计算Hash

理解java的字符串

String StringBuffer StringBuider有什么区别 String 是不可变的,不能被继承和修改,用final修饰的类,线程安全. StringBuffer可以被改变,但是线程不安全. StringBuilder也是可变的,线程安全.

什么情况下java程序会产生死锁

如何排除 线程T1和T2,T1获得L1,但是要获得L2后才能释放L1,T2获得L2,但是要获得L1以后才能释放L2,这样有可能会出现死锁,避免方式是加synchronized同步锁.

JVM运行模块

程序计数器(相当于指针 不共享) 虚拟机栈 (运行时的数据,方法 不共享) 方法区 (常量,类信息,变异后的代码 线程共享) 堆 (创建的对象 线程共享) 本地方法栈 (本地方法运行时的数据 不共享)

Spring用到了那些设计模式

简单工厂模式

BeanFactory根据标识创建bean的过程

单例模式

singleton作用域创建的bean , SpringIoC容器中只有一个对应的实例 .

代理模式

SpringAOP基于JDK的动态代理

适配器模式

观察者模式

ApplicationListener的实现 . 定义一种一对多的关系 , 当一个对象状态发生改变时 , 其他的对象也对应发生改变 .

策略模式

SpringBoot

不是一个框架,而是快速构建项目的方式 默认的代码和注释配置 以最少的配置或者零配置开发和构建 适用新项目,不适合将SpringFramework的项目转化 SpringBoot约定过配置,不需要声明资源映射,资源映射会自动处理。

Spring线程安全

单例模式不一定线程安全,涉及多线程时要对其改造,一般是加锁或者适用threadlocal。

ZooKeeper

在分布式系统中 协调各个节点 监视各个节点的状态 根据节点提交的反馈进行下一步的合理操作
提供了文件系统 通知机制
根据是否持久化 / 是否有编号 分为四种znode节点 .
通知机制 是watch关心的节点 当发生变化时 , 通知客户端 .
命名服务
唯一的path 可以通过path相互发现
配置管理
管理配置 , 将配置信息放到zk的节点上去 并监听对应的节点 当有配置发生变化时可以通知应用程序 .
集群管理
有新的节点加入或退出 选举master
分布式锁
可以把zk的节点当做一把锁 , 所有程序都去创建这个节点 , 成功的即得到锁 , 用完删除即可释放锁 .
其他未得到锁的程序可以排序创建节点 , 等锁释放了 , 按照顺序得到锁 .

Spring bean的作用域和生命周期

singleton

单例作用域下 scope = singleton , 表示一个bean 在Spring IoC 容器中只有一个实例 .

prototype

prototype作用域中 , 每一次请求都会创建一个实例 , 并配置和装饰 , 但不会调用对象的生命周期回调函数 , 不会负责bean的生命周期 .

request / session

在每一次的HTTP 的request / session中创建实例 , 并且尽在request / session中有效 .  

谈谈java反射机制, 动态代理是基于什么原理

java的反射机制可以获得对象的类 , 以及属性 , 方法 , 和构造函数 .

动态代理基于反射机制 . IoC的依赖注入也是基于反射机制 . 

抽象类和接口的区别是什么

抽象类通过extends继承 ,  接口是通过implements实现接口 .

抽象类可以有构造器 , 接口没有构造器 .

抽象类和接口都不能实例化

接口中的方法只能是public的 , 但抽象方法没有限制 

只能继承一个抽象类 , 可以实现多个接口 

事务的四个特性

原子性

事务要完整 , 要么全部做完 , 要么没有做

一致性

事务开始到结束 , 数据库的完整约束没有变 .

隔离性

事务在访问数据库时 , 不被干扰 , 相互隔离 .

持久性

事务完成后 , 数据库不能回滚 .

MySql支持的隔离级别

读未提交 read-uncommited

读已提交 read-commited

可重复度 repeateable - read

串行化 serializable 

脏读

不可重复读

幻读

悲观锁和乐观锁的原理和应用场景

 

谈谈你对几种常见排序算法的理解

 

你解决过的最大并发是多少 你采用了那些方法 获得了什么成效

使用缓存技术 / 查询语句的优化 / 优化表结构加索引 / 集群的方式

进程和线程的区别

 

Spring的异常处理 如何返回错误信息

  1. 可以通过web.xml中的error-page来配置错误状态码 / 异常的跳转页面
  2. 实现HandlerExceptionResolver接口 , Spring提供了默认的实现类SimpleMappingExceptionResolver , 要在配置文件中配置 , 实现resolveException方法 , 返回一个ViewandModel
  3. 在类中实现 , 用@ExceptionHandler

Nigix的理解

基于C开发 / 跨平台 / 可以作为HTTP服务器作为网站的发布处理 / 作为反向代理服务器实现负载均衡

表分区

将一个数据表和索引分别存储在不同的物理文件中

-- 增加
partition by range(id){
    partition user_1 values less than (10),
    partition user_2 values less than (20)      
}

--删除
alter table user drop partition user_1 ;
alter talbe user drop partition user_2;

分区的表不支持外键 , 可能会让索引失灵 .

JDBC操作数据库步骤

  1. 加载驱动  Class.forName()
  2. 获得连接  DriverManager.getConnection()
  3. 创建statement / preparestatement对象  conn.createStatement
  4. 执行SQL获得结果  stmt.executeQuery()

Dubbo

SpringCloud

ActiveMQ

集合基础操作

map.get(key);
map.put(key, value);

list.get(location);
list.add(object);

boolean flag = set.add(object);

dataType[] array = new dataType[size]

类加载过程

加载 - 连接(验证 - 准备 - 解析) - 初始化 - 使用 - 卸载

加载
将class加载到jvm的方法区中
连接
验证 检验加载类是否有问题
准备 将静态变量分配内存
解析 将符号转化成直接引用
初始化
执行Static静态的代码块 - 执行构造函数 (从父类开始)

BootstrapClassLoader   jre/lib/rt下的

ExtensionClassLoader  jre/lib/ext下的

AppClassLoader   classpath下的

CustomClassLoader  自定义的

posted @ 2018-07-19 23:26  EmbraceU  阅读(304)  评论(0编辑  收藏  举报