Java中重点知识

1.&(按位与)和&&(逻辑与)的区别?

&&具有短路功能,当第一个表达式为false,则不执行第二个表达式。
&可以当位运算符,例如一个整数与15做&操作,可以获得该整数最后4个人bit位。

2.Integer 与 int 的区别?

int是Java提供的8种原始数据类型之一,Java为每个原始类型提供了封装类,Integer为的就是以对象的形式去更好地操作int类型的变量。Integer默认为null,int默认为0。

3.String是基本类型吗?

Java的基本类型有byte,short,int,long,char,float,double,boolean。
String类型是final修饰的类,不能被继承,不能被修改。

4.面向对象的特征

抽象:指将一类对象的共同特征总结出来构建类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,不关注这些行为的细节。
继承:指从已有类得到继承信息创建类的过程。
封装:指把数据和操作的方法绑定起来,对数据的访问只能通过已定义的接口。例如:Integer封装了整数int,ArrayList封装了数组Object[]。封装隐藏了实现的内部细节,你只需通过简单的接口调用就能实现你想要的功能(如调用contains方法就能知道数组里是否有要找的对象)
多态:简单讲就是父类型的引用指向子类型的对象。能通过改变引用指向不同的对象从而去实现该对象的方法,而无需去改变已有的代码,提高了代码的可维护性,可扩展性,(如 List list=new ArrrayList; list.add(); list即可以指向ArrayList的对象也可以指向LinkedList对象,方法也不用改)多态分为运行时多态和编译时多态。编译时多态指对于多个同名方法,如果在编译时能够确定执行同名方法中的哪一个,则称为编译时多态性。运行时多态是面向对象最精髓的地方。上述例子就是一个运行时多态

5.抽象类与接口的区别

1.抽象类和接口都不能直接实例化,子类继承它们要实现所有抽象方法
2.接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
3.抽象类里可以没有抽象方法。
4.接口可以被类多实现(被其他接口多继承),抽象类只能被子类单继承。
5.接口中没有 this 指针,没有构造函数,不能拥有实例字段(实例变量)或实例方法。

6.StringBuilder和StringBuffer的区别

方法完全相同,循环连接字符串时效率比String高,只是StringBuller的所有方法都被synchronsized修饰,是线程安全的,但是在单线程环境下StringBuilder效率更高是Java 5引入的。

GC Algorithms

Mark-Sweep(标记清除)
Copying(拷贝)
Mark-Compact(标记压缩)

Java 内存区域

JVM内存模型.png
在该图中堆和方法区是所有线程共享的。

1 程序计数器

内存空间小,线程私有。每个线程都有自己的程序计数器。通过改变这个计数器的值来选取下一条需要执行指令的字节码指令。所以它存放的是当前线程下一条指令的地址,是不断变化的。并将地址送至执行引擎去执行指令

2 java虚拟机栈

线程私有,生命周期和线程一致。每个线程都有自己的栈空间。描述的是 Java 方法执行的内存模型:每个方法在执行时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。
2.1 局部变量表
存放了编译期可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型)等
2.2 操作数栈
存储数据的临时操作过程,
2.3 动态链接
存储运行时动态生成的地址,比如调用到的某方法在方法区的实际字节码地址(指令)
2.4 方法出口
存储当前方法结束后要回到地方的下一条指令的地址
StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。
OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存。

3 本地方法栈

区别于 Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。也会有 StackOverflowError 和 OutOfMemoryError 异常 本地C语言写的方法(操作系统中)

4 Java堆

对于绝大多数应用来说,这块区域是 JVM 所管理的内存中最大的一块。线程共享,主要是存放对象实例和数组。内部会划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer, TLAB)。可以位于物理上不连续的空间,但是逻辑上要连续。
QQ截图20200516232733.png
从图中可以看出堆中分为年轻代和老年代
刚创建的对象放在Eden区 当Eden区放满了会执行minor GC算法回收无效的对象
GC roots根节点:如栈中对象引用类型就是一个GC roots根节点
Eden区的对象如果经历一次GC没有被清理的对象会移动到From区。然后From区放满了执行GC没有回收的对象会移动到To区,每经历一次GC,剩下的对象就移动到另一个存储区,直到对象的年龄到15的时候存入老年代区。当老年代存满了会调用full GC算法,如果full GC执行完内存还是满的则报错内存溢出
当full GC执行时会停止应用程序所有线程(程序卡死)所以JVM调优的目的是减少Full GC的次数

5 方法区

属于共享内存区域,是Java虚拟机外的内存,1.8后叫元空间,以前叫永久代,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

每个区域存储的内容

QQ截图20200517001257.png
题目描述 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

要求
不能更改原数组(假设数组是只读的)。
只能使用额外的 O(1) 的空间。
时间复杂度小于 O(n2) 。
数组中只有一个重复的数字,但它可能不止重复出现一次

使用快慢指针,时间O(n),空间O(1) 把数组看作链表,nums[i]表示第i个节点指向第nums[i]个节点,然后问题就变成了找一个有环的链表中环的起始节点

class Solution {
  public int findDuplicate(int[] nums) {
        int fast = nums[0], slow = nums[0];
        slow = nums[slow];
        fast = nums[nums[fast]];
        while(slow!=fast){
            slow = nums[slow];
            fast = nums[nums[fast]];
        }
        fast = nums[0];
        while(slow!=fast){
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
}

Collection

对象是封装数据的,集合是用于存储对象的。
集合长度可变,只能存储引用数据类型,可以是不同数据类型。
Collection
Collection是接口的接口(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除效率高, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 查询效率高, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,无序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序
1.添加
add(object)添加一个元素
addAll(Collection)添加一个集合中所有元素
2.删除
clear()清空集合
remove(obj)删除指定元素
removeAll(Collection)删除部分与Collection中一致的元素
3.判断
contains(obj)集合是否包含指定元素
containsAll(Collection)集合中是否包含指定的多个元素
isEmpty()集合是否为空
4.获取
size()集合中有几个元素
5.交集
retainAll(Collection)是否有交集
6.iterator() 迭代器
7.集合转数组
toArray()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hD41Lzle-1635307179990)(http://huangxiaohua.top/upload/2020/6/822135-20200603095608702-1240978642-5ef4d7eba83440ceb63868ae5cbb86e9.jpg)]
Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类,哈希表,同步线程安全
├———HashMap 接口实现类 数组+链表+红黑树,没有同步,线程不安全
|———ConcurenHashMap hashMap的线程安全实现
│—————–├ LinkedHashMap 双向链表+哈希表实现
├———TreeMap 红黑树 对所有的key进行排序

HashTable底层实现和HashMap实现原理基本上一致,只不过HashTable等所有提供的方法都通过Synchronzied修饰,所以HashTable是线程安全的,但是性能比较差。深入理解HashMap可以看我另一篇博文
20180803205119738.png

集合常用的工具类有Collections和Arrays。
Arrays.copyOfRange(T[ ] original,int from,int to) 返回新数组
将一个原始的数组original,从下标from开始复制,复制到上标to前一个元素,
Arrays.sort(object[]) 对数组排序
Arrays.toString(Object[] array) 返回数组的字符串形式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值