开发工具分享
  • 首页
  • 计算科学
  • 文化旅游
  • 项目和网站
    • OSSEZ 计算技术
    • USRealEstate 社区
    • 地区文化
    • CWIKI.US
    • BUG.OSSEZ.COM
    • RSS.OSSEZ.COM
CWIKIUS.CN
一个有独立思考和温度的清新站
Computer Science

Java 虚拟机的概念是怎么来的

JVM 是 Java 的精髓部分之一。 Java 最开始是怎么来的?其实是从 C++ 上过来的,所以 Java 上面很多的面向对象特性都有 C++ 的影子。 C/C++ 最受诟病的是什么,就是指针,经常性的内存溢出。Java 说,算了,我们做个东西没有指针吧,这样程序就不会因为内存溢出而挂起退出了。得到的是经常性的空对象异常。 C/C++ 不仅仅有个编译的过程,还有一个过程叫做连接,这个也是经常出问题的地方,经常连接不上去。 不同计算机体系结构也不一样,大学应该有一门课程叫做《计算机体系结构》,主要涉及到 CPU,内存,存储,以及对字符和数字的处理上。     Java 就说,那么这样的话连接也出问题,编译好的代码也没法用,那我就用个虚拟机,然后让这个虚拟机在所有计算机体系结构上跑吧。 这个就是 Java 虚拟机的由来,JVM 是 Java 中非常重要的概念,帮你屏蔽掉了 Java 针对硬件环境中的各种痛点和不适。 https://www.ossez.com/t/java/14041

2022年08月03日 0Comments 552Browse 0Like Read more
Computer Science

JAVA程序员写的接口没有PHP程序员体验好

PHP 把压力大部分都丢给数据库了。 一个公司,一个查询,超过 10 个 join, 5 万左右实际数据级,512G 数据库内存,还经常锁表。 一个 PHP 文件,超过 2.5 万行代码,我都不知道他们怎么写的。反正在数据库上面调完 SQL 再拿回来用,连分页都没有。     这么大的 PHP 文件,连 IDEA 的代码分析都困难,IDE 都能被折腾死 Java 比较注意数据结构化定义,ORM 倾向在业务层处理数据,少用 Join。 PHP 上手确实容易,但是这代码实在是没有那么规范,再加上变量名命名的随意性,简直想死的心都有。 这 API 接口对 PHP 来说,毫无规矩可言,随便怎么跳转就怎么跳转,真的好想哭。   https://www.ossez.com/t/java-php/14040

2022年08月03日 0Comments 466Browse 0Like Read more
Computer Science

Hibernate 元数据模型(MetaModel)提示类没有找到错误

在进行一次编译的时候,提示下面的错误信息: java: java.lang.ClassNotFoundException: org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor     问题和解决 如果你对 Hibernate 的元数据还是不非常了解的话,请参考文章: JPA 的 Metamodel 中的内容。 有关元数据生成器中的内容,请参看官方的:JPA Static Metamodel Generator 这里有几种使用方法: 我们使用了第一种的 Maven 配置方法: <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <compilerArguments> <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor> </compilerArguments> </configuration> </plugin>     在我们的项目中和 lombok 的插件编译方法冲突了。     需要讲上面的配置方法通过 annotationProcessorPaths 来进行配置。 修改后的配置如下: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven-compiler-plugin.version}</version> <configuration> <release>${java.version}</release> <annotationProcessorPaths> <path> <groupId>org.hibernate</groupId> <artifactId>hibernate-jpamodelgen</artifactId> <version>5.4.33.Final</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </path> </annotationProcessorPaths> </configuration> </plugin> 然后再次编译和运行项目,上面的错误就解决了。     通常官方文档需要认真参考下。   https://www.ossez.com/t/hibernate-metamodel/14038

2022年08月03日 0Comments 487Browse 0Like Read more
Computer Science

Lombok 使用在 IDEA 中进行 JUnit 测试的时候提示 variable log 错误

提示的错误信息如下: D:\WorkDir\USRealEstate\Source-Code\Common\common\src\test\java\com\ossez\common\tests\ConfTest.java:28:9 java: cannot find symbol symbol: variable log location: class com.ossez.common.tests.ConfTest     原因和问题解决 这个问题可以通过修改 POM 文件来解决。 根据官方的说法,如果你使用了 JDK 9+ 以上版本的话,你同时需要在依赖和编译插件中加入 lombok 依赖。 如果你直接添加依赖,没有在插件中添加就会出现上面的错误。 解决办法就是,如果你使用的是 JDK 9+ 以上版本的话,需要添加 2 个位置。     然后再次运行就不会出现上面的提示了。 当然,你还需要在 IDEA 中启用插件。   https://www.ossez.com/t/lombok-idea-junit-variable-log/14037

2022年08月03日 0Comments 439Browse 0Like Read more
Computer Science

