方案1:前端
经过join方法保证多线程的顺序性的特性java
join:让主线程等待子线程执行完成后,主线程才执行。这里join是调用的Object的wait方法node
package com.lzy; public class Main { static Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread1"); } }); static Thread thread2 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread2"); } }); static Thread thread3 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread3"); } }); static Thread thread4 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread4"); } }); public static void main(String[] args) throws InterruptedException { thread1.start(); thread1.join();// 这里的thread1.join是让主线程wait thread2.start(); thread2.join(); thread3.start(); thread3.join(); thread4.start(); } }
方案2:mysql
static ExecutorService executorService = Executors.newSingleThreadExecutor();// FIFO
executorService.submit(thread1); executorService.submit(thread2); executorService.submit(thread3); executorService.submit(thread4);
这种方式是使用了单线程配合队列(LinkedBlockingQueue)完成的。nginx
代码git
方案3:web
经过共享对象锁加上可见变量来实现ajax
public class MyService { private volatile int orderNum = 1; // 共享变量 public synchronized void methodA() { try { while (orderNum != 1) { wait(); // 当前线程让出CPU } for (int i = 0; i < 2; i++) { System.out.println("AAAAA"); } orderNum = 2; notifyAll(); // 通知其余线程启动 } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void methodB() { try { while (orderNum != 2) { wait(); } for (int i = 0; i < 2; i++) { System.out.println("BBBBB"); } orderNum = 3; notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void methodC() { try { while (orderNum != 3) { wait(); } for (int i = 0; i < 2; i++) { System.out.println("CCCCC"); } orderNum = 1; notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } }
import service.MyService; public class ThreadAA extends Thread { private MyService dbtools; public ThreadAA(MyService dbtools) { super(); this.dbtools = dbtools; } @Override public void run() { dbtools.methodA(); } }
import service.MyService; public class ThreadBB extends Thread { private MyService dbtools; public ThreadBB(MyService dbtools) { super(); this.dbtools = dbtools; } @Override public void run() { dbtools.methodB(); } }
import service.MyService; public class ThreadCC extends Thread { private MyService dbtools; public ThreadCC(MyService dbtools) { this.dbtools = dbtools; } @Override public void run() { dbtools.methodC(); } }
import extthread.ThreadCC; import service.MyService; import extthread.ThreadAA; import extthread.ThreadBB; public class Run { public static void main(String[] args) { MyService myService = new MyService(); for (int i = 0; i < 2; i++) { ThreadBB output = new ThreadBB(myService); output.start(); ThreadAA input = new ThreadAA(myService); input.start(); ThreadCC threadCC = new ThreadCC(myService); threadCC.start(); } } }
共享对象锁,能够保证每一个方法只能同时有一个线程进入,配合wait和notifyall方法,能够启动或者唤醒线程。redis
1.什么是JMM算法
JAVA Memory Model
并发过程当中如何处理可见性、原子性、有序性的问题。
并发编程中的两个关键问题
a.线程之间如何通讯;wait()、notify()、notifyall()
a)共享内存 - 隐式通讯
b)消息传递 - 显式通讯
b.线程之间如何同步
在共享内存的并发模型中,同步是显式作的;synchronized
在消息传递的并发模型中,因为消息的并发必须在消息接受以前,全部同步是隐式
2.定位内存可见性问题
什么对象是内存共享的,什么不是(见 图1-1)
Volatile、synchronized
3.
a.对于声明了Volatile的变量进行写操做的时候,JVM会向处理器发送一条Lock前缀指令。会把这个变量所在的缓存行的数据写回到系统主内存中。
b.在多个处理器的状况下,保证各个处理器缓存一致性的特色,就会实现缓存一致性协议
synchronized:可重入锁、互斥性、可见性。
Volatile 能够作到原子性、可见性;不能作到复合操做的原子性。
Volatile | Synchronized |
执行控制 | |
内存可见 | 内存可见 |
线程不安全 | 线程安全 |
从主存中取数据 | 锁加 |
使用在变量级别 | 变量、方法 、类 |
不会线程阻塞 | 会线程阻塞 |
不能够被编译器优化 | 能够被编译器优化 |
图1-1
Lock和synchronized的区别
Java5之后出现的:juc(java.util.concurrent.locks)包
1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
2)synchronized在发生异常时,会自动释放线程占有的锁,所以不会致使死锁现象发生;而Lock在发生异常时,若是没有主动经过unLock()去释放锁,则极可能形成死锁现象,所以使用Lock时须要在finally块中释放锁;
3)Lock可让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不可以响应中断;
4)经过Lock能够知道有没有成功获取锁,而synchronized却没法办到。
5)Lock能够提升多个线程进行读操做的效率。
在性能上来讲,若是竞争资源不激烈,二者的性能是差很少的,而当竞争资源很是激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。因此说,在具体使用时要根据适当状况选择。
一个进程中包含不少线程。
1.继承Thread类,
2.实现Runnable接口,
3.使用ExecutorService(java5),
4.Callable Future带返回值的多线程操做
建立、就绪、运行、阻塞、终止
分布式锁是针对多进程同步。
解决方式:
1.经过数据库的方式解决
create table (
id,
method_name(惟一约束)
……
)
多个进程向数据库插入数据,返回结果大于1的获取锁,那么就能够去操做共享资源,释放锁是经过删除数据库中的这条记录。这种方式是利用了数据库设置的惟一约束性。
问题:删除失败怎么办;insert模式不是重入锁。
2.zookeeper方式
zookeeper节点特色:持久、持久有序、临时、临时有序。而且是树形、相似文件存储结构
咱们能够建立一个锁节点,而后每一个进程都向这个锁节点下建立一个临时有序节点,咱们把建立序号最小的节点做为得到锁的进程,带进程操做完了后,删除该进程建立的节点,此时剩下的节点中的最小节点就是获的锁的进程,可是该进程怎么知道本身获取到锁了呢?其实zookeeper还提供了watch机制,该机制是建立节点时绑定watch,即序号大的watch比他小的相邻的节点,以此类推,当小节点被删除后就会通知相邻大节点。
3.基于redis
setnx命令是只有当key不存在时才为key设置值,并返回0和1,能够根据返回值去判断谁得到了锁。
1. 集合框架中有哪些是安全的?
线程安全的有Hashtable、Vector、properties
2. 设计模式使用过哪些?
使用过模板模式、单例模式、策略模式、代理模式。
模板模式是使用在命令下发时,使用抽象类实现公共的步骤,主要是数据准备,各自的实现类去完成符合不一样设备的命令格式的数据,
策略模式是使用在数据解析上,咱们的项目会接受多个平台的数据,数据同样可是格式不同,这时就使用了策略模式去解析不一样格式的数据,返回同一格式的数据。
代理模式主要是使用在短信平台接入上,项目要求能够接入多个短信平台,这时就使用动态代理加载不一样的实现类。
单例模式主要是用在封装单线程处理队列任务的业务场景下,好比把数据放到LinkListBlockQueue中 ,开启单线程去处理这个队列。
3. 怎样实现多线程返回结果
Callable 配合Future实现待返回值的多线程,经过实现Callable的call方法,将callable传入到线程的submit方法中,最后经过Future获取结果
4. java 中的排序算法怎样实现的?
5. hashmap实现
6. Volatile关键字的做用
7. 单例模式中加上volatile关键字的做用
8.了解jvm吗
9. 双亲委派模型
10. gc运行过程
11. 线程池能够设置哪些参数
12. 线程池中怎样给线程命名
13.看过那些书
《重构改善既有代码的设计》、《java并发编程实战》、《Effective java》
14.java中给变量赋值是原子操做吗
1)除long和double以外的基本类型的赋值操做
2)全部引用reference的赋值操做
3)java.concurrent.Atomic.* 包中全部类的一切操做
count++不是原子操做,是3个原子操做组合
15.动态代理的实现方式
16. cglib动态代理有哪些缺陷
1. 不使用https怎样防止盗链?或者使用过怎样的签名方式
对用户的token,时间戳,参数等进行md5签名,服务器端判断是否被篡改。
2. 加解密:AES?
AES、Base64
3.若是jwt中token被盗窃了,怎样阻止用户登陆或者锁定帐号
1. 秒杀思路?
前端作页面静态化处理,使用ajax作时间同步,开启秒杀后,启动时加载商品数量好比20个,使用redis的原子操做incr判断当前是否超过了20人,前20名的请求进入到队列,并将这20个用户的信息存入到redis中,开启单线程去消费队列中的数据,操做数据库时,可使用乐观锁对数据枷锁,只要成功了就更新redis中的用户信息标记为秒杀成功,前端查询秒杀结果是经过ajax异步查询redis中的信息获得是否秒杀成功,
1. zookeeper 怎么使用?
2. ActiveMQ的做用?
实现系统之间的解耦
提供的消息类型有:TextMessage、MapMessage、ObjectMessage、ByteMessage 、StreamMessage
消息模式
p2p:一对一的,只要发送了,不论消费者在不在线,最终均可以接收到
发布/订阅:一对多,Topic模式,只有消费者在线才能够接受 ,也能够注册持久化订阅
2. spring cloud 有哪些模块
注册中心Eureka、Ribbon客户端负载均衡、Feign实现接口调用、Hystrix实现容错处理、zuul实现网关或者getWay、config实现配置中心。
3. nginx 负载均衡
轮训、权重、ip_Hash
4. 为何nginx性能这么高
得益于它的事件处理机制:
异步非阻塞事件处理机制:运用了epoll模型,提供了一个队列,排队解决
5.spring mvc请求过程
6. springbean的生命周期
9.http 常见状态码 40一、403
java语言提供的远程方法调用,服务接口集成remote,使用Naming.rebind方法发布服务,客户端使用Naming.lookup方法调用该服务
1. spring boot 怎样注入map属性?
springboot 的配置文件若是是properties就不能注入,若是是yml的就能够,使用缩进的格式定义key和value值
2. 在使用框架时,遇到哪些问题?
好比咱们常用配置文,并使用@Value注解将数据注入进去,可是我遇到在Controller中不能注册,老是说找不到,进过资料查找发现确实不能注入,由于spring 和springmvc有父子容器的概念,既是自容器能访问父容器内容,父容器不能访问自容器的内容,我只在父容器中配置了,并无在自容器中配置。
3. spring Bean生命周期
4. dubbo 支持那些协议
dubbo(默认)、hessian、http、redis、webservice、rmi、thrift、memached
5.dubbo支持序列化方式
dubbo 、jdk、fastjson、hessian2(默认)
6.zookeeper的数据结构
树下结构、znode
7.zookeeper使用的哪一个算法
paxos
8.spring中怎样加载properties的方式
9.
1. 作过哪些优化
2. sql层面作过哪些优化
3. tomcat 优化
1. 分库分表
2. 使用过mycat吗?
3. 当多张表联合查询时,其中一张表的索引不生效,怎样找出这个索引
使用explain查询执行计划
4. mysql 的整数类型有哪些
5.mysql怎样枷锁
select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values (…);
update table set ? where ?;
delete from table where ?;
6.mysql的事物隔离界别
1.读未提交,2.不可重复读,3.可重复读,4.串行化
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read-uncommitted) | 是 | 是 | 是 |
不可重复读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
7.教师表和学生表,老师之间有继承性,查出某个老师下的全部学生,表结构能够从新设计
teacher表
id 老师 父亲id
1 | A老师 | 0 |
2 | B老师 | 1 |
3 | C老师 | 3 |
student表
id | 学生 | 老师外键id |
1 | A学生 | 1老师 |
2 | B学生 | 2老师 |
1. 我们公司和你心目中的公司相比,百分制能打多少分
2.你对我们公司了解多少
3.你认为写好一个程序最重要的是什么
4.你最看重一个公司的什么
5.你对将来有什么规划