本文主要是介绍HT笔试随笔,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
这里写目录标题
- 选择
- 关于ArrayBlockingQueue说法不正确的是?
- 下面哪个流属于面向字符流
- 以下关于线程通讯的说法错误的是
- 在java。util.concurrent.locks.AbstractQueueSychronizer的实现当中,使用了哪种数据结构?
- 一下代码的运行结果
- 存在一个变量List strList,循环遍历List正确的项
- 简答
- 已知二叉树的前序遍历和中序遍历,求后续遍历?
- Sychronized和Lock的区别
- 一道SQL题,找出所有重复的字段,重复的字段仅输出一次
- 在java.util.ThreadPoolExecutor的构造函数参数中,有corePoolSize、maximumSize、workQueue三个参数,那么当不断往线程池中添加任务时,这三个参数是如何影响线程池中的线程数的?
选择
关于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(){@Overridepublic 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 6public 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
这篇关于HT笔试随笔的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!