java异常
异常类java.lang.Throwable在Java中 所有异常都有一个共同的祖先java.lang包中的Throwable类
Throwbale 包含两个重要子类 Exception(异常) Error(错误)
ErrorError 是程序无法处理的错误信息 表示代码运行时JVM(Java虚拟机)出现的问题 如: OutOfMemoryError这些异常发生时 JVM一般会选择线程终止
Exception运行时异常(RuntimeException)编译时异常编译时异常 需要保证在运行之前给出一个处理方案
异常处理异常默认处理流程
try-catch好处: 异常对象可以被捕获 后续的代码可以继续执行
格式:
12345try{ 可能会出异常的代码} catch(异常名称 对象名){ 异常的处理方案}
执行流程:
执行try{} 中的代码 看是否有异常对象产生
没有: catch就不会捕获 后续代码继续执行
有: catch捕获异常对象 执行catch{} 中的处理方案 后续代码继续执行部
如果要捕获多个异常那么最大的异常 ...
leetcode1726同积元组
原题链接:https://leetcode.cn/problems/tuple-with-same-product/
解法1:哈希表记数 + 排列组合求解
12345678910111213141516171819202122232425262728293031/* 哈希 + 排列组合 hash记录乘积出现的次数 -> 乘积由两个数相乘构成 -> 出现两次相同的乘积证明有四个数符合题目要求 -> 出现n次 则只需从n对中任意选两对进行组合即可C(2,n) -> 又因为根据题意四元组内的数顺序不同也是可以算是一种组合 A(2,4) */class Solution {public: int tupleSameProduct(vector<int>& nums) { int n = nums.size(); // 乘积 -> 乘积出现的次数 unordered_map<int,int>hash; for(int i = 0 ...
JVM_5运行时数据区
总览
面试相关难题
Java的内存分成哪几部分 详细介绍一下
Java内存中哪些部分会溢出?
JDK7和8在内存结构上的区别是什么?
内存调优:
程序计数器程序计数器(Program Conter Register) 也叫PC寄存器 每个线程会通过程序计数器记录当前要执行的字节码指令的地址
在加载阶段 虚拟机将字节码文件中的指令读取到内存之后 会将原文件中的偏移量转换成内存地址 每一条字节码指令都会拥有一个内存地址
在代码执行过程中 程序计数器会记录下一行字节码指令的地址 执行完当前指令之后 虚拟机的执行引擎根据程序计数器执行下一行指令
程序计数器可以控制程序指令的进行,实现分支、跳转、异常等逻辑
在多线程执行情况下 Java虚拟机需要通过程序计数器记录CPU切换前解释执行到哪一句指令并继续解释运行
问题: 程序计数器在运行中会出现内存溢出吗?内存溢出:指的是程序在使用某一块内存区域时,存放的数据需要占用的内存大小超过了虚拟机能提供的内存上限不会因为每个线程只存储一个固定长度的内存地址 程序计数器是不会发生内存溢出的(程序员无需对程序计数器做任何处理 程序计数器完全由java虚 ...
leetcode2530执行k次操作后的最大分数
原题链接:https://leetcode.cn/problems/maximal-score-after-applying-k-operations/
解法1 堆123456789101112131415161718192021222324252627282930313233/* 贪心 每次选最大的执行即可 heap*/typedef long long LL;class Solution {public: long long maxKelements(vector<int>& nums, int k) { // c++ 堆默认 大根堆 // 值 以及 下标 priority_queue<pair<LL,int>>heap; for(int i = 0 ; i < nums.size() ; i++){ heap.push(pair<LL,int>(nums[i],i)); ...
JVM_4类加载器
类加载器类加载器是Java虚拟机提供给应用程序取获取类和接口字节码数据的技术
类加载器应用场景
类加载器的分类
启动类加载器启动类加载器(Bootstrap ClassLoader) 是有Hotspot虚拟机提供的 使用c++编写的类加载器默认加载Java安装目录/jre/lib下的类文件 比如rt.jar,tools.jar, resources.jar等
通过启动类加载器去加载用户jar包(不推荐)使用参数进行扩展
双亲委派机制使用应用类加载器去加载类 却发现是扩展类加载器对类进行加载
在类加载器的过程中 每个类加载器都会先检查是否已经加载了该类 如果已经加载了则直接返回 否则会加载请求委派给父类加载器在双亲委派机制中 如果parent为null 则会提交给启动类加载器处理如果所有的父类都无法加载该类 则由当前类加载器自己尝试加载 所以看上去自顶向下尝试第二次再去加载相同的类 仍然会向上进行委派 如果某个类加载器加载过就会直接返回
双亲委派机制例题:
双亲委派机制的作用:
保证类加载的安全性
通过双亲委派机制 让顶层的类加载器去加载核心类 ...
leetcode260只出现一次的数字Ⅲ
原题链接:https://leetcode.cn/problems/single-number-iii/description/
解法1: 位运算 分组异或要求是线性时间复杂度的算法且仅使用常量额外空间来解决此问题
123456789101112131415161718192021222324252627282930313233343536373839/* 分组异或 先对nums中所有数进行异或得到sum 根据题意以及异或运算的性质 sum两个不同数的异或值(其他两个相同的数直接被抵消了) 然后取sum二进制位的任意为1 的一位 根据异或运算性质该位为1 说明 对于两个不同的数在第k位的二进制为的表示不同 然后对原nums中的数 第k位为0或1的分别进行异或运算 这样相同的数仍然会消去(反证法 思想如果k位不相同那么数必定不同 就一定不可能在同一个组内进行运算) 最后得到就是两个不同的数*/class Solution {public: vector<int> singleNumber(vector<int>& ...
JVM_3类的生命周期
应用场景
运行时常量池
多态的原理
类加载器的作用
类的加密和解密
生命周期概述加载->连接->初始化->使用->卸载
加载阶段
加载(Loading)阶段第一步时类加载器根据类的全限定名通过不同的渠道(本地文件、动态代理生成、通过网络传输的类)以二进制流的方式来获取字节码信息可以使用java代码扩展不同的渠道
类加载器在加载完类之后,Java虚拟机会将字节码中的信息保存到方法区中生成一个InstanceKlass对象 把保存类的所有信息 里面还包含实现特定功能比如多态的信息
同时Java虚拟机还会在堆中生成一份与方法区中数据类似的java.lang.Class对象 作用是在Java代码中去获取类的信息以及存储静态字段的数据(JDK8及以后)
对于开发者来说只需要访问堆中的Class对象而不需要访问方法区中所有信息。这样Java虚拟机就能很好地控制开发者访问数据的范围
连接阶段验证验证内容是否满足<Java虚拟机规范>
准备给静态变量赋初值准备阶段赋的是初始值 与 变量真正在代码中赋的值是不同的(真正赋值的这个步骤在初始化阶段完成)
但 ...
c++STL
哈希集合基本操作123456789101112unordered_map<int,int>h1;unordered_set<int>h2;// 在容器中查找以 key 键的键值对的个数。h1.count(键值)h2.count(键值)// 查找以 key 为键的键值对,如果找到,则返回一个指向该键值对的正向迭代器;反之,则返回一个指向容器中最后一个键值对之后位置的迭代器(如果 end() 方法返回的迭代器)。// 所以对find 进行判断 要根据迭代器进行判断h1.find(键值) == h1.end() // 没找到h1.find(键值) != h1.end() // 找到
遍历map1234567891011map<int,int>hash;// 遍历值for(auto & v : hash){ ...}// 遍历键值对for(auto it = hash.begin() ; it != hash.end() ; it++){ cout << it->first <&l ...
leetcode137只出现一次的数字Ⅱ
原题链接:https://leetcode.cn/problems/single-number-ii/description
要求线性时间复杂度 常数级空间
解法1: 哈希可以通过但不符合常数级空间
1234567891011121314151617class Solution {public: int singleNumber(vector<int>& nums) { // 数字 -> 出现次数 unordered_map<int,int>hash; for(auto & e : nums){ hash[e]++; } for(auto it = hash.begin() ; it != hash.end() ; it++){ if(it->second == 1){ return it->first; ...
JVM_2字节码文件详解
Java虚拟机的组成
字节码文件的组成
常量池:
常量池的作用: 避免相同的内容重复定义,节省空间
常量池中的数据都有一个编号 编号从1开始 在字段或者字节码指令中通过编号可以快速的找到对应的数据
字节码指令中通过编号引用到常量池的过程称之为符号引用
方法
字节码中的方法区域是存放字节码指令的核心位置,字节码指令的内容存放在方法的Code属性中
操作数栈是临时存放数据的地方,局部变量表是存放方法中的局部变量的位置
举例: