1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-08-14 05:21:42 +08:00

Compare commits

...

8 Commits

Author SHA1 Message Date
Guide
3bb366ad35
Merge pull request #1896 from xtexChooser/patch-1
fix typo
2023-01-17 20:47:59 +08:00
Guide
b15d4a639c
Merge pull request #1895 from cckkrr/patch-1
Update java-basic-questions-01.md
2023-01-17 20:47:44 +08:00
Guide
af19a6faca
Merge pull request #1893 from Konjacor/patch-1
修改一个错别字
2023-01-17 20:45:37 +08:00
Guide
74e2b5b47d
Merge pull request #1892 from Jarvan-Song/main
添加ArrayList随机访问标识RandomAccess
2023-01-17 20:44:47 +08:00
xtexChooser
2a1291a29a
fix typo 2023-01-16 13:08:19 +08:00
cckkrr
017a99aef3
Update java-basic-questions-01.md
是否笔误呢
2023-01-16 02:32:11 +08:00
Konjacor
5d1b0f0e05
修改一个错别字
212行 对象投 -> 对象头
2023-01-15 14:08:47 +08:00
Jarvan-Song
be26d790eb
添加ArrayList随机访问标识
添加ArrayList随机访问标识
2023-01-13 15:25:22 +08:00
4 changed files with 4 additions and 4 deletions

View File

