排序
冒泡排序:两两对比,每次找到这组最大的,最后得效果得每次排序都把最大的放到后面 O(n^2)
选择排序:每次找出最小得放到队列前面 O(n^2)
插入排序:第一次排好前2个,第二次排好前3个,第三次排好前4个 O(n^2)
快速排序:以指定值把队列分成两半,然后对每一半进行循环分成两半 O(nlogn)
希尔排序:分成长度/2组,直到分成1组。O(nlogn)
归并排序:把队列分成2份并且有序,然后创建两个指针,一个一个的把小球放到临时队列中O(nlogn)
加密算法
对称算法:DES,3DES,AES
非对称算法:RSA,DSA
散列算法:MD5,SHA-1
本地存储
localStorage 用法:localStorage.setItem(Key,Value);
sessionStorage 用法:sessionStorage.setItem(Key,Value);
浏览器事件传播机制
捕获:事件对象从 window ==》目标对象父级的过程
目标:事件对象派发到目标元素时的阶段
冒泡:与是以目标对象父级 ==》到 window 的过程
常见JS的DOM操作
浏览器渲染过程
构建dom树
构建render树
布局render树
绘制render树
跨域问题
document.domain + iframe
location.hash + iframe
window.name + iframe
postMessage
CORS
JSONP
web sockets
动态创建script
浏览器安全
XSS:跨站点脚本攻击,注入JS。1.非持久性跨站点脚本攻击 2.持久的跨站点脚本攻击 3. 基于dom的跨站点脚本攻击
CSRF:伪装Cookie攻击。
防御手段:1.判断请求头中的 Referer 2.在请求参数中加入 csrf token 3.新增Http请求头,将 token 放在请求头中
SpringMVC流程
DispatcherServlet ==> HandlerMapping ==> Handler ==> HandlerAdapter ==> ModelAndView == > ViewResolver
1.用户发送请求到前端控制器DispatcherServlet。
2.DispatcherServlet收到请求,调用HandlerMapping处理器映射器。
3.处理器映射器HandlerMapping找到具体的处理器,解析请求对应的Handler。
4.解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由 HandlerAdapter 适配器处理。
5.HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑。
6.处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。
7.ViewResolver 会根据逻辑 View 查找实际的 View。
8.DispaterServlet 把返回的 Model 传给 View(视图渲染)
9.把 View 返回给请求者(浏览器)
AOP实现技术
AOP(这里的AOP指的是面向切面编程思想,而不是Spring AOP)主要的的实现技术主要有Spring AOP和AspectJ。
AspectJ的底层技术是静态代理,该代理类增强了业务类,这是在编译时增强。
Spring AOP采用的是动态代理,在运行期间对业务方法进行增强,所以不会生成新类,对于动态代理技术,Spring AOP提供了对 JDK动态代理的支持以及CGLib的支持。
JDK动态代理只能为接口创建动态代理实例,而不能对类创建动态代理。需要获得被目标类的接口信息(应用Java的反射技术),生成一个实现了代理接口的动态代理类(字节码),再通过反射机制获得动态代理类的构造函数,利用构造函数生成动态代理类的实例对象,在调用具体方法前调用invokeHandler方法来处理。
CGLib动态代理需要依赖asm包,把被代理对象类的class文件加载进来,修改其字节码生成子类。
创建线程池的四种方式
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。以共享的无界队列方式来运行这些线程。如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。线程池的大小一旦达到最大值就会保持不变。
newScheduledThreadPool 创建一个定长的(大小无限制)线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。【使用单个线程执行的线程池,特点是先进先出、先进后出、带优先级】
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。【注:创建与实际需求相符合的线程池】
阻塞队列
BlockingQueue是双缓冲队列。BlockingQueue内部使用两条队列,允许两个线程同时向队列一个存储,一个取出操作。在保证并发安全的同时,提高了队列的存取效率。
我们知道队列是先进先出的。当放入一个元素的时候,会放在队列的末尾,取出元素的时候,会从队头取。那么,当队列为空或者队列满的时候怎么办呢。这时,阻塞队列,会自动帮我们处理这种情况。
当阻塞队列为空的时候,从队列中取元素的操作就会被阻塞。当阻塞队列满的时候,往队列中放入元素的操作就会被阻塞。后,一旦空队列有数据了,或者满队列有空余位置时,被阻塞的线程就会被自动唤醒。
ArrayBlockingQueue这是一个由数组结构组成的有界阻塞队列,它没有实现读写分离,也就是说,读和写是不能同时进行的。因为,它读写时用的是同一把锁。
LinkedBlockingQueue这是一个由链表结构组成的有界阻塞队列,实现了读写分离,可以实现数据的读和写互不影响。
SynchronousQueue这是一个没有缓冲的无界队列,Size方法总是返回 0 ,因为它是一个没有容量的队列。当执行插入元素的操作时,必须等待一个取出操作。也就是说,put元素的时候,必须等待 take 操作。适用于并发任务不大,而且生产者和消费者的速度相差不多的场景下,直接把生产者和消费者对接,不用经过队列的入队出队这一系列操作。所以,效率上会高一些。Excutors.newCachedThreadPool 方法用的就是这种队列。
PriorityBlockingQueue这是一个支持优先级排序的无界队列。它基于二叉树最小堆实现的,每当取元素的时候,就会把优先级最高的元素取出来。
DelayQueue这是一个带有延迟时间的无界阻塞队列。队列中的元素,只有等延时时间到了,才能取出来。此队列一般用于过期数据的删除,或任务调度。
线程生命周期
New | New状态是线程实例化后还没有执行start()方法的状态。new Thread().getState(); |
RUNNABLE | 线程进入运行的状态。 即 Thread t1 = new Thread(); t1.start(); |
TIMED_WAITING | 有时间限制的等待。 即线程调用了Thread.sleep(XXX)方法后的状态。 |
WAITING | 线程执行了 lock.wait() 后的状态。 永久等待,直到被另外一个线程lock.notify() |
BLOCKED | 当一个线程在等待同步锁时,线程状态为BLOCKED |
TERMINATED | 当任务执行完毕后的状态 |
不释放锁
sleep(),yeild()
调用 sleep() 方法使线程进入等待状态,等待休眠时间达到,则继续执行。而调用我们的 yield() 方法,线程会进入就绪状态,也就是sleep()需要等待设置的时间后才会进行就绪状态,而yield会立即进入就绪状态,准备下次竞争CPU时间片。
释放锁
wait(),join()
A线程的任务中出现 B.join(); 那么A线程需要等待B线程任务执行完毕再继续执行。线程A调用 otherThread.join()方法,那么线程A进入 WAITING 状态,内部使用的是 wait()方法实现,所以会释放同步锁。
notify和notifyAll都会释放锁,但是不是立即释放锁而是会等到其synchronized内中的代码全部执行完之后,才会释放锁。
分区分表规则
分区
分区并不是生成新的数据表,而是将表的数据均衡分摊到不同的硬盘或服务器存储上,实际上还是一张表。它把一张表的数据分成N个区块,在逻辑上看最终只是一张表,但底层是由N个物理区块组成的
水平分区:对表的行进行分区。比如十年的发票,按照年份分成十个区。
垂直分区:使某些特定的列被划分到特定的分区。比如不常使用的大字段【商品描述】可以划分到另外一个分区。
分表
分表就是把一张表按一定的规则分解成N个具有独立存储空间的实体表。一旦分表,一个库中的表会越来越多。
水平分表:school_001、school_002
垂直分表:例如把存储大图片、大BLOB对象的列单独抽出一张表,与原来的表一一对应。
分区和分表的区别与联系
分区和分表的目的都是减少数据库的负担,提高表的增删改查效率。
分区只是一张表中的数据的存储位置发生改变,分表是将一张表分成多张表。
当访问量大,且表数据比较大时,两种方式可以互相配合使用。
当访问量不大,但表数据比较多时,可以只进行分区。
分表的规则策略
- Range(范围)
- Hash(哈希)
- 按照时间拆分
- Hash之后按照分表个数取模
- 在认证库中保存数据库配置,就是建立一个DB,这个DB单独保存user_id到DB的映射关系
Java基础
面向对象最小的程序单元是:类
封装说明一个类行为和属性与其他类的关系
继承是父类和子类的关系
多态说的是类与类的关系