java知识点

Posted 吐个泡泡oo0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java知识点相关的知识,希望对你有一定的参考价值。

目录
2021年5月16日11:03:06 3
Vector与 ArrayList 的比较 3
LinkedList与 ArrayList 的比较 3
线程实现的3种方式 3
1、实现 Runnable 接口 3
2、实现 Callable 接口 4
3、继承 Thread 类 4
4、实现Runnable接口 VS 继承 Thread 类 5
互斥同步 5
java线程状态 7
java线程安全 7
多线程开发良好的实践 8
JVM结构 9
JVM垃圾回收机制 11
java  IO 11
JDK1.8 的特征(区别) 14
1、JVM中方法区 14
2021年5月20日16:30:51 15
Linux系列 15
1、VIM 三个模式 15
2、文件属性 16
3、文件与目录的基本操作 16
4、修改权限 18
5、默认权限 19
6、目录的权限 19
7、获取文件内容 19
8、指令与文件搜索 20
9、压缩指令 21
10、进程管理 21
查看进程 21

  


2021年5月16日11:03:06

ArrayList 是基于数组实现的,所以支持快速随机访问,

Vector与 ArrayList 的比较

  • Vector 是同步的,因此开销就比 ArrayList 要大,访问速度更慢。最好使用 ArrayList 而不是 Vector,因为同步操作完全可以由程序员自己来控制;

  • Vector 每次扩容请求其大小的 2 倍(也可以通过构造函数设置增长的容量),而 ArrayList 是 1.5 倍。

LinkedList与 ArrayList 的比较

LinkedList是基于双向链表实现,使用 Node 存储链表节点信息。

ArrayList 基于动态数组实现,LinkedList 基于双向链表实现。ArrayList 和 LinkedList 的区别可以归结为数组和链表的区别:

  • 数组支持随机访问,但插入删除的代价很高,需要移动大量元素;

  • 链表不支持随机访问,但插入删除只需要改变指针。


线程实现的3种方式

  • 实现 Runnable 接口;

  • 实现 Callable 接口;

  • 继承 Thread 类。

实现 Runnable 和 Callable 接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过 Thread 来调用。可以理解为任务是通过线程驱动从而执行的。


1、实现 Runnable 接口

需要实现接口中的 run() 方法。

public class MyRunnable implements Runnable {

@Override

public void run() {

// ...

}

}

使用 Runnable 实例再创建一个 Thread 实例,然后调用 Thread 实例的 start() 方法来启动线程。

public static void main(String[] args) {

MyRunnable instance = new MyRunnable();

Thread thread = new Thread(instance);

thread.start();

}


2、实现 Callable 接口

与 Runnable 相比,Callable 可以有返回值,返回值通过 FutureTask 进行封装。

public class MyCallable implements Callable<Integer> {

public Integer call() {

return 123;

}

}

public static void main(String[] args) throws ExecutionException, InterruptedException {

MyCallable mc = new MyCallable();

FutureTask<Integer> ft = new FutureTask<>(mc);

Thread thread = new Thread(ft);

thread.start();

System.out.println(ft.get());

}


3、继承 Thread 类

同样也是需要实现 run() 方法,因为 Thread 类也实现了 Runable 接口。

当调用 start() 方法启动一个线程时,虚拟机会将该线程放入就绪队列中等待被调度,当一个线程被调度时会执行该线程的 run() 方法。


public class MyThread extends Thread {

public void run() {

// ...

}

}

public static void main(String[] args) {

MyThread mt = new MyThread();

mt.start();

}

4、实现Runnable接口 VS 继承 Thread 类

实现接口会更好一些,因为:

Java 不支持多重继承,因此继承了 Thread 类就无法继承其它类,但是可以实现多个接口;

类可能只要求可执行就行,继承整个 Thread 类开销过大。


互斥同步

Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是 JVM 实现的 synchronized,而另一个是 JDK 实现的 ReentrantLock。


比较

1. 锁的实现

synchronized 是 JVM 实现的,而 ReentrantLock 是 JDK 实现的。

2. 性能

新版本 Java 对 synchronized 进行了很多优化,例如自旋锁等,synchronized 与 ReentrantLock 大致相同。

3. 等待可中断

当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。

ReentrantLock 可中断,而 synchronized 不行。

4. 公平锁

公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。

synchronized 中的锁是非公平的,ReentrantLock 默认情况下也是非公平的,但是也可以是公平的。

