选择
关于ArrayBlockingQueue说法不正确的是?
- 其主要应用场景是“生产者-消费者”模型
- 其是线程安全的
- 允许元素为null
- 必须显示的设置容量
并没有无参构造,所以必须要初始化长度,不让他变成一个无边界的数据队列,可能会存在内存过大的问题
内部实现了ReentrantLock锁,所以线程是安全的,
下面哪个流属于面向字符流
- ObjectInputStream
- BufferedWriter
- FileInputStream
- InputStreamReader
CharArrayReader 从字符数组读取的输入流
BufferedReader 缓冲输入字符流
PipedReader 输入管道
InputStreamReader 将字节转换到字符的输入流
FilterReader 过滤输入流
StringReader 从字符串读取的输入流
LineNumberReader 为输入数据附加行号
PushbackReader 返回一个字符并把此字节放回输入流
FileReader 从文件读取的输入流
以下关于线程通讯的说法错误的是
- wait()有多个重载的方法,可指定等待时间
- 可以调用wait()、notify()、notifyAll()三个方法实现线程通讯
- wait()必须在sychronized方法或者代码块中使用
- wait()、notify()、notifyAll()是Object类提供的方法、子类可以重写
wait()、notify()、notifyAll()都被final修饰子类不能重写
在java。util.concurrent.locks.AbstractQueueSychronizer的实现当中,使用了哪种数据结构?
- 数组
- 哈希表
- 双向链表
- 集合
查看源码易知是是双向链表
一下代码的运行结果
public class Demo1 {
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run(){
pong();
}
};
t.run();
System.out.println("ping");
}
static void pong(){
System.out.println("pong");
}
}
结果就是:
pong
ping
存在一个变量List strList,循环遍历List正确的项
System.out.println("方式一:");
Iterator<String> it = strList.iterator();
while(it.hasNext()){
String str = it.next();
System.out.print(str+" ");
}
System.out.println();
System.out.println("方式二:");
for(String str:strList){
System.out.print(str+" ");
}
System.out.println();
System.out.println("方式三"); //错误!!!!!!!
// for(int i=0;i<strList.length;i++){
// String str = strList[i];
// }
System.out.println();
System.out.println("方式四:"); //错误!!!!!
// List.foreach(strList,function(str){
//
// });
简答
已知二叉树的前序遍历和中序遍历,求后续遍历?
public class Solution {
public static TreeNode reConstructBinaryTree(int[] prev, int[] in) {
//不管什么遍历方式,结果长度肯定是一样的,都是总结点数
if (prev.length != in.length || prev.length < 1) {
return null;
}
//只有一个节点,那就是根节点
if (prev.length == 1) {
return new TreeNode(prev[0]);
}
//在中序遍历结果中找根节点
int index = -1;
for (int i = 0; i < in.length; i++) {
if (in[i] == prev[0]) {
index = i;
break;
}
}
//没找到,说明数据有问题
if (index == -1) {
return null;
}
//找到根节点了
TreeNode root = new TreeNode(prev[0]);
//得到左子树的前序遍历结果
int[] lChildPrev = new int[index];
System.arraycopy(prev, 1, lChildPrev, 0, index);
//得到左子树的中序遍历结果
int[] lChildin = new int[index];
System.arraycopy(in, 0, lChildin, 0, index);
//通过递归,得到左子树结构
root.left = reConstructBinaryTree(lChildPrev, lChildin);
//得到右子树的前序遍历结果
int[] rChildPrev = new int[in.length - 1 - index];
System.arraycopy(prev, index + 1, rChildPrev, 0, in.length - 1 - index);
//得到右子树的中序遍历结果
int[] rChildin = new int[in.length - 1 - index];
System.arraycopy(in, index + 1, rChildin, 0, in.length - 1 - index);
//通过递归,得到右子树结构
root.right = reConstructBinaryTree(rChildPrev, rChildin);
//得到完整的二叉树结构
return root;
}
//测试
public static void main(String[] args) {
int[] prev = {1, 2, 4, 7, 3, 5, 6, 8};
int[] in = {4, 7, 2, 1, 5, 3, 8, 6};
TreeNode root = reConstructBinaryTree(prev, in);
prevPrintTreeNode(root);
System.out.println();
inPrintTreeNode(root);
}
//测试结果
//1 2 4 7 3 5 6 8
//4 7 2 1 5 3 8 6
public static void inPrintTreeNode(TreeNode root) {
if (root == null) {
return;
}
//运用了递归
inPrintTreeNode(root.left);
System.out.print(root.val + " ");
inPrintTreeNode(root.right);
}
public static void prevPrintTreeNode(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.val + " ");
//运用了递归
prevPrintTreeNode(root.left);
prevPrintTreeNode(root.right);
}
public static void postPrintTreeNode(TreeNode root) {
if (root == null) {
return;
}
//运用了递归
postPrintTreeNode(root.left);
postPrintTreeNode(root.right);
System.out.print(root.val + " ");
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
Sychronized和Lock的区别
参考:https://blog.csdn.net/hefenglian/article/details/82383569
一道SQL题,找出所有重复的字段,重复的字段仅输出一次
SELECT distinct(email) FROM person
在java.util.ThreadPoolExecutor的构造函数参数中,有corePoolSize、maximumSize、workQueue三个参数,那么当不断往线程池中添加任务时,这三个参数是如何影响线程池中的线程数的?
corePoolSize:
线程池的基本大小,线程池默认初始化线程数;只有在工作队列满了的情况下才在该基础上创建新的线程。
注意:在刚刚创建ThreadPoolExecutor的时候,线程并不会立即启动,而是要等到有任务提交时才会启动,除非调用了prestartCoreThread/prestartAllCoreThreads事先启动核心线程。再考虑到keepAliveTime和allowCoreThreadTimeOut超时参数的影响,所以没有任务需要执行的时候,线程池的大小不一定是corePoolSize。
maximumPoolSize:
线程池中允许的最大线程数,线程池中的当前线程数目不会超过该值。如果队列中任务已满,并且当前线程个数小于maximumPoolSize,那么会创建新的线程来执行任务。
这里要注意的是largestPoolSize,该变量记录了线程池在整个生命周期中曾经出现的最大线程个数。为什么说是曾经呢?因为线程池创建之后,可以调用setMaximumPoolSize()改变运行的最大线程的数目。
poolSize:
线程池中当前线程的数量,当该值为0的时候,意味着没有任何线程,线程池会终止;同一时刻,poolSize不会超过maximumPoolSize。
workQueue:
阻塞队列,队列里存放可执行的线程。
参考: https://blog.csdn.net/aitangyong/article/details/38822505