笔记

Author Avatar
YZ 3月 15, 2018
  • Java多线程

    sleep不会释放锁,即使当前线程sleep,其他线程也无法访问其持有的对象;相当于阻塞状态

    yield不会释放锁,只能让拥有相同或更高优先级的线程获取CPU执行时间;重回就绪状态

    start启动线程,run只是定义需要执行的任务

    http://www.importnew.com/21136.html

    面试题

    线程和进程有什么区别?
    答:一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

    如何在Java中实现线程?
    答:
    创建线程有两种方式:
    一、继承 Thread 类,扩展线程。
    二、实现 Runnable 接口。

    三、实现Callable接口

    启动一个线程是调用run()还是start()方法?
    答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM 调度并执行,这并不意味着线程就会立即运行。run()方法是线程启动后要进行回调(callback)的方法。

    Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?
    答:sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态)。wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。

    线程的sleep()方法和yield()方法有什么区别?
    ① sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
    ② 线程执行sleep()方法后转入阻塞状态,而执行yield()方法后转入就绪状态;
    ③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
    ④ sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。

    请说出与线程同步以及线程调度相关的方法。

    • wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;

    • sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;

    • notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;

    • notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;

      每个线程都维护一个map,而这个map的key就是threadLocal;这个变量的状态不发生变化,仅仅充当一次key的角色,另外提供给每一个线程一个初始值。

  • List vs ArrayList

    Object的equals方法默认和==一样,比较的是地址;

  • JVM

    程序计数器:记录当前线程正在执行的那一条字节码指令的地址;

    java虚拟机栈

    本地方法栈

    堆:在虚拟机启动时创建,垃圾回收的主要场所;

    方法区

  • SSH

    AOP Aspect Oriented Programming

  • web容器

    1. 通信支持,封装一系列复杂操作,我们专注于servlet的业务逻辑

    2. 生命周期管理,容器负责servlet的整个生命周期;不用考虑垃圾回收balabala

    3. 多线程支持,容器为每一个servlet创建java线程,自动结束

    4. 声明式实现安全,xml部署描述文件

  • Collection Collections

    Collection集合接口,提供对集合对象进行基本操作的通用接口方法,有很多具体的实现;目的是为各种具体的集合提供最大化的统一操作方式。

    list: linkedlist arraylist vector—>stack

    set queue map

    Collections是包装类,含有各种有关集合操作的静态多态方法,不能实例化;类似工具类,服务于Java的Collection框架。eg: Collections.sort(list);

  • Queue

    线程安全的非阻塞队列ConcurrentLinkedQueue

    阻塞队列 ArrayBlockingQueue

  • 阻塞非阻塞 同步异步

    阻塞非阻塞与等待消息通知时的状态有关;阻塞指调用结果返回前,当前线程挂起,一直等待消息通知,不执行其他任务,函数只有在得到结果后才返回;

    同步异步与消息的通知机制,如何通知有关;

    1
    2
    a.如果线程在等待当前函数返回时,仍在执行其他消息处理,则是同步非阻塞;【行为切换,效率很低】
    b.如果线程在等待当前函数返回时,没有执行其他消息处理,而是处于挂起等待态,则同步阻塞

  • queue remove() poll()都是从队列中删除第一个元素;但是poll在用空集合调用时不是抛出异常,只是返回null;同理,element()抛出异常,而peek()返回null;

  • java二维数组初始化 https://zhidao.baidu.com/question/383661238.html

  • 图的遍历https://www.cnblogs.com/0kk470/p/7555033.html

    非加权:BFS先找到的是最短路径

    加权:利用Dijkstra

  • java继承初始化顺序【初始化过程是执行类构造器方法clinit过程】

    1. 父类静态代码区和父类静态成员
    2. 子类静态代码区和子类静态成员
    3. 父类非静态代码区和普通成员
    4. 父类构造函数
    5. 子类非静态代码区和普通成员
    6. 子类构造函数

    涉及到 JVM 加载机制:

    1. 触发main方法,会先触发类的初始化;

    2. 使用new关键字实例化对象,读取或设置一个类的静态字段【除final】,调用一个类的静态方法,会触发初始化;

    3. 初始化一个类时,如果父类没有初始化,先触发父类;

  • String StringBuilder StringBuffer

    运行速度:StringBuilder>StringBuffer>String

    原因:String是字符串常量,其余两个变量;string + 会新建一个string对象,原来的被GC

    线程安全:StringBuilder不安全 StringBuffer安全

    原因:StringBuffer可以@Synchronized;

    总结:

    1. String:适用于少量的字符串操作

    2. StringBuilder:适用于单线程下在字符缓冲区进行大量操作

    3. StringBuffer:适用于多线程下在字符缓冲区进行大量操作

  • 线程安全

  • 输入URL到页面加载发生了啥?

  • 行锁,表锁,页级锁,意向锁,读锁,写锁,悲观锁,乐观锁,以及加锁的select sql方式

    悲观锁按使用性质划分:

    1. 共享锁S锁,读锁:可以同时读,不能同时写;

    2. 排他锁X锁,写锁:其他事务干巴巴等~

    3. 更新锁U锁:预定施加X锁,要更新升级为X【S会有死锁】

    数据库中的并发一致性问题:【数据库提供了事物的隔离级别】

    1. 丢失修改【第一类&第二类】

    2. 脏读

    3. 不可重复读

    4. 幻读

    事物隔离级别:

    1. 未提交读(READ UNCOMMITTED)读写都不加锁,事务更新没提交,也能读
    2. 提交读(READ COMMITTED)写锁,只能看到已提交的更新【Oracle,Sqlserver】
    3. 可重复读(REPEATABLE READ)读写锁【Mysql】
    4. 可串行化(SERIALIXABLE)

    avatar

  • B B+ 红黑树

  • volatile 指令重排序

  • 线程池

    1. 原因:

      1) 创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率;

      2) 线程并发数量太多,抢占资源而造成阻塞;

      3) 对线程进行一些简单的管理,如:延时执行,定时循环执行;

    2. 线程池概念是Executor接口,具体实现为ThreadPoolExecutor类;ThreadPoolExecutor构造函数参数:【一般用前五个】

      1) int corePoolSize 该线程池中核心线程数最大值

      2) int maximumPoolSize 该线程池中线程总数最大值

      3) long keepAliveTime 该线程池中非核心线程闲置超时时长

      4) TimeUnit unit 枚举类型

      5) BlockingQueue workQueue 该线程池中的任务队列:维护着等待执行的Runnable对象

      1
      2
      3
      4
      SynchronousQueue//max无限大
      LinkedBlockingQueue//总线程数不会超过corePoolSize!!!
      ArrayBlockingQueue//规定队列的长度
      DelayQueue//到达指定的延时时间,才执行任务

      6) ThreadFactory threadFactory 创建线程的方式,是一个接口

      7) RejectedExecutionHandler handler 抛出异常专用

    3. 常见四种线程池

      1) CachedThreadPool()可缓存线程池

      2) FixedThreadPool()定长线程池,可控制线程最大并发数

      3) ScheduledThreadPool()定长线程池,支持定时及周期性任务执行

      4) SingleThreadExecutor()单线程化的线程池,有且仅有一个工作线程执行任务;所有任务按指定顺序执行,遵循队列的入队出队规则。