日常理解
{
空
}
1. 什么叫线程安全?servlet是线程安全吗?
{
答:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
servlet不是线程安全的,每个servlet都只被实例化一次,每个调用都是servlet的同一个实例,并且对类变量没有线程安全,数据量大的时候容易照成异常。
}
2. 同步有几种实现方法?
{
答:同步的实现方面有两种,分别是synchronized,wait与notify
}
Thread join yield
{
thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。
thread.yield 当前线程回到可执行状态,以便让具有相同优先级的线程进入执行状态,但不是绝对的
}
ThreadLocal
{
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题,那么,ThreadLocal和线程同步机制相比有什么优势呢?
在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序缜密的分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大
而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal为每一个线程提供一个独特的变量副本,从而隔离了多个线程对访问数据的冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的对象封装,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。看了
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式:访问串行化,对象共享化。而ThreadLocal采用了“以空间换时间”的方式:访问并行化,对象独享化。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
}
JVM 处理器重排序
{
一般来说,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。
i = 1; //语句1
flag = true; //语句2
语句1.语句2 执行顺序不确定,他么之间的执行 没有数据依赖关系
int a = 10; //语句1
int r = 2; //语句2
a = a + 3; //语句3
r = a*a; //语句4
语句3 必须在语句4之前执行
如果一个指令Instruction2必须用到Instruction1的结果,那么处理器会保证Instruction1会在Instruction2之前执行
虽然重排序不会影响单个线程内程序执行的结果 但是会影响到线程并发执行的正确性。
也就是说,要想并发程序正确地执行,必须要保证原子性、可见性以及有序性。只要有一个没有被保证,就有可能会导致程序运行不正确。
}
原子性、可见性以及有序性
{
Java内存模型并没有限制执行引擎使用处理器的寄存器或者高速缓存来提升指令执行速度,也没有限制编译器对指令进行重排序。也就是说,在java内存模型中,也会存在缓存一致性问题和指令重排序的问题。
原子性
简单的读取、赋值(而且必须是将数字赋值给某个变量,变量之间的相互赋值不是原子操作)才是原子操作。
x = 10; //语句1
y = x; //语句2 读取x 赋值给y
x++; //语句3 读取x x+1操作 赋值给x 三步
x = x + 1; //语句4 读取x x+1操作 赋值给x 三步
只有语句1是原子性的
Java内存模型只保证了基本读取和赋值是原子性操作,如果要实现更大范围操作的原子性,可以通过synchronized和Lock来实现。由于synchronized和Lock能够保证任一时刻只有一个线程执行该代码块,那么自然就不存在原子性问题了,从而保证了原子性
可见性
对于可见性,Java提供了volatile关键字来保证可见性。
保证了不同线程对这个volatile修饰的变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。另外,通过synchronized和Lock也能够保证可见性,synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中。因此可以保证可见性。
有序性
在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。
Java内存模型具备一些先天的“有序性”,即不需要通过任何手段就能够得到保证的有序性,这个通常也称为 happens-before 原则。如果两个操作的执行次序无法从happens-before原则推导出来,那么它们就不能保证它们的有序性,虚拟机可以随意地对它们进行重排序
}
happens-before原则
{
下面就来具体介绍下happens-before原则(先行发生原则):
程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作
volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作
线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始
这8条原则摘自《深入理解Java虚拟机》。
这8条规则中,前4条规则是比较重要的,后4条规则都是显而易见的。
}
3. volatile有什么用?能否用一句话说明下volatile的应用场景?
{
http://www.importnew.com/18126.html
保证了不同线程对这个volatile修饰的变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中
Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。
应用场景
synchronized关键字是防止多个线程同时执行一段代码,那么就会很影响程序执行效率,而volatile关键字在某些情况下性能要优于synchronized,但是要注意volatile关键字是无法替代synchronized关键字的,因为volatile关键字无法保证操作的原子性。通常来说,使用volatile必须具备以下2个条件:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中
实际上,这些条件表明,可以被写入 volatile 变量的这些有效值独立于任何程序的状态,包括变量的当前状态。
事实上,我的理解就是上面的2个条件需要保证操作是原子性操作,才能保证使用volatile关键字的程序在并发时能够正确执行。
下面列举几个Java中使用volatile的几个场景。
1.状态标记量
volatile boolean flag = false;
while(!flag){
doSomething();
}
public void setFlag() {
flag = true;
}
volatile boolean inited = false;
//线程1:
context = loadContext();
inited = true;
//线程2:
while(!inited ){
sleep()
}
doSomethingwithconfig(context);
2.double check
class Singleton{
private volatile static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if(instance==null) {
synchronized (Singleton.class) {
if(instance==null)
instance = new Singleton();
}
}
return instance;
}
}
}
4. 请说明下java的内存模型及其工作流程。
{
答:Java把内存划分成两种:一种是栈内存,一种是堆内存。
栈内存:存放对象:函数中基本类型的变量和对象的引用变量、静态类方法 ;特点:栈有一个很重要的特殊性,就是存在栈中的数据可以共享。
堆内存:存放对象:用来存放由new创建的对象和数组;特点:在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
java 内存模型 ( java memory model ):根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有对象成员变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些对象成员变量的拷贝,线程对所有对象成员变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。
(1) 获取对象监视器的锁(lock)
(2) 清空工作内存数据, 从主存复制对象成员变量到当前工作内存, 即同步数据 (read and load)
(3) 执行代码,改变共享变量值 (use and assign)
(4) 将工作内存数据刷回主存 (store and write)
(5) 释放对象监视器的锁 (unlock)
}
5. 为什么代码会重排序.
{
由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中
}
6. 如何让一段程序并发的执行,并最终汇总结果
{
cyclibarrier
它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
的应用场景
CyclicBarrier可以用于多线程计算数据,最后合并计算结果的应用场景。比如我们用一个Excel保存了用户所有银行流水,每个Sheet保存一个帐户近一年的每笔银行流水,现在需要统计用户的日均银行流水,先用多线程处理每个sheet里的银行流水,都执行完之后,得到每个sheet的日均银行流水,最后,再用barrierAction用这些线程的计算结果,计算出整个Excel的日均银行流水。
}
CyclicBarrier和CountDownLatch的区别
{
CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。
CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。比如以下代码执行完之后会返回true。
}
CountDownLatch{
CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行
构造器中的计数值(count)实际上就是闭锁需要等待的线程数量。这个值只能被设置一次,而且CountDownLatch没有提供任何机制去重新设置这个计数值。
与CountDownLatch的第一次交互是主线程等待其他线程。主线程必须在启动其他线程后立即调用CountDownLatch.await()方法。这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。
}
如何合理的配置java线程池?如CPU密集型的任务,基本线程池应该配置多大?IO密集型的任务,基本线程池应该配置多大?用有界队列好还是无界队列好?任务非常多的时候,使用什么阻塞队列能获取最好的吞吐量?
{
线程池的配置都需要结合系统真实情况(比如是IO密集型或者是CPU密集型或者是纯内存操作)和硬件环境(CPU、内存、硬盘读写速度、网络状况等)来不断尝试达到一个符合实际的合理估算值。基本上IO密集型的线程池要比Cpu密集型的线程池大1倍左右
}
java类加载器
{
Bootstrap ClassLoader
负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
Extension ClassLoader
负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/ lib / *.jar或-Djava.ext.dirs指定目录下的jar包
App ClassLoader
负责记载classpath中指定的jar包及目录中class
Custom ClassLoader
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader
加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader 逐层检查 ,只要某个classloader已加载就视为已加载此类,
保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
先检查是否加载(从下往上),再加载(从上往下)
}
java类加载器的双亲委派模型:
{
双亲委派模型是一种组织类加载器之间关系的一种规范,他的工作原理是:如果一个类加载器收到了类加载的请求,它不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,这样层层递进,最终所有的加载请求都被传到最顶层的启动类加载器中,只有当父类加载器无法完成这个加载请求(它的搜索范围内没有找到所需的类)时,才会交给子类加载器去 尝试 加载.
这样的好处是:java类随着它的类加载器一起具备了带有优先级的层次关系.这是十分必要的,比如java.lang.Object,它存放在\jre\lib\rt.jar中,它是所有java类的父类,因此无论哪个类加载都要加载这个类,最终所有的加载请求都汇总到顶层的启动类加载器中,因此Object类会由启动类加载器来加载,所以加载的都是同一个类,如果不使用双亲委派模型,由各个类加载器自行去加载的话,系统中就会出现不止一个Object类,应用程序就会全乱了.
}
7. 何使用阻塞队列实现一个生产者和消费者模型?请写代码。
8. 多读少写的场景应该使用哪个并发容器,为什么使用它?比如你做了一个搜索引擎,搜索引擎每次搜索前需要判断搜索关键词是否在黑名单里,黑名单每天更新一次。
9. 如何实现乐观锁(CAS)?如何避免ABA问题?
{
CAS sql : update table set value = value1 where vrsn = vrsn1;
如果V值首先由A变成B,在由B变成A 这样CAS的时候还是会有问题
解决方法:不是只是更新某个引用的值, 而是更新两个值,包含一个引用和一个版本号。即使这个值由A变成B,然后又变为A,版本号也将是不同的
}
10. 读写锁可以用于什么应用场景?
{
}
11. 什么时候应该使用可重入锁?
12. 什么场景下可以使用volatile替换synchronized?
13. 如何实现一个流控程序,用于控制请求的调用次数?
*******************************************************************************************************************************
1、 如何实现分布式事务,你们公司是怎么解决的?
二阶段提交
2、 HashMap数据结构及实现原理,其链表是用来解决什么问题的
3、 可以自定义java.lang.String类吗,说明为什么
ConcurrentHashMap和HashMap和HashTable
http://blog.csdn.net/basycia/article/details/51890699
HashMap本质数组加链表。根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面。
HashTable差别为同步和值不可非空,效率问题,具体如下介绍;ConcurrentHashMap和HashTable在于效率,算法的变更
*******************************************************************************************************************************
*******************************************************************************************************************************
6、zookeeper
1) 说说选举算法
2) 有哪几种节点类型
3) 有哪些应用场景
4) 如何部署集群,至少有几台机器?
*******************************************************************************************************************************
nginx
*******************************************************************************************************************************
nginx
正向代理与方向代理
{
正向代理:针对客户端而言, 代理服务器代理客户端,转发请求,并将获得的内容返回给客户端。
反向代理:针对客户端而言, 代理服务器就像是原始服务器,代理集群的web节点服务器返回结果。
正向代理:代理端代理的是客户端。
反向代理:代理端代理的是服务端。
}
负载均衡策略
{有2种:内置策略和扩展策略。
内置策略为轮询,加权轮询,Ip hash。
1.加权值越大,接受更多的请求 2.对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题
扩展策略
}
*******************************************************************************************************************************
12、mysql
1) 如何进行sql优化?如何进行性能检测
2) 有哪几种索引类型及应用场景
{
FULLTEXT
目前只有MyISAM引擎支持 只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引
它的出现是为了解决WHERE name LIKE “%word%"这类针对文本的模糊查询效率较低的问题。在没有全文索引之前,这样一个查询语句是要进行遍历数据表操作的,可见,在数据量较大时是极其的耗时的
Hash
其实,hash就是一种(key=>value)形式的键值对,如数学中的函数映射,允许多个key对应相同的value,但不允许一个key对应多个value。正是由于这个特性,hash很适合做索引,为某一列或几列建立hash索引,就会利用这一列或几列的值通过一定的算法计算出一个hash值,对应一行或几行数据
(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。
由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
(2)Hash 索引无法被用来避免数据的排序操作。
由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
(3)Hash 索引不能利用部分索引键查询。
对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
(4)Hash 索引在任何时候都不能避免表扫描。
前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数(无法屋顶这个hash值具体对应哪个),也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。
BTREE
BTREE索引就是一种将索引值按一定的算法,存入一个树形的数据结构中,相信学过数据结构的童鞋都对当初学习二叉树这种数据结构的经历记忆犹新,反正愚安我当时为了软考可是被这玩意儿好好地折腾了一番,不过那次考试好像没怎么考这个。如二叉树一样,每次查询都是从树的入口root开始,依次遍历node,获取leaf。
BTREE在MyISAM里的形式和Innodb稍有不同
在 Innodb里,有两种形态:一是primary key形态,其leaf node里存放的是数据,而且不仅存放了索引键的数据,还存放了其他字段的数据。二是secondary index,其leaf node和普通的BTREE差不多,只是还存放了指向主键的信息.
而在MyISAM里,主键和其他的并没有太大区别。不过和Innodb不太一样的地方是在MyISAM里,leaf node里存放的不是主键的信息,而是指向数据文件里的对应数据行的信息.
RTREE
RTREE在mysql很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种
各种索引的使用情况
(1)对于BTREE这种Mysql默认的索引类型,具有普遍的适用性
(2)由于FULLTEXT对中文支持不是很好,在没有插件的情况下,最好不要使用。其实,一些小的博客应用,只需要在数据采集时,为其建立关键字列表,通过关键字索引,也是一个不错的方法,至少愚安我是经常这么做的。
(3)对于一些搜索引擎级别的应用来说,FULLTEXT同样不是一个好的处理方法,Mysql的全文索引建立的文件还是比较大的,而且效率不是很高,即便是使用了中文分词插件,对中文分词支持也只是一般。真要碰到这种问题,Apache的Lucene或许是你的选择。
(4)正是因为hash表在处理较小数据量时具有无可比拟的素的优势,所以hash索引很适合做缓存(内存数据库)。如mysql数据库的内存版本Memsql,使用量很广泛的缓存工具Mencached,NoSql数据库redis等,都使用了hash索引这种形式。当然,不想学习这些东西的话Mysql的MEMORY引擎也是可以满足这种需求的。
(5)至于RTREE,愚安我至今还没有使用过,它具体怎么样,我就不知道了。有RTREE使用经历的同学,到时可以交流下!
}
3) 主备同步是如何进行的,原理是什么
{
主库将数据变更写到二进制的日志中,从库去主库中拉日志,写到从库的日志中,从库有线程去读取日志,写到从库里面
}
4) 分库分表有哪几种分法,如何解决数据分布不均匀的问题,如果避免查询某个字段扫全库全表的情况
5) 事务隔离级别有哪几种,默认是哪个
Read uncommitted 、Read committed 、Repeatable read 、Serializable
6) 如何解决幻读问题
7) 读写分离方案
8) 有哪几种引擎及应用场景
13、 mybatis占位符的#和$有什么区别
14、 如何实现分布锁,需要考虑的问题
15、 spring事务传播机制有哪些,如何用jdbc实现require_new
16、 java集合常用类及数据结构
*******************************************************************************************************************************
*******************************************************************************************************************************
18、设计模式
1) 说说六大设计原则
2) 你会哪些设计模式
3) 装饰模式和代理模式有什么区别
4) 单例模式有哪几种写法,有哪些注意的地方
5) 怎么实现策略模式
6) spring中用到了哪些设计模式
19、 线程有哪几种状态流转
20、 spring ioc aop是什么,实现动态代理有哪些方式,代理类和原来的类之间是什么关系
21、 什么是悲观锁和乐观锁,分别如何实现
22、 java有哪几种自带的线程池,说说它们的应用场景
java动态代理
{
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理
JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。
cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
Spring AOP中,当拦截对象实现了接口时,生成方式是用JDK的Proxy类。当没有实现任何接口时用的是GCLIB开源项目生成的拦截类的子类.
}
*******************************************************************************************************************************
23、 说说volatile关键字及使用场景
24、 怎么排查多线程问题
25、 session共享有哪些方案
26、 jvm有哪些自带命令及如何使用
27、 说说jvm内存模式及如何调优
28、 如何对tomcat调优
29、 用户登录有哪些保障安全的手段
30、 如何减库存,如何防止超买超卖
31、 TCP协议为什么是三次握手四次挥手,为什么不是别的
{
这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。
}
32、 HTTP报文有哪几个部分
*******************************************************************************************************************************
33、 接口安全如何做
34、 要你实现RCP框架,你会注重什么
35、 linux查看cpu、内存、硬盘、网络IO、负载、端口占用情况、及某个具体进程的命令
36、 说说一致性hash算法
37、 说说类加载机制,它们是怎么设计的
38、 你怎么做职业规划的,未来三年你有什么规划
39、 你目前手中有哪些offer,你会考虑我们公司吗,你对我们公司有什么想要了解的
40、 你为什么要离职(这个要慎重,千万不要抱怨前任公司,更不要说坏话,不然你技术再牛逼也过不了)
*******************************************************************************************************************************
Spring Bean的生命周期
Spring AOP的定义与原理,运行时增强还是编译时增强
HashMap,TreeMap,Hashtable,LinkedHashMap实现原理及对比
Linux系统了解程度
ConcurrentHashMap实现原理
脏读与幻读
ThreadLocal如何实现线程隔离
ThreadLocal在Spring中的应用
类加载器与加载过程
Spring bean后处理器与容器后处理器
抽象类与接口适用场合
Java IO:BIO,NIO,AIO
CDN
base64设计目的
节点流与过滤流
Spring事务传播行为
volatile关键字
乐观锁与悲观锁
语法糖概念
搜索引擎倒排索引
线程的几种状态
线程间通信
秒杀功能的实现
一致性HASH算法
操作字节码
RPC底层实现,动态代理起所起得作用
SQL优化及数据库索引原理,B-tree
设计模式
JAVA回调机制
延迟加载(lazyload)的实现原理
拦截器与过滤器区别
事务四种隔离级别
java中会存在内存泄漏吗
消息中间件的意义和应用场景
CAS
Spring 事务编程式事务处理
mysql 内存锁 get_lock,release_lock
java.util.concurrent.ExecutorService
X/Open DTP
B-tree R-tree T-tree
缓存穿透与缓存雪崩
缓存与内存数据库
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
外部数据---数据管理中心--规则平台 数据规则处理 符合规则--沉淀下来--供业务系统使用
数据规则平台
对外部合作机构推送的数据进行校验和处理, 符合业务规则的数据沉淀下来供业务系统使用,一个数据模版包含模版简述,模块(模块下可有子模块),字段,数据规则.
数据规则类型包含数据校验,数据预警,数据清洗,数据拉平
数据预警 缺少字段报警
数据校验 字段是否符合该字段属性要求 手机号 邮箱 身份证 为空为null 长度
数据拉平 json字符串嵌套比较深 直接把嵌套拉平成K,V
数据清洗 日期的转换,
数据模版数据结构
模版简述
模块
字段
数据规则(模块,字段约束)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
授信申请,提供申请的核心能力,比如前准入.在途、渠道保护、提交申请等能力。对于外部系统来说,关心一笔贷款贷前的生命周期,只要关心平台申请就好。
调查审批:提供信贷管控能力,包含自动审批与人工审批 人工审批会启动调查采集流程,调查下采集结束后进入审批流程,运营人员更具调查采集的数据结合信贷决策系统给出的推荐授信得出最终的审批结论
申请成功 同步申请信息后 启动调查采集流程 调查采集项与运营产品关联,调查采集结束启动审批流程 审批通过后固化授信到信贷决策系统,同步申请状态给其他业务系统
调查采集项
征信报告 法院执行网信息 工商报告 汇法网信息 法人工商报告 借款人信息,大数贷模式下行业的采集数据
贷前调查报告:公司基本信息(工商信息,用户信息),公司经营信息(销售,流水,资产)网络负面(汇法网 百度信息 执行网)负债情况
授信申请后台 提供授信申请常用的后台功能,方便测试与查询
包含后台报名 申请查询 在途准入 贷款准入 异步命令等功能
机构服务聚合平台
借助支付宝开放平台将网商银行资金,授信,风控等能力输出给外部合作机构,目前主要以平台贷和大数贷两种合作模式
基于以上两种模式提供了一系列相对通用的接口 协议签署,协议查询 贷前咨询 会员创建 合作机构数据接入 放款,还款等接口
开放平台接口开发,测试,联调.以及日常迭代.现主要负责大数贷业务线外部机构申贷,审批,支用,还款等流程对接