5. 锁绑定多个条件

一个 ReentrantLock 可以同时绑定多个 Condition 对象。

使用选择

除非需要使用 ReentrantLock 的高级功能,否则优先使用 synchronized。这是因为 synchronized 是 JVM 实现的一种锁机制,JVM 原生地支持它,而 ReentrantLock 不是所有的 JDK 版本都支持。并且使用 synchronized 不用担心没有释放锁而导致死锁问题,因为 JVM 会确保锁的释放。


join()

在线程中调用另一个线程的 join() 方法,会将当前线程挂起,而不是忙等待,直到目标线程结束。

wait() 和 sleep() 的区别

  • wait() 是 Object 的方法,而 sleep() 是 Thread 的静态方法;

  • wait() 会释放锁,sleep() 不会。



java线程状态


java线程安全

多个线程不管以何种方式访问某个类,并且在主调代码中不需要进行同步,都能表现正确的行为。


线程安全有以下几种实现方式:

1、不可变

不可变(Immutable)的对象一定是线程安全的,不需要再采取任何的线程安全保障措施。只要一个不可变的对象被正确地构建出来,永远也不会看到它在多个线程之中处于不一致的状态。多线程环境下,应当尽量使对象成为不可变,来满足线程安全。

不可变的类型:

  • final 关键字修饰的基本数据类型

  • String

  • 枚举类型

  • Number 部分子类,如 Long 和 Double 等数值包装类型,BigInteger 和 BigDecimal 等大数据类型。但同为 Number 的原子类 AtomicInteger 和 AtomicLong 则是可变的。


2、互斥同步

synchronized 和 ReentrantLock。


3、非阻塞同步

互斥同步最主要的问题就是线程阻塞和唤醒所带来的性能问题,因此这种同步也称为阻塞同步。

互斥同步属于一种悲观的并发策略,总是认为只要不去做正确的同步措施,那就肯定会出现问题。无论共享数据是否真的会出现竞争,它都要进行加锁(这里讨论的是概念模型,实际上虚拟机会优化掉很大一部分不必要的加锁)、用户态核心态转换、维护锁计数器和检查是否有被阻塞的线程需要唤醒等操作。


4、有些情况无需设置同步

要保证线程安全,并不是一定就要进行同步。如果一个方法本来就不涉及共享数据,那它自然就无须任何同步措施去保证正确性。


多线程开发良好的实践

  • 给线程起个有意义的名字,这样可以方便找 Bug。

  • 缩小同步范围,从而减少锁争用。例如对于 synchronized,应该尽量使用同步块而不是同步方法。

  • 多用同步工具少用 wait() 和 notify()。首先,CountDownLatch, CyclicBarrier, Semaphore 和 Exchanger 这些同步类简化了编码操作,而用 wait() 和 notify() 很难实现复杂控制流;其次,这些同步类是由最好的企业编写和维护,在后续的 JDK 中还会不断优化和完善。

  • 使用 BlockingQueue 实现生产者消费者问题。

  • 多用并发集合少用同步集合,例如应该使用 ConcurrentHashMap 而不是 Hashtable。

  • 使用本地变量和不可变类来保证线程安全。

  • 使用线程池而不是直接创建线程,这是因为创建线程代价很高,线程池可以有效地利用有限的线程来启动任务。


JVM结构

java知识点 java知识点


java知识点

JVM垃圾回收机制

垃圾收集主要是针对堆和方法区进行。程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后就会消失,因此不需要对这三个区域进行垃圾回收。


java  IO

Java 的 I/O 大概可以分成以下几类:

  • 磁盘操作:File

  • 字节操作:InputStream 和 OutputStream

  • 字符操作:Reader 和 Writer

  • 对象操作:Serializable

  • 网络操作:Socket

  • 新的输入/输出:NIO


网络操作

Java 中的网络支持:

  • URL:统一资源定位符;

  • Sockets:使用 TCP 协议实现网络通信;

  • Datagram:使用 UDP 协议实现网络通信。






JDK1.8 的特征(区别)

1、JVM中方法区




2021年5月20日16:30:51

Linux系列

在面试中,Linux 知识点相对于网络和操作系统等知识点而言不是那么重要,只需要重点掌握一些原理和命令即可。为了方便大家准备面试,在此先将一些比较重要的知识点列出来:

  • 能简单使用 cat,grep,cut 等命令进行一些操作;

  • 文件系统相关的原理,inode 和 block 等概念,数据恢复;

  • 硬链接与软链接;

  • 进程管理相关,僵尸进程与孤儿进程,SIGCHLD 。