到底应不应该使用 lombok

对使用 lombok 还是有很多争议的,有些公司不建议使用,有些公司又大量使用。     我们的想法是:可以使用,但是不要滥用。 什么是 lombok Lombok是 一种Java™实用工具,可用来帮助开发人员消除Java的冗长代码,尤其是对于简单的Java对象(POJO) 。 它通过注释实现这一目的。 通过在开发环境中实现Lombok,开发人员可以节省构建诸如hashCode() 和 equals()这样的方法以及以往用来分类各种 accessor和 mutator的大量时间。 我们都知道使用 Java 定义对象的时候都会用到 Getter 和 Setter 方法。 虽然我们有工具帮我们快速生成这些方法,但是实际上还是有点麻烦。 lombok 就可以通过一行注释来实现所有的这些方法。 lombok 可以做的不仅仅是这个,还可以通过注释 @Slf4j 来帮你实现自动定义 log。 我们就不用写冗长的 private static final Logger logger = LoggerFactory.getLogger(ListingProcessor.class) 这句话了。 而且针对 log 的类不同,这句话也是不同的。 如何使用 如果使用 Maven 的话,直接添加下面的依赖到 pom 文件中就可以了。 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> IDEA 的插件是自动安装的,你直接启用就可以了。 IDEA 会提示你是不是在当前的项目中启用 lombok,你可以选择启用或者不启用。     随后就是在代码中使用注释就可以了。 如下面的代码,我们直接简化使用注解就可以了。     需要注意的是,使用 log 来标记日志。     这样看起来,代码就优雅很多,也能减少不少不需要的代码。 lombok 的原理和滥用 Java 程序的解析分为:运行时解析 和 编译时解析。 通常我们通过反射获取类、方法、注解和成员变量就是运行时解析。但是这种方式效率其实不高,要在程序运行起来才能解析。 这时候编译时解析就体现出它的价值了。 编译时解析又分为:注解处理器(Annotation Processing Tool)和 JSR 269 插入式注解处理器(Pluggable Annotation Processing API) 第一种处理器它最早是在 JDK 1.5 与注解(Annotation) 一起引入的,它是一个命令行工具,能够提供构建时基于源代码对程序结构的读取功能,能够通过运行注解处理器来生成新的中间文件,进而影响编译过程。 不过在JDK 1.8以后,第一种处理器被淘汰了,取而代之的是第二种处理器。 这样就导致了 lombok 对 JDK 的兼容性出现了一些问题。 当你更换 JDK 版本的时候,lombok 的版本也需要一并进行更换,否则你就会出现错误。 如果下面文章讨论的错误: Java 项目编译错误 Error:java: java.lang.ExceptionInInitializer 就是因为 JDK 不兼容的问题导致的整个项目无法编译。 如果上游系统中提供的fegin client 使用了 lombok,那么下游系统必须也使用 lombok,否则会报错,上下游系统构成了强依赖。 如果你需要对 getter 或者 setter 方法进行一些编码的话,lombok 也不是不能用,但是会有一点点的学习曲线。 综合上面的考虑, lombok 还是可以用的,但是不要尝试所有地方都用 lombok,避免滥用。 哪怕就是为了使用 @Slf4j 来考虑的话,也是值得的。   https://www.ossez.com/t/lombok/14036

2022年08月03日 0Comments 451Browse 0Like Read more
Computer Science

Nginx 部署的虚拟主机如何使用 Let's Encrypt 来进行加密 https

HTTPS 是现在网站的标配了,很多服务都是必须使用 https,如果你不使用的话,浏览器可能就不会对你非常友好了。 如果你不想使用商业的 CA 秘钥的话,你可以使用 Let’s Encrypt 来进行加密。 使用 Let’s Encrypt 唯一不好的地方就是每 3 个月要更新一次,当然你也可以使用自动的更新来处理就好了。 我们需要通过安装插件来实现: 获得 SSL 加密需要的 pem 秘钥。 设置 certbot 能自动更新秘钥。 需要前提条件 已经安装好了 Nginx并且配置好了虚拟主机 安装好 python3-certbot-nginx 插件 对 Nginx 虚拟主机的配置方法我们就不详细说了,你可以自己搜索下进行配置。 安装 python3-certbot-nginx 插件 安装的命令非常简单: 执行下面的命令就可以了:sudo dnf install python3-certbot-nginx 需要注意的是,我们这个命令是带有 nginx 插件的。 还有一个官方的是不带有插件的,不建议装那个,因为非常不好配。 获得 pem 秘钥 运行下面的命令 sudo certbot certonly --nginx,需要后面添加 nginx 参数才可以了。 通过下面的寂寞我们可以看到,这个工具将会检测到你的本地服务器上有几个虚拟主机。 然后你需要选择你需要的一个来进行安装。 在安装成功后,会生成我们需要的 pem 秘钥。 配置你的虚拟主机 找打你的虚拟主机文件,然后将生成的秘钥配置上去就可以了。 例如我们的虚拟主机配置:     我们首先在上面配置了 80 端口的重定向,然后将生成的 2 个秘钥文件的指定位置配置上去就行了。 然后重启 Nginx 服务器,然后检查你的网站的 HTTPS 情况。 检查网站 HTTPS 情况 可以使用一些第三方的网站来进行检查,也可以直接使用浏览器来检查。     主要看看网站有没有正常的重定向,和 SSL 证书的过期时间。 上面的证书看起来签发的是泛域名。 https://www.ossez.com/t/nginx-lets-encrypt-https/14034

