java

  • 算法:八皇后问题

    八皇后问题

    该图片由MisterMoeterPixabay上发布

    你好,我是看山。

    八皇后问题,是以国际象棋为背景:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任意两个皇后都不能处于同一条横行、纵行或斜线上。

  • 如果非要在多线程中使用 ArrayList 会发生什么?(第二篇)

    如果非要在多线程中使用 ArrayList 会发生什么?(第二篇)

    你好,我是看山。

    前面写过一篇文章 《如果非要在多线程中使用 ArrayList 会发生什么?》,有读者反馈,Java 11 代码已经修复,还会出现 null 元素。

    为了便于理解,当时只是通过代码执行顺序说明了异常原因。其实多线程中还会涉及 Java 内存模型,本文就从这方面说明一下。

  • 如果非要在多线程中使用ArrayList会发生什么?

    如果非要在多线程中使用ArrayList会发生什么?

    你好,我是看山。

    我们都知道,Java中的ArrayList是非线程安全的,这个知识点太熟了,甚至面试的时候都很少问了。

    但是我们真的清楚原理吗?或者知道多线程情况下使用ArrayList会发生什么?

    前段时间,我们就踩坑了,而且直接踩了两个坑,今天就来扒一扒。

  • JDK中居然也有反模式接口常量

    你好,我是看山。

    在实际开发过程中,经常会需要定义一个文件,用于存储一些常量,这些常量设计为静态公共常量(使用 public static final 修饰)。这个时候就出现两种选择:

    1. 在接口中定义常量,比如 JDK 1.1 中的 java.io.ObjectStreamConstans 接口;
    2. 在类中定义常量,比如 JDK 1.7 中的 java.nio.charset.StandardCharsets

    这两种方式都能够达到要求:存储常量、无需实例化。下面分情况讨论下两种方式孰优孰劣。

  • 看山聊 Java:IPv4 与 int 之间互相转换

    IPv4 与 int 之间互相转换

    该图片由suju-fotoPixabay上发布

    你好,我是看山。

    目前数据存储设备越来越便宜,已经不存在为了节省空间而引入复杂计算的场景,但是有时候,将 IPv4 这种长字符串数据转换为数字,更加便于比较和查询。

  • java.lang.OutOfMemoryError:GC overhead limit exceeded

    java.lang.OutOfMemoryError:GC overhead limit exceeded

    该图片由Here and now, unfortunately, ends my journey on PixabayPixabay上发布

    你好,我是看山。

    java.lang.OutOfMemoryError这个错误是比较经典的错误了,经过JDK不断的迭代,服务器硬件的不断升级。。。总之,社会在发展,时代在进步。很多错误已经消失在时代的浪潮中。我也是很久没有见过这个错误了,以至于都以为在Java的世界中不会再碰到这个错误。结果,就在最疏忽的时候碰到了TA,真是,心中一万只神兽奔袭而过,狠狠的践踏了我这颗上了年纪的心脏啊。

    吐槽完毕,言归正传。

    Java刚刚出现的年代,有一个相比于其他语言的优势就是,内存回收机制。不需要明确的调用释放内存的API,java就自动完成,这个过程就是Garbage Collection,简称GC。这对以懒著称的程序猿们来说,绝对是重大利好。但是,凡事有利必有弊,可以肯定的是,Java语言是人创造的,GC也是人编写的代码,绝对不是机器自动完成的。也就是说,GC的过程是另外一群程序猿根据可能出现的情况,预设了GC条件,把符合回收条件的内存空间释放出来。一旦被占用的内存空间不符合释放的条件,GC没办法清理,那就会适时出现java.lang.OutOfMemoryError。这个错误就是提醒我们这群程序猿,写GC程序的程序猿不知道这种情况怎么处理,为了安全也不便处理,谁使用Java就自己看着解决吧。

    说起来,java.lang.OutOfMemoryError有几种分类的,这次碰到的是java.lang.OutOfMemoryError: GC overhead limit exceeded,下面就来说说这种类型的内存溢出。

  • Java 注释总结

    Java 注释总结

    该图片由Nimrod OrenPixabay上发布

    你好,我是看山。

    在 Java 的编写过程中我们需要对一些程序进行注释,除了自己方便阅读,更为别人更好理解自己的程序,所以我们需要进行一些注释,可以是编程思路或者是程序的作用,总而言之就是方便自己他人更好的阅读。

  • Java 并发基础(五):面试实战之多线程顺序打印

    Java 并发基础(五):面试实战之多线程顺序打印

    你好,我是看山。

    来个面试题,让大家练练手。这个题在阿里和小米都被问过,所以放在这个抛砖引玉,期望能够得到一个更佳的答案。

  • Java 并发基础(一):synchronized 锁同步

    Java 并发基础(一):synchronized 锁同步

    你好,我是看山。

    synchronized 是 java 内置的同步锁实现,一个关键字实现对共享资源的锁定。synchronized 有 3 种使用场景,场景不同,加锁对象也不同:

    1. 普通方法:锁对象是当前实例对象
    2. 静态方法:锁对象是类的 Class 对象
    3. 方法块:锁对象是 synchronized 括号中的对象

  • 看山聊 Java:检查日期字符串是否合法

    看山聊 Java:检查日期字符串是否合法

    该图片由Анастасия БелоусоваPixabay上发布

    你好,我是看山。

  • 看山聊 Java:Date 与 LocalDate 或 LocalDateTime 互相转换

    看山聊 Java:Date 与 LocalDate 或 LocalDateTime 互相转换

    你好,我是看山。

    从 Java1 到 Java8 将近 20 年,再加上 Java8 的普及时间、各种历史 API 兼容过渡时间。我们很多时候需要在旧时间 API 与新时间 API 之间切换,并行使用。今天就来说说,java.util.Datejava.time.LocalDate/LocalDateTime如何互相转换。

  • 看山聊 Java:使用 Java8 中的时间类

    看山聊 Java:使用 Java8 中的时间类

    该图片由Erik KaritsPixabay上发布

    你好,我是看山。

    前面聊了聊 Java8 新版时间 API 的类,然后又说了说怎么与旧版时间 API 的转换,今天来聊聊怎样通过新 API 实现老 API 的功能,这样我们就可以逐步替换掉旧版 API,与时俱进。

  • java import 导入包时,我们需要注意什么呢?

    java import 导入包

    你好,我是看山。

    这篇文章起因是 code review 时和同事关于 import 导入声明的分歧。

    用过 IDEA 的都知道,默认情况下,通过 import 导入类时,当数量达到设置数量(类 5 个、静态变量 3 个),就会改为按需导入方式,也就是使用使用*号折叠导入。

    同事建议不要采用按需导入,要使用单类型导入 (single-type-import)。而我是觉得既然 IDEA 作为宇宙级的 IDE,不会在这种地方出现纰漏,所以想继续按照 IDEA 默认配置来。

    所以总结一下这两种方式的差异。如果对 java import 不熟悉,可以从 这里 看看。

  • Switch 块、Switch 表达式、Switch 模式匹配,越来越好用的 Switch

    Switch 块、Switch 表达式、Switch 模式匹配,越来越好用的 Switch

    你好,我是看山。

    本文收录在 《从小工到专家的 Java 进阶之旅》 系列专栏中。

    与 if-else 一样,switch 语法是用来做条件判断的。当条件清晰简洁时,能够有效地提升代码可读性。switch 语法从 Java5 开始,Java12 增加了 Switch 表达式(Java14 提供正式版),Java17 增加 Switch 模式匹配(预览版)。

    本文的目标是期望读者可以掌握 Switch 语法的所有能力,在需要的时候信手拈来。

  • 一文掌握 Java8 Stream 中 Collectors 的 24 个操作

    一文掌握 Java8 Stream 中 Collectors 的 24 个操作

    你好,我是看山。

    Java8 应该算是业界主版本了,版本中重要性很高的一个更新是Stream流处理。关于流处理内容比较多,本文主要是说一下Stream中的Collectors工具类的使用。

  • Java 进阶:使用 Lambda 表达式实现超强的排序功能

    Java 进阶:使用 Lambda 表达式实现超强的排序功能

    该图片由Michael KleinsasserPixabay上发布

    你好,我是看山。

    本文被《Java 进阶》专栏收录,在公众号「看山的小屋」,回复“java”可获取源码。

    我们在系统开发过程中,对数据排序是很常见的场景。一般来说,我们可以采用两种方式:

  • 一文掌握 Java8 的 Optional 的 6 种操作

    一文掌握 Java8 的 Optional 的 6 种操作

    你好,我是看山。

    Java8 中引入了一个特别有意思类:Optional,一个可以让我们更加轻松的避免 NPE(空指针异常,NullPointException)的工具。

    很久很久以前,为了避免 NPE,我们会写很多类似if (obj != null) {}的代码,有时候忘记写,就可能出现 NPE,造成线上故障。在 Java 技术栈中,如果谁的代码出现了 NPE,有极大的可能会被笑话,这个异常被很多人认为是低级错误。Optional的出现,可以让大家更加轻松的避免因为低级错误被嘲讽的概率。

  • JVM 参数优化(基础篇)

    JVM 参数优化(基础篇)

    该图片由g3gg0Pixabay上发布

    你好,我是看山。

    这几天压测预生产环境,发现 TPS 各种不稳。因为是重构的系统,据说原来的系统在高并发的时候一点问题没有,结果重构的系统被几十个并发压一下就各种不稳定。虽然测试的同事没有说啥,但自己感觉被啪啪的打脸。

    于是各种排查,最先想到的就是 JVM 参数,于是优化一番,希望能够出一个好的结果。尽管后来证明不稳定的原因是安装 LoadRunner 的压测服务器不稳定,不关我的系统的事,不过也是记录一下,一是做个备份,二是可以给别人做个参考。

  • JDK 工具一览

    JDK 工具一览

    该图片由Thang HaPixabay上发布

    你好,我是看山。

    Java 坑如此大,需要慢慢填。

    本文是列出 JDK 自带的一些工具,介于篇幅,简单列出工具列表及工具的作用。至少先做到知道有哪些工具,然后才能在实际中用到。

    本文参考了 官方介绍 和本机man命令的介绍。

  • Java 并发基础(二):主线程等待子线程结束

    Java 并发基础(二):主线程等待子线程结束

    你好,我是看山。

    在很多时候,我们期望实现这么一种功能:在主线程中启动一些子线程,等待所有子线程执行结束后,主线程再继续执行。比如:老板分配任务,众多工人开始工作,等所有工人完成工作后,老板进行检查。

    解决方法分析:

    1. 主线程通过 join 等待所有子线程完成后,继续执行;
    2. 主线程知道子线程的数量、未完成子线程数量,主线程等待所有子线程完成后,才继续执行。

  • 使用FreeMarker替换JSP的10个理由

    你还在使用 Java Server Pages(俗称JSP,Java服务器页面)吗?我曾经也是,但是几年前我抛弃了它们,并且再也没有用过JSP了。JSP 是个很好的概念,但是它却剥夺了 web 开发的乐趣。 对我而言,这些都是小事,比如无法在页面模板上使用单独的文件header.jsp 和 footer.jsp,不能调用表达式语言的方法,在运行时无法合并,重新排列页面的各个部分。所以我转而使用 FreeMarker 模板。FreeMarker 已经存在一段时间了,如果你最近没有关注过 FreeMarker 的话,那这有些建议给你,让你考虑下个 web 应用使用 FreeMarker。

  • Java 并发基础(三):再谈 CountDownLatch

    Java 并发基础(三):再谈 CountDownLatch

    你好,我是看山。

    java.util.concurrent.CountDownLatch 是 JDK 1.5 提供的一个同步辅助类:在一组正在其他线程中的操作执行完成之前,它允许一个或多个线程一直等待。

    初始化 CountDownLatch 时需要指定计数。通过调用 countDown 方法使当前计数到达零之前,await 方法会一直阻塞。之后,所有等待的线程会被释放,await 后面的操作也会立即执行。因为计数无法被重置,所以这种操作只会出现一次。如果需要重置计数,请考虑使用 java.util.concurrent.CyclicBarrier。

  • Java 并发基础(四):再谈 CyclicBarrier

    Java 并发基础(四):再谈 CyclicBarrier

    你好,我是看山。

    java.util.concurrent.CyclicBarrier 也是 JDK 1.5 提供的一个同步辅助类(为什么用也呢?参见 再谈 CountDownLatch),它允许一组线程互相等待,直到到达某个临界点(a common barrier point,翻译成公共障碍点、公共栅栏点都不够传神,直接用临界点吧)。在某个程序中,一组固定大小的线程必须互相等待时,CyclicBarrier 将起很大的作用。因为在等待线程被释放后,这个临界点可以重用,所以说是循环的。

  • 认识 Java 中的队列:Vector、ArrayList、CopyOnWriteArrayList、SynchronizedList

    认识 Java 中的队列:Vector、ArrayList、CopyOnWriteArrayList、SynchronizedList

    你好,我是看山。

    书接上文,上次聊了聊 在多线程中使用 ArrayList 会发生什么,这次我们说说平时常用的列表:Vector、ArrayList、CopyOnWriteArrayList、SynchronizedList。

  • Java 中 Vector 和 SynchronizedList 的区别

    Java 中 Vector 和 SynchronizedList 的区别

    你好,我是看山。

    本文还是折腾 Java 中的队列,上次比较了 Vector、ArrayList、CopyOnWriteArrayList、SynchronizedList,当时感觉挺明白,后来想想又有些不理解的地方,所以今天在重新翻出来研究一下,我承认我钻了牛角尖了。