k12机构面试小结

公司:英语在线培训机构

面试知识点:
1 并发
java线程池常用6大参数以及含义

1 corePoolSize:核心线程数
  核心线程会一直存活,及时没有任务需要执行
  当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
  设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭
2 queueCapacity:任务队列容量(阻塞队列)用来做缓冲
  核心线程数达到最大时,新任务会放在队列中排队等待执行
3 maxPoolSize:最大线程数
  当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
  当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常
4 keepAliveTime:线程空闲时间
   当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
   如果allowCoreThreadTimeout=true,则会直到线程数量=0 (也就是核心线程长时间没有活干也会退出)
5 allowCoreThreadTimeout:允许核心线程超时
6 rejectedExecutionHandler:任务拒绝处理器
   两种情况会拒绝处理任务:
   当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
   当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线    程池真正shutdown之间提交任务,会拒绝新任务
   线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
## 任务拒绝处理器处理情形
  ThreadPoolExecutor类有几个内部实现类来处理这类情况:
  AbortPolicy 丢弃任务,抛运行时异常
  CallerRunsPolicy 执行任务
  DiscardPolicy 忽视,什么都不会发生
  DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
当然也支持自定义处理器

reentrantlock 用法及实现原理
代码示例:


image.png

从代码中很容易看出,reentrantlock 相比于sychronized需要在finally中释放锁。如果不在 finally解锁,有可能代码出现异常锁没被释放。
说明: 在jdk1.5里面,ReentrantLock的性能是明显优于synchronized的,但是在jdk1.6里面,synchronized做了优化,他们之间的性能差别已经不明显了

reentrantlock 特点

image.png

可中断(这里本身是有死锁的,但是可以通过中断来处理)

