相信大家最近都被 Apache
的 Log4j2
的漏洞相关的文章刷屏了,不得不说这次的这个漏洞影响范围之广,很多互联网大厂和开源软件都被影响到了,作为一个特别通用的日志框架,日常使用的场景非常多,而且很多开源软件都在使用,所以此次影响到一大批公司,堪称核弹级漏洞!
Java 中一个你不常用,但是关键时刻可以帮我们提升性能的一个知识点
最近阿粉在实现一个功能的时候,遇到了一个性能问题,一个方法在某些场景下运行时长达到了 4s 多,虽然说业务功能是实现了,但是不管是从业务的角度还是作为一个有追求的程序员,都是不能接受的,所以优化这个方法势在必行。在优化的过程中就用到了本文要说明的一个知识点,看阿粉慢慢道来。
Java 中 再一个你可能不经常用,但使用的时候不一定会注意的一个知识点
我们都知道在遇到一些单线程处理很慢的场景,往往我们会采用多线程的方式进行处理,从而缩短处理时间提升性能。
Java 中 又一个你天天使用,但是不一定知道的知识点
大家都知道当我们在进行条件判断的时候除了可以使用 if-else
之外,还可以是用 switch
,而且在 JDK 7
之后在 switch
中还增加了 String
类型的支持,如下代码所示。
Java 中 String 字符串可以有多长?65535?
毫无疑问 Strin
g 是作为一个 Java
开发工程师天天都需要打交道的类,那么如果问你 String
字符串的最大长度是多少你知道吗?有的小伙伴可能想都没想,就直接回答 65535
,那么问题来了,真的吗?今天阿粉就带你研究一下。
让 Fackbook 孤注一掷的元宇宙是个什么玩意?
相信大家最近都看到 Facebook
改名称和股票代码的新闻了,全面进军元宇宙领域。那到底什么是元宇宙,扎克伯格这样孤注一掷的将一家社交公司往一个新的领域去转型意味着什么呢?对于我们普通人要怎么参与到元宇宙领域呢?这篇文章阿粉用自己的理解阐述一下,水平有限,欢迎大家在评论区发表自己的看法。
什么是元宇宙
我们先看一下什么是元宇宙,Metaverse
此一词汇是由英文前缀词 meta
与宇宙(universe
)的尾部verse
组成,最早见于尼尔·斯蒂芬森在 1992 年的科幻小说《雪崩》。下面这段是维基百科的介绍
元宇宙(英语:Metaverse),或称为形上宇宙、元界、超感空间、虚空间,通常被用来描述未来互联网虚拟环境的概念,于共享、持久的虚拟现实组成一个可感知的虚拟宇宙,此合成环境包含对象、常驻用户与其交互关系,并存在于虚拟定义的时间中。旨在提供连接用户长时间登录和交互。广义上的元宇宙概念不仅指虚拟合成世界,还指整个互联网,也包括增强现实的范围。
Java 中一个天天都在被人使用,你一定听过,但是并不知道为什么的知识点
泛型作为 Java
中一个天天都在被人使用的特性,你真的知道它的原理吗?
首先我们说下什么是泛型。
泛型,就是泛化类型也就是泛化参数类型。平时我们在编写代码的时候,方法的参数在定义的时候都是指定特定的类型,比如 Integer
,Double
或者其他自己别笑的类。那么泛化类型就是,我们在编写一个方法的时候对于参数的类型不具体指定,而是定义一个通用类型,在使用的时候根据类型自动转化。
上面的描述可能比较抽象,我们再看一下,如果没有泛型的话,会出现什么情况以及为什么说这个泛型大家天天都在使用。
新人一优化,系统就会炸!
阿粉最近在刷知乎的时候发现了一个很有意思的问题,那就是:为什么程序员会有代码能跑就不要动的观点?
说实话这句话在阿粉的工作中经常会听到,不仅仅是对于一些长期没人维护的代码,对于日常维护的系统哪怕是之前实现的代码,大家更是敬而远之,能不动一行代码绝不加个空格,更有甚者哪怕是复制一下之前的代码改改,也不考虑复用之前的代码,毕竟复制粘贴大法实在好用。
那么为什么程序员会有这种想法呢?
不得不说知乎的答主都说人才,同意一句:新人一优化,系统就会炸!
容易改出问题
首先当我们对系统不熟悉的时候,最容易改出问题,你是不是也遇到过明明就改了一行人畜无害的代码,结果服务就挂了,然而还找不到任何原因,最后只能回滚!这种情况往往是因为对系统的设计不了解的人,不知道哪里有坑,看着只是改了一行很简单的代码,结果导致了服务宕机。
经验告诉我们再修改任何代码的时候我们都需要搞清楚这段代码的真实意图和逻辑,不管是谁如果面对的是一段自己不熟悉的代码的时候千万不能随便动,因为很有可能会改出问题,动手之前一定要搞清楚代码的具体逻辑。
特别是新人!特别是新人!!特别是新人!!!
这里的新人指的是刚刚接触项目的人,跟工作年限关系不是特别大,新人虽然说因为没有经验偶尔会改出问题,但是并不代表有经验的人就不会改出问题,特别是有一些有多年工作经验的人,在面对新的环境和编程风格的时候,往往还是习惯自己的那一套,上来就大刀阔斧的改东西,结果导致各种问题发生。
这其实也是为什么有些公司愿意招聘一些毕业生,因为毕业生就好比一张白纸,可以慢慢培养,当然也可以理解成容易洗脑,哈哈哈。
成本问题
动不动代码取也决于我们对这段代码的投入是一次性的还是长久的,如果是一次性的那能不动就不动,因为不值得为了一次性的功能花费时间和精力去改动原有的东西,更不要随便就重构(虽然我知道很多程序员动不动就喜欢说重构)。
但是在工作中很多时候我们都会接手别人的项目,接手的项目肯定是后续我们需要维护和迭代的,这种项目未来会有很多需求和迭代,我们要动,而且要精雕细琢好好的动,弄清楚系统中的每个细节,在适当的时候该重写就重写,该重构就重构,因为我们的目的是让服务长久的运行下去,如果长期不动旧的代码,只往里面添加,那么系统只会变动臃肿,最后想维护都维护不起来。这个时候我们就需要通过一些设计思想和设计模式来改造我们的系统,使其变得更加活力。所以就要动了,也该动了。
真的改不动
其实阿粉觉得还有一种可能,那就是真的改不动啊~网上经常有段子,说一个程序员看到一段代码,不由自主的骂了一句:这代码写的就跟狗屎一样,然后看一下提交记录,打脸了,原来是自己几个星球前写的。说真的,这种情况经常会发生,很多代码只有在面临当时的业务需求的时候才知道为什么要这样写,时间一长根本记不起来当时为啥这么写,更不用说再重构了,要想重构也需要花费很多的时间去重新理解当时的业务逻辑,但是在业务推动的社会,老板哪有那个时间给你重构!
知乎网友的一个回答也很有意思,截图给大家看看。
是不是有一种蝴蝶效应的感觉,软件开发有的时候真的就跟蝴蝶效应一个样,不然也不会经常出现往往自己就改了很简单的一行代码,结果就崩了。
总结
总结一下该动旧代码的时候就要动。
技术是为了业务服务的,当我们的技术或者系统在不满足业务发展的时候就需要动,即使项目能正常运行,我们也需要进行适当的重构,作为一个合格的工程师,在设计系统的时候,我们要把眼光放到未来一年,提前做好设计和布局,这样就不会被业务追着跑,导致系统臃肿从而最后改不动!
所以小伙伴们你们在平时工作中有遇到过这种情况吗?欢迎在评论区留言说一说。
SELECT * FROM GIRLS WHERE AGE BETWEEN 20 AND 24 ...
阿粉最近看到一张图,如下所示,原本只是一个搞笑的图,但是在阿粉看来这分明是个渣男啊!一句普通的 SQL 语句SELECT * FROM GIRLS WHERE AGE BETWEEN 20 AND 24 AND BOYFRIEND IS NULL
,也有很多内涵!
又一个关于 996 的开源项目在程序员之间火了
不知道大家有没有注意到最近非常火的一个关于 996 的开源项目,在知乎上一度被抄上热榜第一,可见大家对于互联网公司的 996 加班情况是非常关注的。
说下背景,这两天突然有一个共享文档在程序员之间到处传播,传播到被 10 万+ 的人浏览过,而且同时有数百人参与编辑,项目名称叫 workerlivesmatter
在 Github
上面可以搜到,目前截止阿粉写文的时候,star
数为 7.9k,地址如下: https://github.com/WorkerLivesMatter/WorkingTime。
项目的内容就是一份共享文档,重点是文档里面记录的都是各个公司的员工自发的填入的公司加班时间!要知道在这么多互联网公司和部门的情况下能收集到这么多的一线信息是很困难的,最重要的是这些信息都是各个公司一线人员自发填写的。对于找工作的朋友或者校招的同学是很具有参考性的。
还记得两年前的 996ICU 项目吗?那一次也是一场很刺激的斗争,是程序员与 996 的斗争,在业界引起了很大的反响,同样的这一次也是。阿粉之前写过一篇文章,说的是国家已经说明 996 是违法的,感兴趣的可以去看看这篇文章自从被国家认定为新时代的农民工过后,国家又不让我 996 了。
分享一下这个项目的一些内容截图给大家看看,我们可以看到文档记录的信息详细到几点吃午饭都有,虽然不排除有些内容可能不够真实,但是还是具有一定的代表性。
根据知乎上的首答作者,也是这个项目的发起人之一的自我描述,之所以创建这个项目是因为如下内容:
“我们四个人 1996~2001 年不等,都是曾在互联网大厂技术岗实习且正在秋招的应届生,学历从本科到硕士不等,并且都拿到了多个大厂的意向书,处于选 offer 的状态。由于一些原因,国内企业加班盛行且毫无监管,互联网大厂尤甚。大厂美名其曰弹性工作制其实不过是 1095 和 11105 给你弹,一天照样要工作十个小时以上。这就导致了互联网企业工作时间的不透明,作为校招生,工作时间是选择 offer 非常重要的一个因素。所以我们创建了这个表来分享信息。所谓人人为我,我为人人。”
不仅项目火的快,效率高,就连 logo 都制作了。
其实互联网行业 996 的话题从来都没有断过,从之前的 996 icu 项目,到前段时间国家出的政策,可以看出,这个问题以后的关注度只会越来越高。目前有很多公司都开始实施一周固定的某天不让加班,而且目前随着限电的政策,很多公司晚上也开始进行断电了,所以看上去一切是在向着好的方向发展,不过只能说道阻且长。
我将这份文档的备份、在线链接、开源项目等打包放在了后台,有需要的小伙伴,赶紧在下方公众号后台回复“表格”自动获取。
Equal 与 “==” 引发的血案
众所周知阿里巴巴开发手册里面有一条强制的规则,说的是在包装类对象之间的值比较的时候需要使用 equals
方法,在 -128
和 127
之间的数值比较可以使用 ==
,如下图所示。具体的原因相信大家都知道,虽然规则中提到 -128
和 127
之间的数值比较可以使用 ==
,但是阿粉强烈建议你还是不要这样,包装类统一使用 equals
,特别是如果有些数值是通过 API
或者 RPC
接口过来的,一定要注意。
一文带你详解 BigDecimal Java 小能手必备
作为 Java
程序员在日常的工作中,很多时候我们都会遇到一些需要进行数据计算的场景,通常对于不需要计算精度的场景我们都可以使用 Integer
,Float
或者 Double
来进行计算,虽然会丢失精度但是偶尔也可以用,如果我们需要精确计算结果的时候,就会用到 java.math
包中提供的 BigDecimal
类来实现对应的功能了。
2021 StackOverflow 开发者年度调查报告
StackOverflow
发布了 2021 年度开发者调查报告,整个调查问卷参与人数达到八万多,来自全球 180 多个地域。问卷内容包含基本信息,教育、工作经历,用到的技术相关,社区相关,人口相关,最终问题六个部分,每个部分由多个随机问题组成。涉及到的问题有受访者的所在地域,工作年限,薪资水平,性别,性取向,以及用到的语言和工具等。
金九银十到来,盘点今年截止八月的 80 篇原创文章列表,建议收藏慢慢看!
随着开学季的到来,金九银十也来了,马上又到了新一波的跳槽季,本篇文章阿粉帮大家梳理了一下 2021 年以来 Java 极客技术原创的 80 篇优质文章,包含 Java / JVM、组件如 MySQL,Redis 队列、以及面试技巧和面试题,还有设计模式、软件设计、常用工具和技术成长相关的优质文章,内容较多,一下子肯定看不完,先收藏起来慢慢看。如果觉得有收获,欢迎分享,点赞,在看,评论四连!话不多说,请慢慢享用!
自从被国家认定为新时代的农民工过后,国家又不让我 996 了
以前程序员这一行总是喜欢把工作说成在搬砖,把自己称为码农,以此来自我调侃,但是现在程序员说搬砖是真正的在搬砖了,因为国家已经承认了我们新时代农民工的身份!被国家承认,我骄傲了吗?
Java 程序员可以学习的技术方向,精通任何一个都可以成为专家
Hello 大家好,相信大家跟阿粉一样,在成为卓越的 Java
程序员的路上从未停止过学习,作为一个 Java
程序员还有很多我们需要学习的东西,特别是在这样一个技术快速发展的时期可能昨天还在流行的技术,转眼就已经落后了。那么在 2021 年已经接近尾声的时候有哪些技术我们可以继续不断的学习呢?
GitHub 验证升级,不再支持密码验证,手把手教你创建 PAT
Hello 大家好, 我是阿粉,最近在写文章提交到 GitHub
的时候突发发现提交不上去,仔细一看原来是 GitHub
不支持密码验证了,熟悉 GitHub
的朋友都知道 GitHub
的仓库除了可以用 SSH
方式拉取之外还可以使用 HTTPS
的方式拉取,并且通过账号和密码进行提交。阿粉之前的项目就是使用 HTTPS
的方式来拉取,现在不让使用密码来进行提交了,突然就用不了了。
BTrace 告诉你如何在不重启 JVM 的情况下在线调试
Hello 大家好, 我是阿粉,不知道你有没有遇到过这种场景,线上服务跑了一段时间过后偶尔会出现问题,光靠代码和数据分析找不到原因,而且这种情况也不是很常见所以对应的代码也没有加日志输出,如果说重新加上日志进行发布的话,就会破坏现场只能再等一段时间了,或者有的时候想看下接口的参数,从而判断接口参数有没有问题。
这个时候就在想有没有一个好的方法,可以不用重新修改源代码也不用发布升级就可以增加一些日志看到运行状态和入口参数呢?答案当然是肯定的,下面我们就来看一下神器 BTrace
!
JDK8 的判空就是这么爽!
阿粉相信大家肯定所有的开发者都对Java8里面的所有的东西都感兴趣,虽然目前的 JDK 已经更新到 JDK17 了,但是阿粉相信,现在很多公司使用的还都是 JDK8 甚至是 JDK7,但是,就算是有些公司已经升级到 JDK8 但是对于 JDK8 里面的一些东西的使用,却没有使用的淋漓尽致。阿粉今天就给大家放出几个 JDK8 里面比较好用的。
JDK8
大家都是知道 JDK8 就开始使用 Lambda 表达式,但是很多不管是在教程上还是在其他的书籍上,都没有说在实际开发的时候去使用上这个 Lambda 表达式,而且包括 JDK8 里面的一些新的类,也都没有引入,所以阿粉在这里想要给大家安利一波使用方面的知识。
JDK8 – Optional类
这个类对于大家来说,是一个非常重要的类,不知道大家有没有被 java.lang.NullPointerException 疯狂的折磨过,不管是新人开发还是老开发,遇到这个问题的时候,都是头大的很,因为我们要在代码里面去疯狂的判断是否是null,如果不是 null 需要怎么处理,如果是 null 需要怎么处理,反正就是你要是想解决 java.lang.NullPointerException 这个问题,就免不了去加一些判断条件,而 Optional 这个类,则是帮你优雅的处理 null 的问题。
我们先看一组 Java7 中的一些判断空的实现:
1 |
|
阿粉相信大家一定都写过这个样子的代码,因为我们不知道SQL查询出来的数据中是否包含了我们的 Users 对象,如果要是 Users 对象,那么就会无情的出现 java.lang.NullPointerException 这个空指针异常,这时候就很尴尬了,老开发一脸懵逼,我竟然还有的地方没有验证?
但是验证了之后,你就会发现代码量是非常的大,而且有点不太美观,我们再来对比一下 JDK8 中,给我们提供的方法来进行验证的方式。
1 |
|
大家看这种链式编程,ofNullable() 方法给我们提供了判断 user 是不是空,并且去校验 userName,如果存在,然后执行下面的逻辑,相比较 JDK7 的内容,相信大家看起来的话肯定是没有 JDK7 中的表现的那么的明显,但是大家看代码是不是发现已经被处理的妥妥的了。而且非常的优雅。
相信大家肯定都看过一些教程,上面会写到:
1 |
|
但是相对于代码的可读性来说,我们肯定还是希望使用 JDK7 上面的判断来进行判断,但是这种 JDK8 的链式编程,在一定程度上减少了代码量,并且开发效率也会相对应的提升。
如果大家不信,我们可以来运行一下我们的代码,然后看一下效果。
1 |
|
大家看,是不是就出现了我们想要的结果,一个判断 null 的操作,瞬间变得高大上了,而且代码的逼格瞬间上升一个档次。
对于 Optional 类,在 Java8 实战中给出了很多的方法,阿粉也是给大家摘取了一下,做了个总结,
-
ofNullable 方法 :将指定值用Optional封装之后返回,如果该值为null,则返回一个空的Optional对象
-
empty 方法 :返回一个空的Optional实例
-
filter 方法 : 如果值存在并且满足提供的谓词,就返回包含该值的Optional对象;否则返回一个空的 Optional对象
-
flatMap 方法 : 如果值存在,就对该值执行提供的mapping函数调用,返回一个Optional类型的值,否则就返 回一个空的Optional对象
-
get 方法 :如果该值存在,将该值用Optional封装返回,否则抛出一个NoSuchElementException异常
-
ifPresent 方法 : 如果值存在,就执行使用该值的方法调用,否则什么也不做
-
isPresent 方法 : 如果值存在就返回true,否则返回false
-
map 方法 :如果值存在,就对该值执行提供的mapping函数调用
-
of 方法 : 将指定值用Optional封装之后返回,如果该值为null,则抛出一个NullPointerException异常
-
orElse 方法: 如果有值则将其返回,否则返回一个默认值
-
orElseGet 方法 : 如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值
-
orElseThrow 方法 : 如果有值则将其返回,否则抛出一个由指定的Supplier接口生成的异常
大家看这些方法是不是都有很多相似的,比如 map,flatMap,还有orElse,orElseGet,orElseThrow 方法
map 和 flatMap 比较:
这两个都是做 转换值 的操作,区别就是入参的类型不是一样的,map的入参是 Function<? super T, ? extends U> mapper
而 flatMap 入参则是 Function<? super T, Optional<U> > mapper
。
入参的不同也就导致了他们获取返回值也是不同的,map中获取的返回值自动被Optional包装,flatMap中返回值保持不变,但必须是Optional类型。
这么一看总是感觉不太对的样子,我们去源码里面看看是什么样子的。
1 |
|
map 方法参数中的函数 mapper 输出的是值,然后 map 方法会使用 Optional.ofNullable 将其包装为 Optional;而 flatMap 要求参数中的函数 mapper 输出的就是 Optional。
一个是比较聪明的,另外一个就相对来说不是那么聪明了,人家会自己包装呀,是不是?
同样的比较还有 orElse,orElseGet,orElseThrow 但是这个阿粉就不再给大家絮叨了,因为上面的方法解释上都很明显的能看到了。
Lambda 表达式
Lambda 表达式实际上就是相当于是一个匿名内部类,他就是让我们开发的人把函数当成参数传递给某个方法,然后把代码当做数据去处理。
阿粉相信大家肯定都了解这块,就比如说下面的代码对比:
1 |
|
同样的一个循环,我们肯定想用第二种写法不是么?
Java8 实际上在从发布开始,很多公司都在用,但是也有很多人依旧选择是 Java7,因为不想改变自己的学习风格,阿粉相信大家如果是一个决心在开发领域一直做下去的人,那么肯定会保持一个不断学习的心,所以,你是这样的人么?
Java8 的 G1 垃圾回收器相对于之前的 CMS 有什么特别的呢?
CMS
CMS
垃圾回收器,全称 Concurrent Mark Sweep
并发标记-清除,从名字上面我们也可以看出这个垃圾回收器是基于标记清除算法实现的。首先”并发”表示 GC
线程可以和用户线程并发执行,同时既然是标记-清除算法,说明这个垃圾回收器会产生很多碎片,这是标记-清除算法的缺点。同时 CMS
是作用于老年代的,老年代的垃圾回收频率相对年轻代会低一点。