第三章:二叉树问题
树形dp套路在做树结构的题目中,如果求解规则可以分为,以某个节点为子树,先向左要数据,再向右要数据,最后返回总数据,我们就可以使用该套路。
递归进行遍历
public static void QTraverse2(Point tree) {
if (tree == null) {
return;
}
System.out.println("先序");
QTraverse2(tree.left);
System.out.println("中序");
QTraverse2(tree.right);
System.out.println("后续");
}
非递归进行遍历
//非递归前序遍历 使用栈
public static void QTraverse1(Point tree) {
Stack<Point> stack = new Stack<> ...
Shell脚本
Shell输入输出重定向
我们在后台挂在jar包时,常使用过一个命令:nohup java -jar xxx.jar > java.log 2>&1 &
这里就有几个知识点:
末尾的 & 代表后台默认启动,页面关闭后,程序终止。
头部的 nohup 表示页面关闭后,后台仍继续运行,如果没有指定日志文件,则默认将输出重定向到nohup.log文件
java -jar xxx.jar最基本的启动jar包
> java.log 将运行jar包后的输出日志文件重定向到 java.log文件中
2>&1将标准输出与标准错误输出合并,在当前语义下就是将所有信息输出到 java.log文件。
如果只写 > 表示只将正常输出重定向到log文件中,错误信息直接显示页面
如果写 2> 表示只将错误输出重定向到log文件中,正常信息直接显示页面
> 默认表示重定向,并覆盖原来内容
>> 表示以追加的方式重定向
这样我们就可以监控到后台运行程序的日志信息了。
shell脚本保证程序运行
需求:当我们将项目挂在到服务 ...
IO流复习
今天面试的时候问了一道IO流的题,鉴于之前在java基础篇的时候学过一遍,后再无使用和复习,就再跟着韩顺平老师的课件复习一遍。
IO流IO流是什么?当我们使用程序读取或修改本地文件时, 文件是以流的形式加载在内存中的。
InputStream:输入流,从数据源加载至内存。
OutputStream:输出流,从存在中加载至目的地。
IO流有哪些分类
输入流,输出流是最宽泛的概念,也是我们上面讲的概念。那为什么还需要分成字节流,字符流,节点流,处理流呢?
字节我们都知道:byte,是一个二进制单位,而我们的文件可以是txt(存储字符的),png(存储图片的),mp3(存储音频的),mp4(存储视频的),但传输的时候我们都将其转化为二进制,因为计算机只能识别二进制,也就是字节。所以字节流的意思就是说:将该文件以字节为单位进行读取,可以一个字节一个字节读取,或者一段字节数组进行重复读取。这样不管是什么文件都可以进行传输了。
那为啥还需要字符流呢?这是已因为字节流是直接作用于文件的,而字符流使用了缓冲区,先将数据写入缓冲区进行读写操作,当输出流close或者flush时,才会把内容写 ...
反射复习
反射复习能干嘛 当我们创建一个对象时,需要事先在源码中进行编写,例如:new Object(),但如果未来发生变化,我就不得不在源码中进行修改,这也违反了开闭原则,我们能不能仅修改配置文件就可以调整系统中需要创建的类。比如说我在配置文件写:
classPathName=org.Mysql.SQLBuilder
mathod=getSqlSession
我想未来我的系统可以读取该配置文件,知道需要的是一个org.Mysql.SQLBuilder类,并且调用getSqlSession方法。等到未来如果修改成:
classPathName=org.Oracle.SQLBuilder
mathod=getSqlSessions
那系统也能动态的感知到现在需要的是org.Oracle.SQLBuilder,并要调用getSqlSessions方法。在使用反射前我们是无法解决的,因为所有使用的类,在编译期就固定了。所以引出了反射技术。也就是为了在运行期,可动态获取类信息或者创建对象。
这在我们学习框架例如Spring,Mybatis时就经常使用,比如我想动 ...
Java基础
List
集合中线程安全的方案:
Collections.synchronizedList(arrayList);
Vector
CopyOnWriteArrayList
Collections.synchronizedListCollections.synchronizedList 使用了装饰者模式,将原本的List包装了一层,在调用List原本的方法时,通过多态进行加锁操作,这里我们注意:读写操作加锁,获取迭代器不加锁
public boolean add(E e) {
synchronized (mutex) {return c.add(e);}
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public Iterator<E> iterator() {
return list.iter ...