2022年08月03日 0Comments 415Browse 0Like Read more
Computer Science

缩小字符串( Compact String)和 压缩字符串(Compressed String)

正如我们在上面文章提到的内容,在英文语境中上面 2 个方法还是有区别的,在中文环境下主要表达就是字符串压缩。   JDK 6 使用的压缩字符串方法,主要原因是我们修改了 String 的存储结构,char[] 在 Java 的很多地都会用到,并且 String 因为这个修改就只能接受使用 char[] 为参数的构造方法了。 在很多算法中,String 的操作又严重依赖 char[] 数组,如果我们进行这样修改的话,很多程序的代码都会需要跟着修改,这个显然是不划算的。 在后面我们使用的缩小字符串的处理方案来说也会有问题的,同样也会增加一些不少的问题,例如会导致一些方法修改为内部方法 intrinsified 同时一些 JIT compiler 编译的代码也需要进行改进。 因为存储方式的改变,也会有一些反人类的情况会出现: LATIN-1 的 indexOf(String) 方法调用的是内部方法,但是 indexOf(char) 不是小的。 在 UTF-16 环境下,这 2 个方法都可以使用相同的内部方法,这个问题只会对 LATIN-1 字符集的 String 字符串有影响,并且也会在后续的版本中修正。 整体来说使用缩小字符串( Compact String)的效率更高一些。 你可以将 Java 应用程序的 Heap 内存空间 dump 出来后进行分析,针对 String 的改进不会对你应用程序的提高产生非常显著的影响,如果你的程序有很多逻辑上面的问题,修改程序上面的逻辑问题比考虑如何使用 String 要实际得多。 但是对 JVM 来说这种提高还是有必要的。 性能的不同 让我们通过下面的一个简单的测试来看看启用缩小字符串( Compact String)配置和不启用这个配置对性能产生的异同。 long startTime = System.currentTimeMillis(); List strings = IntStream.rangeClosed(1, 10_000_000) .mapToObj(Integer::toString) .collect(toList()); long totalTime = System.currentTimeMillis() - startTime; System.out.println( "Generated " + strings.size() + " strings in " + totalTime + " ms."); startTime = System.currentTimeMillis(); String appended = (String) strings.stream() .limit(100_000) .reduce("", (l, r) -> l.toString() + r.toString()); totalTime = System.currentTimeMillis() - startTime; System.out.println("Created string of length " + appended.length() + " in " + totalTime + " ms."); 在这里,我们首先使用一个基本的方法来创建 1千万个 String 字符串,然后使用默认开启的配置来看看上面的代码的输出: Generated 10000000 strings in 854 ms. Created string of length 488895 in 5130 ms. 同样的,我们禁用 JVM 的这个参数 -XX:-CompactStrings 参数选项再来看看输出: Generated 10000000 strings in 936 ms. Created string of length 488895 in 9727 ms. 通过上面的代码,我们可以看到上面 2 个参数修改后对比的输出并不是非常的明显,但是也可以看到有明确的性能提升。   https://www.ossez.com/t/java-9-string/14024

2022年08月03日 0Comments 705Browse 0Like Read more
Computer Science

Java 9 缩小字符串( Compact String)