package com.protobuf.MultiThreading;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.locks.ReentrantLock;
public class LockInterrupt extends Thread {
    public static ReentrantLock lock1 = new ReentrantLock();
    public static ReentrantLock lock2 = new ReentrantLock();
    int lock;
    public LockInterrupt(int lock, String name) {
        super(name);
        this.lock = lock;
    }
    @Override
    public void run() {
        try {
            if (lock == 1) {
                lock1.lockInterruptibly();
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                lock2.lockInterruptibly();
            } else {
                lock2.lockInterruptibly();
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                lock1.lockInterruptibly();
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            if (lock1.isHeldByCurrentThread()) {
                lock1.unlock();
            }
            if (lock2.isHeldByCurrentThread()) {
                lock2.unlock();
            }
            System.out.println(Thread.currentThread().getId() + ":线程退出");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        LockInterrupt t1 = new LockInterrupt(1, "LockInterrupt1");
        LockInterrupt t2 = new LockInterrupt(2, "LockInterrupt2");
        t1.start();
        t2.start();
        Thread.sleep(1000);
//      DeadlockChecker.check();
        System.out.println("ok");
    }
    static class DeadlockChecker {
        private final static ThreadMXBean mbean = ManagementFactory
                .getThreadMXBean();
        public static void check() {
            Thread tt = new Thread(() -> {
                {
                    // TODO Auto-generated method stub
                    while (true) {
                        long[] deadlockedThreadIds = mbean.findDeadlockedThreads();
                        if (deadlockedThreadIds != null) {
                            ThreadInfo[] threadInfos = mbean.getThreadInfo(deadlockedThreadIds);
                            for (Thread t : Thread.getAllStackTraces().keySet()) {
                                for (int i = 0; i < threadInfos.length; i++) {
                                    if (t.getId() == threadInfos[i].getThreadId()) {
                                        System.out.println(t.getName());
                                        t.interrupt();
                                    }
                                }
                            }
                        }
                        try {
                            Thread.sleep(5000);
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                    }

                }
            });
            tt.setDaemon(true);
            tt.start();
        }
    }
}

死锁具体情形如下,但是上文的守护线程可以通过中断的方式解决死锁。但是对于sychronized 如果获取不到锁只能阻塞等待,因此没有这个机制

可限时

超时不能获得锁,就返回false,不会永久等待构成死锁
使用lock.tryLock(long timeout, TimeUnit unit)来实现可限时锁,参数为时间和单位。

公平锁

一般意义上的锁是不公平的,不一定先来的线程能先得到锁,后来的线程就后得到锁。不公平的锁可能会产生饥饿现象。
公平锁的意思就是,这个锁能保证线程是先来的先得到锁。虽然公平锁不会产生饥饿现象,但是公平锁的性能会比非公平锁差很多。

## 使用方法
public ReentrantLock(boolean fair) 
public static ReentrantLock fairLock = new ReentrantLock(true);

ConcurrentHashmap实现原理以及使用方法(重新写一篇详细介绍)
redis分布式实现原理(重新写一篇详细介绍)
docker知识点(重新写一篇详细介绍)
redis 并发数据结构以及pipline
常用linux命令
java的复制clone() 命令(重新写一篇节详细介绍)

2 接口编程
restful API的好处,如何实现资源间的耦合

## 之前在老部门做过reseful的接口,可惜忘记的差不多了。
REST是什么?(Resource Representational State Transfer: 资源代表状态变化)
Resource:资源,即数据(前面说过网络的核心)
Representational:某种表现形式: 比如用JSON,XML,JPEG等
State Transfer:状态变化。通过HTTP动词实现
简单介绍:
restful API中,url中只使用名词来指定资源, 原则上不使用动词。“资源”是REST架构或者整个网路处理的核心。

## pf:
http://api.qc.com/v1/newsfeed: 获取某人的信息;
http://api.qc.com/v1/friends: 获取某人的好友列表;
http://api.qc.com/v1/profile: 获取某人的详细信息

但是只有资源,没有操作方法,并不知道具体要做些什么?那么这个时候就需要动词来实现

GET 用来获取资源
POST  用来新建资源(也可以用于更新资源 pf:http://api.qc.com/v1/friends
PUT 用来更新资源 (PUT http://api.qc.com/v1/profile: 更新个人资料)
DELETE  用来删除资源。(比如:DELETE http://api.qc.com/v1/friends, 删除某人的好友, 在http parameter指定好友id)

优势: 接口制定简单,通过url就知道要做什么
看Url就知道要什么
看http method就知道干什么
看http status  code就知道结果如何

spring mvc 具体实现以及过程,分发器,hander等
参考[6]

3 工具类知识点
kafka具体了解哪些知识点
zookeeper 具体了解哪些知识点

4 提高篇
你认为上一段工作自己做的比较好的地方
经常通过哪些渠道学习,举例自己学习到的知识点

5 mysql:
question: 写出同时用username + age做 联合主键的查询语句 ?

注意此时是将a,b,c三列所有不同的组合全部列出来,而不仅仅只是distinct a   
方案一: distinct多列
select distinct a,b,c from tableA;
方案二:group by
select a,b,c from tableA group by a,b,c

mysql的7大事务传播机制

PROPAGATION_REQUIRED  支持当前事务,如果当前没有事务,则新建一个事(spring 默认)
PROPAGATION_SUPPORTS 支持,如果当前没有则以非事务方式执行
PROPAGATION_MANDATORY 支持,如果没有强制抛出异常
PROPAGATION_REQUIRES_NEW 新建,如果存在挂起当前事务
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果存在事务则挂起事务
PROPAGATION_NEVER —— 以非事务方式执行,如果当前存在事务,则抛出异常
PROPAGATION_NESTED —— Nested的事务和它的父事务是相依的,它的提交是要等和它的父事务一块提交的。
小结: 其实可以看出事务的是从支持事务和不支持事务的顺序过渡

Spring事务的5种隔离级别

1、ISOLATION_DEFAULT (使用DB默认隔离级别)
这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。

另外4个与 JDBC 的隔离级别相对应。

2、ISOLATION_READ_UNCOMMITTED(对应mysql:UNCOMMITTED )

这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻读。

3、 ISOLATION_READ_COMMITTED(对应mysql:READ_COMMITTED)

保证一个事务修改的数据提交后才能被另外一个事务读取,其它事务不能读取该事务未提交的数据。

4、ISOLATION_REPEATABLE_READ(对应mysql:REPEATABLE_READ) mysql 默认隔离级别

保证一个事务不能读取另一个事务未提交的数据,避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。

这种事务隔离级别可以防止脏读,不可重复读,但是可能出现幻读。

5、ISOLATION_SERIALIZABLE(对应mysql:SERIALIZABLE)

这是最可靠的但是代价花费最高的事务隔离级别,事务被处理为顺序执行。
除了可防止脏读,不可重复读外,还避免了幻读

具体实例详解参考3

6 vim 常用命令,大文件替换文本等

## 对第一行到最后一行的内容进行替换(即全部文本)多种写法
:1,$s/from/to/g 
:%s/from/to/g

参考文献:
1 distinct 多列详解
2 Spring 七种事务传播机制和五种事务隔离级别
3 脏读、幻读和不可重复读 + 事务隔离级别
4 Vim文本替换
5 RESTful API
6 SpringMVC执行流程及工作原理
7 reentrantlock可重入锁

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容