1、VIM 三个模式

  • 一般指令模式(Command mode):VIM 的默认模式,可以用于移动游标查看内容;

  • 编辑模式(Insert mode):按下 "i" 等按键之后进入,可以对文本进行编辑;

  • 指令列模式(Bottom-line mode):按下 ":" 按键之后进入,用于保存退出等操作。


在指令列模式下,有以下命令用于离开或者保存文件。

命令

作用

:w

写入磁盘

:w!

当文件为只读时,强制写入磁盘。到底能不能写入,与用户对该文件的权限有关

:q

离开

:q!

强制离开不保存

:wq

写入磁盘后离开

:wq!

强制写入磁盘后离开


2、文件属性

用户分为三种:文件拥有者、群组以及其它人,对不同的用户有不同的文件权限。

使用 ls 查看一个文件时,会显示一个文件的信息,例如 drwxr-xr-x 3 root root 17 May 6 00:14 .config,对这个信息的解释如下:

  • drwxr-xr-x:文件类型以及权限,第 1 位为文件类型字段,后 9 位为文件权限字段

  • 3:链接数

  • root:文件拥有者

  • root:所属群组

  • 17:文件大小

  • May 6 00:14:文件最后被修改的时间

  • .config:文件名

常见的文件类型及其含义有:

  • d:目录

  • -:文件

  • l:链接文件

9 位的文件权限字段中,每 3 个为一组,共 3 组,每一组分别代表对文件拥有者、所属群组以及其它人的文件权限。一组权限中的 3 位分别为 r、w、x 权限,表示可读、可写、可执行。

文件时间有以下三种:

  • modification time (mtime):文件的内容更新就会更新;

  • status time (ctime):文件的状态(权限、属性)更新就会更新;

  • access time (atime):读取文件时就会更新。

3、文件与目录的基本操作

1. ls

列出文件或者目录的信息,目录的信息就是其中包含的文件。

## ls [-aAdfFhilnrRSt] file|dir

-a :列出全部的文件

-d :仅列出目录本身

-l :以长数据串行列出,包含文件的属性与权限等等数据

2. cd

更换当前目录。

cd [相对路径或绝对路径]

3. mkdir

创建目录。

## mkdir [-mp] 目录名称

-m :配置目录权限

-p :递归创建目录

4. rmdir

删除目录,目录必须为空。

rmdir [-p] 目录名称

-p :递归删除目录

5. touch

更新文件时间或者建立新文件。

## touch [-acdmt] filename

-a :更新 atime

-c :更新 ctime,若该文件不存在则不建立新文件

-m :更新 mtime

-d :后面可以接更新日期而不使用当前日期,也可以使用 --date="日期或时间"

-t :后面可以接更新时间而不使用当前时间,格式为[YYYYMMDDhhmm]

6. cp

复制文件。如果源文件有两个以上,则目的文件一定要是目录才行。

cp [-adfilprsu] source destination

-a :相当于 -dr --preserve=all

-d :若来源文件为链接文件,则复制链接文件属性而非文件本身

-i :若目标文件已经存在时,在覆盖前会先询问

-p :连同文件的属性一起复制过去

-r :递归复制

-u :destination 比 source 旧才更新 destination,或 destination 不存在的情况下才复制

--preserve=all :除了 -p 的权限相关参数外,还加入 SELinux 的属性, links, xattr 等也复制了

7. rm

删除文件。

## rm [-fir] 文件或目录

-r :递归删除

8. mv

移动文件。

## mv [-fiu] source destination

## mv [options] source1 source2 source3 .... directory

-f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖


4、修改权限

可以将一组权限用数字来表示,此时一组权限的 3 个位当做二进制数字的位,从左到右每个位的权值为 4、2、1,即每个权限对应的数字权值为 r : 4、w : 2、x : 1。

## chmod [-R] xyz dirname/filename

示例:将 .bashrc 文件的权限修改为 -rwxr-xr--。

## chmod 754 .bashrc

也可以使用符号来设定权限。

## chmod [ugoa]  [+-=] [rwx] dirname/filename

- u:拥有者

- g:所属群组

- o:其他人

- a:所有人

- +:添加权限

- -:移除权限

- =:设定权限

示例:为 .bashrc 文件的所有用户添加写权限。

