目录
1. 算法题:有效的括号 https://leetcode-cn.com/problems/valid-parentheses/
1. 算法题:有效的括号 https://leetcode-cn.com/problems/valid-parentheses/
class Solution {
public boolean isValid(String s) {
int n = s.length();
if (n % 2 == 1) {
return false;
}
Map<Character, Character> pairs = new HashMap<Character, Character>() {{
put(')', '(');
put(']', '[');
put('}', '{');
}};
Deque<Character> stack = new LinkedList<Character>();
for (int i = 0; i < n; i++) {
char ch = s.charAt(i);
if (pairs.containsKey(ch)) {
if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
return false;
}
stack.pop();
} else {
stack.push(ch);
}
}
return stack.isEmpty();
}
}
2. Java运行时数据区都有哪几块组成
线程私有的:
1、程序计数器:
(1)当前线程所执行的字节码指令的行号指示器,如分支、跳转、循环、异常处理、线程恢复都依赖程序计数器实现;
(2)Java多线程是通过线程轮流切换并分配CPU时间片来执行的,为了线程切换后能恢复到正确的位置,所以每个线程都有一个单独的程序计数器,所以程序计数器是私有的;
2、虚拟机栈:
(1)为执行Java方法服务‘
(2)当线程创建的时候,为线程分配一块内存区域,在线程执行的过程中,每个方法的执行都会创建一个栈帧,用于存放局部变量表、操作栈、
动态链接,方法出口等。每个方法从被调用,直到被执行完。对应着一个栈帧在虚拟机中从入栈到出栈的过程;
(3)会有两种异常StackOverFlowError和 OutOfMemoneyError。当线程请求栈深度大于虚拟机所允许的深度就会抛出StackOverFlowError错误;虚拟机栈动态扩展,当扩展无法申请到足够的内存空间时候,抛出OutOfMemoneyError;
(4)它是线程私有的,生命周期与线程相同;
3、本地方法栈:
(1)与java虚拟机栈所发挥的作用非常相似,它们之间的区别在于java虚拟机栈执行java方法服务的,本地方法栈是执行本地方法服务的
线程共享的:
1、堆
(1)Java堆是java虚拟机所管理的内存中最大的一块;
(2)被所有线程共享区域,在虚拟机启动时创建,唯一目的存放对象实例;
(3)堆区是gc的主要区域,通常情况下分为两个区块年轻代和年老代。更细一点年轻代又分为Eden区最要放新创建对象,From survivor 和 To survivor 保存gc后幸存下的对象,默认情况下各自占比 8:1:1。 进一步划分的目的是为了更还的内存回收或者更快的内存分配;
(4)会有异常OutOfMemoneyError;
2、方法区
(1)被所有线程共享区域,用于存放已被虚拟机加载的类信息,常量,静态变量等数据。被Java虚拟机描述为堆的一个逻辑部分。习惯是也叫它永久代(仅仅是因为HotSpot虚拟机选择把GC分代收集扩展至方法区);
(2)垃圾回收很少光顾这个区域,不过也是需要回收的,主要针对常量池回收,类型卸载。
(3)会有异常OutOfMemoneyError;
3. 类加载过程
整体流程为:加载、验证、准备、解析、初始化
第一步:加载
加载.class文件
总结:加载
类的.class
文件二进制数据到内存
—> 映射成jvm能识别的结构
—> 在内存中生成class文件
。
第二步:验证
确保class文件中的字节流包含的信息,符合当前虚拟机的要求,保证这个被加载的class类的正确性,不会危害到虚拟机的安全。
第三步:准备
为类中的静态字段
分配内存,并设置默认的初始值,比如int类型初始值是0。被final修饰的static字段不会设置,因为final在编译的时候就分配了
第四步:解析
解析阶段的目的,是将常量池内的符号引用转换为直接引用的过程(将常量池内的符号引用解析成为实际引用)。如果符号引用指向一个未被加载的类,或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化。)
事实上,解析器操作往往会伴随着 JVM 在执行完初始化之后再执行。 符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《Java 虚拟机规范》的Class文件格式中。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。
第五步:初始化
初始化就是执行类的构造器方法init
()的过程。
这个方法不需要定义,是javac编译器自动收集类中所有类变量的赋值动作和静态代码块中的语句合并来的。
若该类具有父类,jvm
会保证父类的init
先执行,然后在执行子类的init
。
4. gc的理解
垃圾回收也简称GC,也成垃圾收集,Java程序会不定时地被唤起检查是否有不再被使用的对象,并释放它们占用的内存空间。
垃圾回收需要完成的三件事情:
-
那些内存需要回收
-
什么时候回收
-
如何回收