从 Java 9 开始,JDK 开始引入了一个叫做 缩小字符串( Compact String)。 在中文语境下,压缩和缩小都是削减的意思,很多时候是可以通用的,但是实际上还是有区别的。 JDK 9 的处理方式是不改变字符串存储使用的 char[] 数组,而是根据字符集来进行处理。 当 String 在创建的时候,如果我们知道这个字符集使用的 LATIN-1 来表示的话,我们就使用一个字节来存储。 如果是中文,或者我们知道不能用 1 个字节来存储的话,我们还是使用 2 个字节来存储,与原来的存储方式保持一致。 换句话说就是尝试用 1 个字节来存储我们可以存储的自己,而不再浪费存储空间。 现在我们需要知道的问题就是,针对 String 的操作是不是会因为这种存储格式的改变而有影响呢,因为我们在数组中存储了 2 个字符集, LATIN-1 和 UTF-16 字符集之间的混合操作是不是会受到改变? 本文章的后续部分就对这种情况进行一些说明和演示,来让我们大致了解这个改进对我们的影响。 针对日常使用 Java 的开发人员来说,这个改变是感觉不到的,至于你使用的比较等操作还是会按照正常的处理方式来处理,对你来说这个是透明的。 Java 9 中的字符串实现 直到现在,我们应该非常明确的了解到 Java 中存储 String 是使用 char[] 来处理的,这个是没有改变的。 首先,我们先定义一个 char[] 数组 private final char[] value; 然后我们再定义一个 byte[] 数组: private final byte[] value; 定义一个 coder 变量: private final byte coder; 这个 Code 的变量可以为下面 2 个值: static final byte LATIN1 = 0; static final byte UTF16 = 1; 大部分情况下,Stgring 将会对 Coder 进行判断,然后根据值使用不同的实现: public int indexOf(int ch, int fromIndex) { return isLatin1() ? StringLatin1.indexOf(value, ch, fromIndex) : StringUTF16.indexOf(value, ch, fromIndex); } private boolean isLatin1() { return COMPACT_STRINGS && coder == LATIN1; } CompactString 在 JVM 中是默认启用的,如果你不想启用,你可以使用下面的参数告诉 JVM 不使用 String 压缩功能: +XX:-CompactStrings coder 是如何工作的 在 Java 9 的 String 类实现中,有关字符串的长度是下面的方法来进行计算的: public int length() { return value.length >> coder; } 如果 String 只含有 LATIN-1 字符的话, coder 的值为 0,那么获得 String 字符串长度的方法就直接返回字节数组的的长度,因为你这个数组的长度就是一个自己一个元素。 在另外的一种情况,如果 Stirng 使用了 UTF-16 字符集的话,coder 的值为 1 Java 将会使用数组中存储的元素的字节实际长度来返回,这是因为数组中存储的字符可能是 2 字节的。 需要注意的是,这个修改是针对 String 的内部修改,针对绝大部分开发者来说,所有有关 String 的处理方法都是透明的。 如果你想了解更多 String 有关的内部实现,这个是你值得深入的地方。 https://www.ossez.com/t/java-9-string/14024

2022年08月03日 0Comments 455Browse 0Like Read more
Computer Science

Java 6 压缩字符串(Compressed String)

JDK 考虑开始对字符串进行优化是从 Java 6 开始的。 从 JDK 6 update 21 版本更新开始,我们可以为 JVM 添加下面的参数: -XX:+UseCompressedStrings 上面参数的主要目的就是将 String 存储使用的 char[] 数组修改为 byte[] 数组。 简单来说就是存储粒度更小,能够提供更多的空间利用率。 但是,这个参数在 JDK 7 后被移除了,主要原因可能是因为修改了存储结构导致的一些不可以预料的情况。 https://www.ossez.com/t/java-9-string/14024

2022年08月03日 0Comments 639Browse 0Like Read more
Computer Science

Java 代码中数字中间带下划线是几个意思

见过下面的代码吗? List strings = IntStream.rangeClosed(1, 10_000_000).mapToObj(Integer::toString).collect(toList()); 在数字中间还带有一个下划线,这是几个意思? 官方解答 官方的说法来了,在页面: Underscores in Numeric Literals 中进行了说明。 简单来说就是从 Java SE 7 的版本开始,程序中的数字可以使用下划线来进行分割(_)以便于为程序提供更好的可读性。 你可以对一个比较长的数字,使用下划线来进行分隔,以便于你不会数错 0。 我们的理解就是 JDK 在编译的时候,将会对数字中间的下划线进行处理,应该就是简单的替换掉下划线了。 例如我们常用的使用逗号作为千分符,这里直接使用下划线代替就可以了。 在使用的时候也是有一些限制的,不是随便都行的。 使用的限制是: 不能在数字的开头和结尾使用,说人话就是不能以下划线开头和结尾。 不能在小数点的前后使用。 不能在使用 F 和 L 为后缀之前使用。 官方文档中也列出一些常用的用例。     如果你使用 IDE 的话,也不用担心,如果语法是错误的,IDE 会给出提示的。     和上面的图一样,IDE 就直接告诉你这个地方是错误的,按照要求修改下就好了。   https://www.ossez.com/t/java/14032

2022年08月03日 0Comments 498Browse 0Like Read more
1…34567…10
Archives
  • June 2026
  • May 2026
  • April 2026
  • March 2026
  • February 2026
  • January 2026
  • December 2025
  • November 2025
  • October 2025
  • September 2025
  • August 2025
  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
Categories
  • Computer Science (2,367)
    • Confluence (663)
    • Gradle (12)
  • U.S. (511)
  • 文化旅游 (146)

COPYRIGHT © 2020 CWIKIUS. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

湘ICP备2020018253号-1