更多的程序员文章收录在
[【JAVA方向学习文章视频汇总】](https://blog.csdn.net/dearmite/article/details/149296144)
@[TOC](文章目录)
---
多线程面试题
序号 | 1 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 什么是线程及实现多线程方法 | ||||
解答 | 线程是指进程中的一个执行流程,一个进程中可以运行多个线程 实现多线程方法: 1.继承thread类,重写run函数;开启线程:对象.start() 2.实现runnable接口,重写run函数 开启线程:Thread t=new thread(Runnable对象);t.start(); | ||||
关键词 | 线程、runnable |
序号 | 2 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 解释一下synchronized关键字的用途? | ||||
解答 | 他是java中的一个关键字,是一种同步锁。当他用来修饰一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该代码块。 他有4种用法:
| ||||
关键词 | synchronized |
序号 | 3 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | java中的volatile变量是什么? | ||||
解答 | 他是多线程中的一个关键字,用volatile修饰的变量,保持可见性,线程在每次使用变量的时候,都会读取变量修改的最新的值.volatile很容易被误用,用来进行原子性操作。Volatile是不能做到线程同步的。 | ||||
关键词 | volatile |
序号 | 4 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 什么是线程? | ||||
解答 | 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。Java在语言层面对多线程提供了卓越的支 持,它也是一个很好的卖点。 | ||||
关键词 |
序号 | 5 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 线程和进程有什么区别? | ||||
解答 | 线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。 |
序号 | 6 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Thread 类中的start() 和 run() 方法有什么区别? | ||||
解答 | 这个问题经常被问到,但还是能从此区分出面试者对Java线程模型的理解程度。start()方法被用来启动新创建的线程,而且start()内部 调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启 动,start()方法才会启动新线程。 | ||||
关键词 |
序号 | 7 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java中Runnable和Callable有什么不同? | ||||
解答 | Runnable和Callable都代表那些要在不同的线程中执行的任务。Runnable从JDK1.0开始就有了,Callable是在 JDK1.5增加的。它们的主要区别是Callable的 call() 方法可以返回值和抛出异常,而Runnable的run()方法没有这些功能。Callable可以返回装载有计算结果的Future对象。 | ||||
关键词 |
序号 | 8 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java中CyclicBarrier 和 CountDownLatch有什么不同? | ||||
解答 | CyclicBarrier 和 CountDownLatch 都可以用来让一组线程等待其它线程。与 CyclicBarrier 不同的是,CountdownLatch 不能重新使用。 | ||||
关键词 |
序号 | 9 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java内存模型是什么? | ||||
解答 | Java内存模型规定和指引Java程序在不同的内存架构、CPU和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java内存模型对一 个线程所做的变动能被其它线程可见提供了保证,它们之间是先行发生关系。这个关系定义了一些规则让程序员在并发编程时思路更清晰。比如,先行发生关系确保了:
| ||||
关键词 |
序号 | 10 | 出题人 | 项目组 | 技术类型 | 集合 |
题目 | 什么是线程安全?Vector是一个线程安全类吗? | ||||
解答 | 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量 的值也和预期的是一样的,就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分 成两组,线程安全和非线程安全的。Vector 是用同步方法来实现线程安全的, 而和它相似的ArrayList不是线程安全的。 | ||||
关键词 |
序号 | 11 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java中什么是竞态条件? 举个例子说明。 | ||||
解答 | 竞态条件会导致程序在并发情况下出现一些bugs。多线程对一些资源的竞争的时候就会产生竞态条件,如果首先要执行的程序竞争失败排到后面执行了, 那么整个程序就会出现一些不确定的bugs。这种bugs很难发现而且会重复出现,因为线程间的随机竞争。 | ||||
关键词 |
序号 | 12 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java中如何停止一个线程? | ||||
解答 | Java提供了很丰富的API但没有为停止线程提供API。JDK 1.0本来有一些像stop(), suspend() 和 resume()的控制方法但是由于潜在的死锁威胁因此在后续的JDK版本中他们被弃用了,之后Java API的设计者就没有提供一个兼容且线程安全的方法来停止一个线程。当run() 或者 call() 方法执行完的时候线程会自动结束,如果要手动结束一个线程,你可以用volatile 布尔变量来退出run()方法的循环或者是取消任务来中断线程。 | ||||
关键词 |
序号 | 13 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 一个线程运行时发生异常会怎样? | ||||
解答 | 简单的说,如果异常没有被捕获该线程将会停止执行。Thread.UncaughtExceptionHandler是用于处理未捕获异常造成线程突然中 断情况的一个内嵌接口。当一个未捕获异常将造成线程中断的时候JVM会使用Thread.getUncaughtExceptionHandler()来 查询线程的UncaughtExceptionHandler并将线程和异常作为参数传递给handler的uncaughtException()方法 进行处理。 | ||||
关键词 |
序号 | 14 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 如何在两个线程间共享数据? | ||||
解答 | 你可以通过共享对象来实现这个目的,或者是使用像阻塞队列这样并发的数据结构。还有一些比如通过数据库、Redis实现数据共享。 | ||||
关键词 |
序号 | 15 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java中notify 和 notifyAll有什么区别? | ||||
解答 | 因为多线程可以等待单监控锁,Java API 的设计人员提供了一些方法当等待条件改变的时候通知它们,但是这些方法没有完全实现。notify()方法不能唤醒某个具体的线程,所以只有一个线程在等 待的时候它才有用武之地。而notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。 | ||||
关键词 |
序号 | 16 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 为什么wait, notify 和 notifyAll这些方法不在thread类里面? | ||||
解答 | 这是个设计相关的问题,它考察的是面试者对现有系统和一些普遍存在但看起来不合理的事物的看法。回答这些问题的时候,你要说明为什么把这些方法放在 Object类里是有意义的,还有不把它放在Thread类里的原因。一个很明显的原因是JAVA提供的锁是对象级的而不是线程级的,每个对象都有锁,通 过线程获得。如果线程需要等待某些锁那么调用对象中的wait()方法就有意义了。如果wait()方法定义在Thread类中,线程正在等待的是哪个锁 就不明显了。简单的说,由于wait,notify和notifyAll都是锁级别的操作,所以把他们定义在Object类中因为锁属于对象。 | ||||
关键词 |
序号 | 17 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 什么是ThreadLocal变量? | ||||
解答 | ThreadLocal是Java里一种特殊的变量。每个线程都有一个ThreadLocal就是每个线程都拥有了自己独立的一个变量,竞争条件被 彻底消除了。它是为创建代价高昂的对象获取线程安全的好方法,比如你可以用ThreadLocal让SimpleDateFormat变成线程安全的,因 为那个类创建代价高昂且每次调用都需要创建不同的实例所以不值得在局部范围使用它,如果为每个线程提供一个自己独有的变量拷贝,将大大提高效率。首先,通 过复用减少了代价高昂的对象的创建个数。其次,你在没有使用高代价的同步或者不变性的情况下获得了线程安全。线程局部变量的另一个不错的例子是 ThreadLocalRandom类,它在多线程环境中减少了创建代价高昂的Random对象的个数。 | ||||
关键词 |
序号 | 18 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java中interrupted 和 isInterruptedd方法的区别? | ||||
解答 | interrupted() 和 isInterrupted()的主要区别是前者会将中断状态清除而后者不会。Java多线程的中断机制是用内部标识来实现的,调用Thread.interrupt()来中断一个线程就会设置中断标识为true。当中断线程调用静态方法Thread.interrupted()来 检查中断状态时,中断状态会被清零。而非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态标识。简单的说就是任何抛 出InterruptedException异常的方法都会将中断状态清零。无论如何,一个线程的中断状态有有可能被其它线程调用中断来改变。 | ||||
关键词 |
序号 | 19 | 出题人 | 项目组 | 技术类型 | Java内存模型 |
题目 | Java中堆和栈有什么不同? | ||||
解答 | 为什么把这个问题归类在多线程和并发面试题里?因为栈是一块和线程紧密相关的内存区域。每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈 调用,一个线程中存储的变量对其它线程是不可见的。而堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己 的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。 | ||||
关键词 |
序号 | 20 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 什么是线程池? 为什么要使用它? | ||||
解答 | 创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时 候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短 的任务的程序的可扩展线程池)。 | ||||
关键词 |
序号 | 21 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 如何写代码来解决生产者消费者问题? | ||||
解答 | 在现实中你解决的许多线程问题都属于生产者消费者模型,就是一个线程生产任务供其它线程进行消费,你必须知道怎么进行线程间通信来解决这个问题。比 较低级的办法是用wait和notify来解决这个问题,比较赞的办法是用Semaphore 或者 BlockingQueue来实现生产者消费者模型,这篇教程有实现它。 | ||||
关键词 |
序号 | 22 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 如何避免死锁? | ||||
解答 | Java多线程中的死锁死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:
避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。 | ||||
关键词 |
序号 | 23 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java中活锁和死锁有什么区别? | ||||
解答 | 这是上题的扩展,活锁和死锁类似,不同之处在于处于活锁的线程或进程的状态是不断改变的,活锁可以认为是一种特殊的饥饿。一个现实的活锁例子是两个 人在狭小的走廊碰到,两个人都试着避让对方好让彼此通过,但是因为避让的方向都一样导致最后谁都不能通过走廊。简单的说就是,活锁和死锁的主要区别是前者 进程的状态可以改变但是却不能继续执行。 | ||||
关键词 |
序号 | 24 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 有三个线程T1,T2,T3,怎么确保它们按顺序执行? | ||||
解答 | 在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。 | ||||
关键词 |
序号 | 25 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Thread类中的yield方法有什么作用? | ||||
解答 | Yield方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行。它是一个静态方法而且只保证当前线程放弃CPU占用而不能保证使其它线程一定能占用CPU,执行yield()的线程有可能在进入到暂停状态后马上又被执行。 | ||||
关键词 |
序号 | 26 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 如果同步块内的线程抛出异常会发生什么? | ||||
解答 | 这个问题坑了很多Java程序员,若你能想到锁是否释放这条线索来回答还有点希望答对。无论你的同步块是正常还是异常退出的,里面的线程都会释放锁,所以对比锁接口我更喜欢同步块,因为它不用我花费精力去释放锁,该功能可以在finally block里释放锁实现。 | ||||
关键词 |
序号 | 27 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 如何强制启动一个线程? | ||||
解答 | 这个问题就像是如何强制进行Java垃圾回收,目前还没有觉得方法,虽然你可以使用System.gc()来进行垃圾回收,但是不保证能成功。在Java里面没有办法强制启动一个线程,它是被线程调度器控制着且Java没有公布相关的API。 | ||||
关键词 |
序号 | 28 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java多线程中调用wait() 和 sleep()方法有什么不同? | ||||
解答 | Java程序中wait 和 sleep都会造成某种形式的暂停,它们可以满足不同的需要。wait()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而 sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁。 | ||||
关键词 |
序号 | 29 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 多线程有什么用? | ||||
解答 | 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了,还管它有什么用?在我看来,这个回答更扯淡。所谓"知其然知其所以然","会用"只是"知其然","为什么用"才是"知其所以然",只有达到"知其然知其所以然"的程度才可以说是把一个知识点运用自如。OK,下面说说我对这个问题的看法:
2)防止阻塞 从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题,多条线程同时运行,哪怕一条线程的代码执行读取数据阻塞,也不会影响其它任务的执行。我刚整理了一套2018最新的0基础入门和进阶教程,无私分享,加Java学习裙 :678-241-563 即可获取,内附:开发工具和安装包,以及系统学习路线图 3)便于建模 这是另外一个没有这么明显的优点了。假设有一个大的任务A,单线程编程,那么就要考虑很多,建立整个程序模型比较麻烦。但是如果把这个大的任务A分解成几个小任务,任务B、任务C、任务D,分别建立程序模型,并通过多线程分别运行这几个任务,那就简单很多了。 | ||||
关键词 |
序号 | 30 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java编程写一个会导致死锁的程序 | ||||
解答 | 第一次看到这个题目,觉得这是一个非常好的问题。很多人都知道死锁是怎么一回事儿:线程A和线程B相互等待对方持有的锁导致程序无限死循环下去。当然也仅限于此了,问一下怎么写一个死锁的程序就不知道了,这种情况说白了就是不懂什么是死锁,懂一个理论就完事儿了,实践中碰到死锁的问题基本上是看不出来的。 真正理解什么是死锁,这个问题其实不难,几个步骤:
这样,线程1"睡觉"睡完,线程2已经获取了lock2的对象锁了,线程1此时尝试获取lock2的对象锁,便被阻塞,此时一个死锁就形成了。代码就不写了,占的篇幅有点多,Java多线程7:死锁这篇文章里面有,就是上面步骤的代码实现。 | ||||
关键词 |
序号 | 31 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 怎么唤醒一个阻塞的线程? | ||||
解答 | 如果线程是因为调用了wait()、sleep()或者join()方法而导致的阻塞,可以中断线程,并且通过抛出InterruptedException来唤醒它;如果线程遇到了IO阻塞,无能为力,因为IO是操作系统实现的,Java代码并没有办法直接接触到操作系统。 | ||||
关键词 |
序号 | 32 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 不可变对象对多线程有什么帮助? | ||||
解答 | 不可变对象保证了对象的内存可见性,对不可变对象的读取不需要进行额外的同步手段,提升了代码执行效率。 | ||||
关键词 |
序号 | 33 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 什么是多线程的上下文切换? | ||||
解答 | 多线程的上下文切换是指CPU控制权由一个已经正在运行的线程切换到另外一个就绪并等待获取CPU执行权的线程的过程。 | ||||
关键词 | |||||
序号 | 34 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Java中用到的线程调度算法是什么? | ||||
解答 | 抢占式。一个线程用完CPU之后,操作系统会根据线程优先级、线程饥饿情况等数据算出一个总的优先级并分配下一个时间片给某个线程执行。 | ||||
关键词 |
序号 | 35 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 什么是Java内存模型? | ||||
解答 | Java内存模型定义了一种多线程访问Java内存的规范。Java内存模型要完整讲不是这里几句话能说清楚的,我简单总结一下Java内存模型的几部分内容: 1)Java内存模型将内存分为了主内存和工作内存。类的状态,也就是类之间共享的变量,是存储在主内存中的,每次Java线程用到这些主内存中的变量的时候,会读一次主内存中的变量,并让这些内存在自己的工作内存中有一份拷贝,运行自己线程代码的时候,用到这些变量,操作的都是自己工作内存中的那一份。在线程代码执行完毕之后,会将最新的值更新到主内存中去
3)定义了volatile变量的使用规则 4)happens-before,即先行发生原则,定义了操作A必然先行发生于操作B的一些规则,比如在同一个线程内控制流前面的代码一定先行发生于控制流后面的代码、一个释放锁unlock的动作一定先行发生于后面对于同一个锁进行锁定lock的动作等等,只要符合这些规则,则不需要额外做同步措施,如果某段代码不符合所有的happens-before规则,则这段代码一定是线程非安全的 | ||||
关键词 |
序号 | 36 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 什么是乐观锁和悲观锁? | ||||
解答 | 1)乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁,将比较-替换这两个动作作为一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有相应的重试逻辑。 2)悲观锁:还是像它的名字一样,对于并发间操作产生的线程安全问题持悲观状态,悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,都会持有一个独占的锁,就像synchronized,不管三七二十一,直接上了锁就操作资源了。 | ||||
关键词 |
序号 | 37 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 单例模式的线程安全性? | ||||
解答 | 老生常谈的问题了,首先要说的是单例模式的线程安全意味着:某个类的实例在多线程环境下只会被创建一次出来。单例模式有很多种的写法,我总结一下:
3)双检锁单例模式的写法:线程安全 | ||||
关键词 |
序号 | 38 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | Hashtable的size()方法中明明只有一条语句"return count",为什么还要做同步? | ||||
解答 | 这是我之前的一个困惑,不知道大家有没有想过这个问题。某个方法中如果有多条语句,并且都在操作同一个类变量,那么在多线程环境下不加锁,势必会引发线程安全问题,这很好理解,但是size()方法明明只有一条语句,为什么还要加锁? 关于这个问题,在慢慢地工作、学习中,有了理解,主要原因有两点:
2)CPU执行代码,执行的不是Java代码,这点很关键,一定得记住。Java代码最终是被翻译成机器码执行的,机器码才是真正可以和硬件电路交互的代码。即使你看到Java代码只有一行,甚至你看到Java代码编译之后生成的字节码也只有一行,也不意味着对于底层来说这句语句的操作只有一个。一句"return count"假设被翻译成了三句汇编语句执行,一句汇编语句和其机器码做对应,完全可能执行完第一句,线程就切换了。 | ||||
关键词 |
序号 | 39 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 同步方法和同步块,哪个是更好的选择? | ||||
解答 | 同步块,这意味着同步块之外的代码是异步执行的,这比同步整个方法更提升代码的效率。请知道一条原则:同步的范围越小越好。 借着这一条,我额外提一点,虽说同步的范围越少越好,但是在Java虚拟机中还是存在着一种叫做锁粗化的优化方法,这种方法就是把同步范围变大。这是有用的,比方说StringBuffer,它是一个线程安全的类,自然最常用的append()方法是一个同步方法,我们写代码的时候会反复append字符串,这意味着要进行反复的加锁->解锁,这对性能不利,因为这意味着Java虚拟机在这条线程上要反复地在内核态和用户态之间进行切换,因此Java虚拟机会将多次append方法调用的代码进行一个锁粗化的操作,将多次的append的操作扩展到append方法的头尾,变成一个大的同步块,这样就减少了加锁-->解锁的次数,有效地提升了代码执行的效率。 | ||||
关键词 |
序号 | 40 | 出题人 | 项目组 | 技术类型 | 多线程 |
题目 | 高并发、任务执行时间短的业务怎样使用线程池?并发不高、任务执行时间长的业务怎样使用线程池?并发高、业务执行时间长的业务怎样使用线程池? | ||||
解答 | 1.高并发、任务执行时间短的业务,线程池线程数可以设置为CPU核数+1,减少线程上下文的切换 2.并发不高、任务执行时间长的业务要区分开看: a)假如是业务时间长集中在IO操作上,也就是IO密集型的任务,因为IO操作并不占用CPU,所以不要让所有的CPU闲下来,可以加大线程池中的线程数目,让CPU处理更多的业务 b)假如是业务时间长集中在计算操作上,也就是计算密集型任务,这个就没办法了,和(1)一样吧,线程池中的线程数设置得少一些,减少线程上下文的切换 c)并发高、业务执行时间长,解决这种类型任务的关键不在于线程池而在于整体架构的设计,看看这些业务里面某些数据是否能做缓存是第一步,增加服务器是第二步,至于线程池的设置,设置参考其他有关线程池的文章。最后,业务执行时间长的问题,也可能需要分析一下,看看能不能使用中间件对任务进行拆分和解耦。 | ||||
关键词 |
关键词
🍑3 碰上好的大量知识点的视频想把里面的字幕拼成上图的样子?
1 准备截图工具,
我一般是使用faststone Capture
下载地址见资源下载
2 第一张图一般截一个全的带脸的
后面的就截字幕的部分就可以了。我一般是设置一个重复截的快捷键。其实不用严格的与第一张同宽。拼图工具会调整为同宽。
3 整理检查所有图片,看看是不是截图有重复,有遗漏。
4 打开工具拼合
完成!
总结及资源下载
截图工具:
系统如何让截图带鼠标指针,推荐两款可以带鼠标指针截图的软件-faststone Capture
本文章里面所使用的字幕拼接工具:
下载地址:
图片拼接-支持jpg格式,一般用于拼接一个视频里的N多字幕
B站视频讲解用法:
【工具】图片拼接-支持jpg格式,一般用于拼接一个视频里的N多字幕
选择了也要努力,没有远虑必有近忧!