## chmod a+w .bashrc


5、默认权限

  • 文件默认权限:文件默认没有可执行权限,因此为 666,也就是 -rw-rw-rw- 。

  • 目录默认权限:目录必须要能够进入,也就是必须拥有可执行权限,因此为 777 ,也就是 drwxrwxrwx。

可以通过 umask 设置或者查看默认权限,通常以掩码的形式来表示,例如 002 表示其它用户的权限去除了一个 2 的权限,也就是写权限,因此建立新文件时默认的权限为 -rw-rw-r--。


6、目录的权限

文件名不是存储在一个文件的内容中,而是存储在一个文件所在的目录中。因此,拥有文件的 w 权限并不能对文件名进行修改。


目录存储文件列表,一个目录的权限也就是对其文件列表的权限。因此,目录的 r 权限表示可以读取文件列表;w 权限表示可以修改文件列表,具体来说,就是添加删除文件,对文件名进行修改;x 权限可以让该目录成为工作目录,x 权限是 r 和 w 权限的基础,如果不能使一个目录成为工作目录,也就没办法读取文件列表以及对文件列表进行修改了。


7、获取文件内容

1. cat

取得文件内容。

## cat [-AbEnTv] filename

-n :打印出行号,连同空白行也会有行号,-b 不会

2. tac

是 cat 的反向操作,从最后一行开始打印。

3. more

和 cat 不同的是它可以一页一页查看文件内容,比较适合大文件的查看。

4. less

和 more 类似,但是多了一个向前翻页的功能。

5. head

取得文件前几行。

## head [-n number] filename

-n :后面接数字,代表显示几行的意思

6. tail

是 head 的反向操作,只是取得是后几行。

7. od

以字符或者十六进制的形式显示二进制文件。


8、指令与文件搜索

1. which

指令搜索。

## which [-a] command

-a :将所有指令列出,而不是只列第一个

2. whereis

文件搜索。速度比较快,因为它只搜索几个特定的目录。

## whereis [-bmsu] dirname/filename

3. locate

文件搜索。可以用关键字或者正则表达式进行搜索。

locate 使用 /var/lib/mlocate/ 这个数据库来进行搜索,它存储在内存中,并且每天更新一次,所以无法用 locate 搜索新建的文件。可以使用 updatedb 来立即更新数据库。

## locate [-ir] keyword

-r:正则表达式

4. find

文件搜索。可以使用文件的属性和权限进行搜索。

## find [basedir] [option]

example: find . -name "shadow*"


9、压缩指令

1. gzip

gzip 是 Linux 使用最广的压缩指令,可以解开 compress、zip 与 gzip 所压缩的文件。

经过 gzip 压缩过,源文件就不存在了。

有 9 个不同的压缩等级可以使用。

可以使用 zcat、zmore、zless 来读取压缩文件的内容。

$ gzip [-cdtv#] filename

-c :将压缩的数据输出到屏幕上

-d :解压缩

-t :检验压缩文件是否出错

-v :显示压缩比等信息

-# :# 为数字的意思,代表压缩等级,数字越大压缩比越高,默认为 6

2. bzip2

提供比 gzip 更高的压缩比。

查看命令:bzcat、bzmore、bzless、bzgrep。

$ bzip2 [-cdkzv#] filename

-k :保留源文件

3. xz

提供比 bzip2 更佳的压缩比。

可以看到,gzip、bzip2、xz 的压缩比不断优化。不过要注意的是,压缩比越高,压缩的时间也越长。

查看命令:xzcat、xzmore、xzless、xzgrep。

$ xz [-dtlkc#] filename


10、进程管理

查看进程

1. ps

查看某个时间点的进程信息。

示例:查看自己的进程

## ps -l

示例:查看系统所有进程

## ps aux

示例:查看特定的进程

## ps aux | grep threadx

2. pstree

查看进程树。

示例:查看所有进程树

## pstree -A

3. top

实时显示进程信息。

示例:两秒钟刷新一次

## top -d 2

4. netstat

查看占用端口的进程

示例:查看特定端口的进程

## netstat -anp | grep port




以上是关于java知识点的主要内容,如果未能解决你的问题,请参考以下文章

Java知识点

[ Java面试题 ]Java 开发岗面试知识点解析

java知识点----java入门

Java基础面试知识点总结

java基础知识有那些

Java容器(ListSetMap)知识点快速复习手册(下)