面试题记录

1.如何控制线程执行的顺序

方案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

2.Java中Volatile和Synchronized的区别

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

                          

3.lock接口和synchronized的对比

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。因此说,在具体使用时要根据适当状况选择。

 

4.多线程基础知识

线程和进程的概念

一个进程中包含不少线程。

实现多线程的方式

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,能够根据返回值去判断谁得到了锁。

java基础

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中的信息获得是否秒杀成功,

SOA

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

 

 

3. rmi

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.你对将来有什么规划

相关文章
相关标签/搜索