@ -429,7 +429,7 @@ public int f4(int a, int b) {
这个需要结合 JVM 的相关知识,主要原因如下: 这个需要结合 JVM 的相关知识,主要原因如下:
1. 静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问。 1. 静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问。
2. 在类的非静态成员不存在的时候静态成员就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法操作。 2. 在类的非静态成员不存在的时候静态方法就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法操作。
#### 静态方法和实例方法有何不同? #### 静态方法和实例方法有何不同?

View File

@ -90,7 +90,7 @@ Java 集合框架如下图所示:
- **插入和删除是否受元素位置的影响:** - **插入和删除是否受元素位置的影响:**
- `ArrayList` 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行`add(E e)`方法的时候, `ArrayList` 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(`add(int index, E element)`)时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 - `ArrayList` 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行`add(E e)`方法的时候, `ArrayList` 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(`add(int index, E element)`)时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。
- `LinkedList` 采用链表存储,所以,如果是在头尾插入或者删除元素不受元素位置的影响(`add(E e)``addFirst(E e)``addLast(E e)``removeFirst()``removeLast()`),时间复杂度为 O(1),如果是要在指定位置 `i` 插入和删除元素的话(`add(int index, E element)``remove(Object o)` 时间复杂度为 O(n) ,因为需要先移动到指定位置再插入。 - `LinkedList` 采用链表存储,所以,如果是在头尾插入或者删除元素不受元素位置的影响(`add(E e)``addFirst(E e)``addLast(E e)``removeFirst()``removeLast()`),时间复杂度为 O(1),如果是要在指定位置 `i` 插入和删除元素的话(`add(int index, E element)``remove(Object o)` 时间复杂度为 O(n) ,因为需要先移动到指定位置再插入。
- **是否支持快速随机访问:** `LinkedList` 不支持高效的随机元素访问,而 `ArrayList` 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于`get(int index)`方法)。 - **是否支持快速随机访问:** `LinkedList` 不支持高效的随机元素访问,而 `ArrayList`实现了RandomAccess接口 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于`get(int index)`方法)。
- **内存空间占用:** `ArrayList` 的空 间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。 - **内存空间占用:** `ArrayList` 的空 间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。
我们在项目中一般是不会使用到 `LinkedList` 的,需要用到 `LinkedList` 的场景几乎都可以使用 `ArrayList` 来代替,并且,性能通常会更好!就连 `LinkedList` 的作者约书亚 · 布洛克Josh Bloch自己都说从来不会使用 `LinkedList` 我们在项目中一般是不会使用到 `LinkedList` 的,需要用到 `LinkedList` 的场景几乎都可以使用 `ArrayList` 来代替,并且,性能通常会更好!就连 `LinkedList` 的作者约书亚 · 布洛克Josh Bloch自己都说从来不会使用 `LinkedList`

View File

@ -209,7 +209,7 @@ JVM内存会划分为堆内存和非堆内存堆内存中也会划分为**年
当我们new一个对象后会先放到Eden划分出来的一块作为存储空间的内存但是我们知道对堆内存是线程共享的所以有可能会出现两个对象共用一个内存的情况。这里JVM的处理是为每个线程都预先申请好一块连续的内存空间并规定了对象存放的位置而如果空间不足会再申请多块内存空间。这个操作我们会称作TLAB有兴趣可以了解一下。 当我们new一个对象后会先放到Eden划分出来的一块作为存储空间的内存但是我们知道对堆内存是线程共享的所以有可能会出现两个对象共用一个内存的情况。这里JVM的处理是为每个线程都预先申请好一块连续的内存空间并规定了对象存放的位置而如果空间不足会再申请多块内存空间。这个操作我们会称作TLAB有兴趣可以了解一下。
当Eden空间满了之后会触发一个叫做Minor GC就是一个发生在年轻代的GC的操作存活下来的对象移动到Survivor0区。Survivor0区满后触发 Minor GC就会将存活对象移动到Survivor1区此时还会把from和to两个指针交换这样保证了一段时间内总有一个survivor区为空且to所指向的survivor区为空。经过多次的 Minor GC后仍然存活的对象**这里的存活判断是15次对应到虚拟机参数为 -XX:MaxTenuringThreshold 。为什么是15因为HotSpot会在对象中的标记字段里记录年龄分配到的空间仅有4位所以最多只能记录到15**会移动到老年代。老年代是存储长期存活的对象的占满时就会触发我们最常听说的Full GC期间会停止所有线程等待GC的完成。所以对于响应要求高的应用应该尽量去减少发生Full GC从而避免响应超时的问题。 当Eden空间满了之后会触发一个叫做Minor GC就是一个发生在年轻代的GC的操作存活下来的对象移动到Survivor0区。Survivor0区满后触发 Minor GC就会将存活对象移动到Survivor1区此时还会把from和to两个指针交换这样保证了一段时间内总有一个survivor区为空且to所指向的survivor区为空。经过多次的 Minor GC后仍然存活的对象**这里的存活判断是15次对应到虚拟机参数为 -XX:MaxTenuringThreshold 。为什么是15因为HotSpot会在对象中的标记字段里记录年龄分配到的空间仅有4位所以最多只能记录到15**会移动到老年代。老年代是存储长期存活的对象的占满时就会触发我们最常听说的Full GC期间会停止所有线程等待GC的完成。所以对于响应要求高的应用应该尽量去减少发生Full GC从而避免响应超时的问题。
而且当老年区执行了full gc之后仍然无法进行对象保存的操作就会产生OOM这时候就是虚拟机中的堆内存不足原因可能会是堆内存设置的大小过小这个可以通过参数-Xms、-Xmx来调整。也可能是代码中创建的对象大且多而且它们一直在被引用从而长时间垃圾收集无法收集它们。 而且当老年区执行了full gc之后仍然无法进行对象保存的操作就会产生OOM这时候就是虚拟机中的堆内存不足原因可能会是堆内存设置的大小过小这个可以通过参数-Xms、-Xmx来调整。也可能是代码中创建的对象大且多而且它们一直在被引用从而长时间垃圾收集无法收集它们。

View File

@ -37,7 +37,7 @@ Java16 将 ZGC 线程栈处理从安全点转移到一个并发阶段,甚至
> 以下介绍摘自:[实操 | 剖析 Java16 新语法特性](https://xie.infoq.cn/article/8304c894c4e38318d38ceb116),原文写的很不错,推荐阅读。 > 以下介绍摘自:[实操 | 剖析 Java16 新语法特性](https://xie.infoq.cn/article/8304c894c4e38318d38ceb116),原文写的很不错,推荐阅读。
早在 Java9 版本时Java 的设计者们就对 `@Deprecated` 注解进行了一次升级,增加了 `since``forRemova`l 等 2 个新元素。其中since 元素用于指定标记了 `@Deprecated` 注解的 API 被弃用时的版本,而 `forRemoval` 则进一步明确了 API 标记 @Deprecated 注解时的语义,如果`forRemoval=true`时,则表示该 API 在未来版本中肯定会被删除,开发人员应该使用新的 API 进行替代不再容易产生歧义Java9 之前,标记 @Deprecated 注解的 API语义上存在多种可能性比如存在使用风险、可能在未来存在兼容性错误、可能在未来版本中被删除以及应该使用更好的替代方案等 早在 Java9 版本时Java 的设计者们就对 `@Deprecated` 注解进行了一次升级,增加了 `since``forRemoval` 等 2 个新元素。其中since 元素用于指定标记了 `@Deprecated` 注解的 API 被弃用时的版本,而 `forRemoval` 则进一步明确了 API 标记 @Deprecated 注解时的语义,如果`forRemoval=true`时,则表示该 API 在未来版本中肯定会被删除,开发人员应该使用新的 API 进行替代不再容易产生歧义Java9 之前,标记 @Deprecated 注解的 API语义上存在多种可能性比如存在使用风险、可能在未来存在兼容性错误、可能在未来版本中被删除以及应该使用更好的替代方案等
仔细观察原始类型的包装类(比如:`java.lang.Integer``java.lang.Double`),不难发现,其构造函数上都已经标记有`@Deprecated(since="9", forRemoval = true)`注解,这就意味着其构造函数在将来会被删除,不应该在程序中继续使用诸如`new Integer();`这样的编码方式(建议使用`Integer a = 10;`或者`Integer.valueOf()`函数),如果继续使用,编译期将会产生'Integer(int)' is deprecated and marked for removal 告警。并且,值得注意的是,这些包装类型已经被指定为同 `java.util.Optional``java.time.LocalDateTime` 一样的值类型。 仔细观察原始类型的包装类(比如:`java.lang.Integer``java.lang.Double`),不难发现,其构造函数上都已经标记有`@Deprecated(since="9", forRemoval = true)`注解,这就意味着其构造函数在将来会被删除,不应该在程序中继续使用诸如`new Integer();`这样的编码方式(建议使用`Integer a = 10;`或者`Integer.valueOf()`函数),如果继续使用,编译期将会产生'Integer(int)' is deprecated and marked for removal 告警。并且,值得注意的是,这些包装类型已经被指定为同 `java.util.Optional``java.time.LocalDateTime` 一样的值类型。