自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(114)
  • 资源 (1)
  • 收藏
  • 关注

原创 这篇3万字的Java后端面试总结,面试官看了瑟瑟发抖(汇总)

「这篇总结我已经导出成pdf版的了,后台回复"总结"即可获取pdf版本哦~」HashMap源码“问:HashMap底层原理,为什么线程不安全。hashmap:数组+链表+红黑树初始长度=16扩容因子=0.75索引确定:index=hashCode(key)%lengthhashCode(key)高8位与低8位异或&(length-1)关于线程不安全HashMap会进行resize操作,在resize操作的时候会造成线程不安...

2020-08-09 22:19:20 887

原创 高并下如何做变量的自增与自减

将单一value的更新压力分担到多个value中去,降低单个value的 “热度”,分段更新。但是用到了锁,这个东西可以说偏重量级的了,会引起线程上下文的切换和调用,线程之间的切换也会有性能成本的。高效的原因是高并发,高并发意味着CAS的失败几率更高, 重试次数更多,越多线程重试,CAS失败几率又越高,变成恶性循环,测试的性能结果如上。高并发量的情况下,由于真正更新成功的线程占少数,容易导致循环次数过多,浪费时间,并且浪费线程资源。,性能好,线程安全,不会出现重复编号的情况。

2022-08-20 11:00:25 1584

原创 还在为日期计算烦恼?Java8帮你轻松搞定

我们平时开发日期一般都是使用Date类。在使用Date计算时,一般将会将Date转换成时间戳,即转换成ms后进行计算,这样做很麻烦。当然我们也可以使用第三方日期类。其实Java8自带的日期类就相当的强大了,基本能满足各种计算。今天我们就来聊聊Java8里面的日期类,LocateDate。

2022-08-20 10:54:32 934

原创 如何优雅的加密配置文件中的敏感信息

我们配置文件数据库信息就可以用加密的形式来配置。这里使用了ENC(*)用于识别是否需要加密。同时还要在文件中中配置密钥:当然更加安全的方法是将密匙加载在环境变量中:那么加密的数据是怎么获取的呢,我们需要将真实的地址和密码行进加密,加密代码如下:运行上述代码即可获取加密后的数据库信息。此框架的逻辑是,在加载配置文件时,做拦截操作,当发现有ENC包裹的字符串,会对其进行解密操作。

2022-08-20 10:51:12 1358

原创 我使用延迟队列实现商品的竞拍成交功能

我们平时开发可能要求实现这样的需求:用户可以在有效的时间内进行商品竞拍,当有效时间过了之后,取竞拍价最高的用户成交。我们一般可以使用定时任务每5s定时扫描数据库,获取有效时间大于当前时间的商品列表,然后取每个商品中竞价最高的用户存入商品成交表中。启动系统后我们发现结束时间小于当前时间的商品已经被消费,因为没有人竞拍,而竞拍时间到了,这里显示为流拍UNSETTLE。启动一个常驻线程,扫描延迟队列,获取已到竞拍时间结束的商品,并获取对应商品的竞拍信息,存入用户商品成交表中。为结束时间,即消费的时间。

2022-08-20 10:46:28 654

原创 我用shell脚本实现项目容器化自动部署

本文主要用shell“代码更新代码编译镜像制作容器启动镜像推送推送通知”有兴趣的童鞋千万不要错过哦~当然我们也可以在IDEA里面做相应的配置,实现镜像构建。

2022-08-20 10:42:50 1496

原创 我用自定义注解优雅的实现了业务的复杂校验

当我们的业务逻辑校验很复杂时,我们可以使用上面的校验注解将校验逻辑与业务逻辑分开,这样有利于业务与非业务解耦,也满足设计原则的单一职责原则。除了方便阅读,还有的好处就是,当我们不需要校验时,我们可以将业务方法上的校验注解注释掉,这样我们就不必在业务代码中去修改了,从而减少了因修改业务代码导致bug的风险。上面的代码相信大家都写过,我们不需要在方法中去写参数的校验,我们在字段上使用注解,就是实现了参数的必填校验,范围校验。类就是真正写校验功能的类,会把业务参数传到这个校验类中。

2022-08-20 10:39:57 644

原创 为什么if-else会影响我的代码的复杂度

我之前写了一篇文章《我用规则引擎消除if语句,提高了代码的可扩展性》,这篇文章我想阐述的观点是复杂的if语句可能会影响代码的阅读和代码的扩展性,会将非业务的条件逻辑与业务逻辑混合在一起。所以,软件系统的扩展性是非常重要的。我的观点并不是说,我们在编码时不能使用if-else,而是说我们不应该简陋地用if-else去实现业务的分支流程,因为这样随意的代码堆砌很容易堆出一座座"屎山"。有的代码 if-else 不仅个数多,而且 if-else 之间嵌套的很深,也很复杂,导致代码可读性很差,自然也就难以维护。

2022-08-20 10:37:57 1427

原创 我用规则引擎实现了消除if语句

规则引擎就是提供一种可选的计算模型。与通常的命令式模型(由带有条件和循环的命令依次组成)不同,规则引擎基于生产规则系统。

2022-08-20 10:34:38 279

原创 BigDecimal计算的这些坑,让我的程序产生难以想象的Bug

通常我们在金融、科学等场景,会使用BigDecimal。然而如果我们不注意BigDecimal的精度问题,计算结果偏差可能会很大,最终会产生难以想象的Bug。1意想不到的加减乘除@Testpublicvoidtest3(){BigDecimalparam1=newBigDecimal(0.1);BigDecimalparam2=newBigDecimal(0.2);//加法BigDecimaladd=param1.add(par...

2022-01-20 17:12:37 1500 1

原创 使用EasyExcel导出,这个轮子真方便

EasyExcel是一款优秀的Excel导出组件,基于注解的形式导出。除了导出,还支持导入。今天我们主要聊聊它的导出。git项目地址:https://github.com/alibaba/easyexcel它的优秀之处在于很省内存,导出导入速度也很快。1实现代码首先需要引入Maven<!--阿里的easyexcel--><dependency><groupId>com.alibaba</groupId>&lt...

2021-04-26 16:30:52 558

原创 我用注解优雅的实现了数据的脱敏

1使用场景你平时肯定做过这样的需求。要求展示用户的手机号,但是不能完全展示,需要在中间给手机号打码,如下图:我们将关键数据做了适当隐藏,这样就叫数据脱敏。2数据脱敏数据脱敏又称数据去隐私化或数据变形,是在给定的规则、策略下对敏感数据进行变换、修改的技术机制,能够在很大程度上解决敏感数据在非可信环境中使用的问题。根据数据保护规范和脱敏策略.对业务数据中的敏感信息实施自动变形.实现对敏感信息的隐藏。我们来看看具体需求,现在要求对以下数据的电话号码和身份证号码适当隐藏处理:要求脱敏

2021-04-26 16:07:50 1013

原创 被Arrays.asList坑了后,我决定分析它的源码

平时我们使用Arrays.asList()快速组装成List集合。比如我们将字符串或者数组转换成集合:String[]arrayStr={"1","2","3"};List<String>list=Arrays.asList(arrayStr);System.out.println(list);结果list的数据为我们点击asList进去看看源码怎么写的@SafeVarargs@SuppressWarnings("varargs")public...

2021-04-12 14:23:47 295

原创 使用DFA自动机算法屏蔽敏感词以及进阶算法AC自动机的思考

需求背景大家有没有做过屏蔽敏感词的需求呢,这个需求一般来说很常见了。比如,系统中有一段话:我爱吃肯德基要求【肯德基】三个词给屏蔽掉,屏蔽后的语句显示为:我爱吃***常规的做法可能是查询敏感词库中的敏感词,循环每一个敏感词,然后去输入的文本中从头到尾搜索一遍,看是否存在此敏感词。但是如果敏感词很多,对于匹配也是很耗性能的。这里介绍使用DFA算法匹配敏感词,并进行处理。性能要优于常规处理方法。什么是DFA算法“在计算理论中,确定有限状态自动机或确定有限自动机(英语:

2021-04-12 14:21:07 1693 1

原创 我的shell脚本实战-编写一个系统发布脚本

平常我们会使用Jenkins发布系统,Jenkins可以从代码更新,编译到发布这样的一条龙服务。操作成本很低,作为程序员,肯定不满足于简单的界面操作。于是我决定使用shell写一个自动发布的脚本,既可以更熟悉发布流程,也可以学习shell语法。发布流程思考结构如上图,我们将编写的shell脚本放到主机A,执行脚本,会从git服务器拉取代码,为了在拉取代码时不需要输入密码,我们需要在gitlab上面添加密钥:image-20210325112328103这个密钥是在主机A中

2021-03-30 14:57:55 577

原创 如何优雅的统计List集合中元素重复出现次数

背景统计List集合中元素出现的次数,相信大家都做过。举个例子,我们要统计集合中名字重复的次数。List<String>nameLists=Arrays.asList("Lvshen","Lvshen","Zhouzhou","Huamulan","Huamulan","Huamulan");方式一一般我们会这么做:Map<String,Integer>nameMap=Maps.newHashMap();nameLists.for...

2021-03-30 14:54:43 11423

原创 聊聊什么是缓存雪崩和缓存穿透

缓存雪崩假如一个系统,它在高峰期有每秒7000个请求,这时我们使用缓存抗住了这么高的请求。但如果在某个时间点缓存大量失效,或者缓存服务器挂掉了,那么这些请求就会直接作用在普通数据库中(如MySQL)。这么高的请求量,MySQL肯定抗不住,进而挂掉,数据库一挂,也会导致系统挂掉。我们总结缓存雪崩触发的条件:“ 高并发情况下 缓存服务器挂了 大量缓存集中失效 ”导致的后果就是:系统崩溃。解决思路,对数据库增加限流排队访问,假设我们的数据库最多能抗住每秒200

2021-03-30 14:45:56 361

原创 Redis是如何持久化到硬盘的

Redis为什么需要持久化我们在项目中或多或少会用到Redis,Redis主要用作缓存数据库。使用Redis可以大大提升我们程序是性能,使用Redis之所以快的原因之一是Redis的数据是存储在内存中,应用程序访问Redis只需要从内存中读取即可。从内存中读取数据确实能提高访问速度,但是当Redis挂了,内存中的数据就会丢失掉,为了防止数据丢失,我们需要将数据持久化到硬盘中。当Redis挂了,数据已经存储到硬盘中了,Redis重启后,硬盘中的数据就会重新加载到内存中。那么,问题来了。

2021-03-30 14:37:18 1225

原创 从Sonar上学习代码优化-代码异味案例

Sonar相信大家都不陌生了,很多公司都把Sonar当做代码质量检测的工具,通过Sonar来考察软件的质量,以及程序员的水平。我们在修改代码异味时,也逐渐提高了自己的编码水平。下面我们来看看在Sonar中常见的一些代码问题吧。包装对象的比较案例代码//两边都为Integer类型if(xxx.getLevel()==xxx.getCurrentLevel()){...}sonar检测问题“所有的包装类对象之间值的比较,全部使用equals方法比较”对...

2021-03-30 14:33:25 937

原创 【知识科普】分布式系统中你不得不了解的CAP定理与BASE理论

CAP定理CAP定理又叫布鲁尔定理,这个定理告诉我们在一个分布式系统中,不可能同时满足下面三点:“ 一致性(Consistency) (等同于所有节点访问同一份最新的数据副本) 可用性(Availability)(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据) 分区容错性(Partition tolerance)(以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。)

2021-03-30 14:30:17 228

原创 分布式环境中如何使用聚合日志系统ELK

ELK简介ELK日志系统相信大家都不陌生了,如果你的系统是集群有多个实例,那么去后台看日志肯定不方便,因为前台访问时随机路由到后台app的,所以需要一个聚合的日志查询系统。ELK就是一个不错的选择。ELK简单说的是:Elasticsearch + Logstash + Kibana。Logstash用于分析日志,获取想要的日志格式;Elasticsearch用于给日志创建索引;Kibana用于展现日志。这里我们还要增加一个采集软件:FileBeat,用于采集各app的日志。系统机构图如下

2021-03-30 14:26:03 556

原创 【知识科普】比多线程还快?了解下什么是协程

什么是线程线程是操作系统能够进行运算调度的最小单位。大部分情况下,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在一些系统中,线程也被称之为轻量进程。而轻量进程一般指的内核线程。一个进程可以有很多线程来处理,每条线程并行执行不同的任务。如果进程要完成的任务很多,这样需很多线程,也要调用很多核心。因此在多核的CPU上面使用多线程程序设计能更有效的利用CPU。多线程示例:@Testpu...

2021-03-12 16:56:03 985

原创 想在线编程么,这几个在线代码编辑器网站适合你

今天给大家推荐几个可以在线编程的网站。对于大部分开发者可能会不屑使用在线的网站,认为在自己电脑安装环境不是很简单的事情么。但是你很有可能临时需要一台电脑去测试一段简单的代码,也有可能想要分享一段代码给别人,也有可能你想要学习很多语言,又不想一一安装编程环境。那么今天推荐的网站肯定满足你的需求。idenone.com网址:https://ideone.com/SExhrM这个网站不错,支持Java,但是页面有广告。除了支持Java语言,还支持其他语言。dabblethttps://

2021-03-12 14:14:24 3859 1

原创 什么,同事写的代码导致数据库死锁了

背景新项目准备上线,测试在测试功能时,发现点击按钮后页面就卡住不动了,开始以为是网络问题,但是这个页面卡住百分之百复现。查看后台日志,发现在执行更新语句的时候被锁住了。通过sql查询select*frominformation_schema.innodb_trx;我们发现是更新表sys_sn_rule导致的,那么我们理一下代码,看看为什么会出现LOCK_WAIT。原因排查通过查看接口调用,我们定位到一个方法上,这里我将方法简化。简化后的代码如下:@Overri...

2021-01-29 15:47:28 244

原创 还记得我之前的代码生成工具么,这次我又给它升级了

又升级啦之前我自己写了个代码生成工具,为了能在创建实体时节省不必要的工作。当时我给这个工具升级了一次。有兴趣的同学可以看看我写的这篇文章:“还记得我之前的代码生成工具么,这次我给它升级了”当时升级的功能可以自动生成Service,ServiceImpl,Controller等类,并按照实际做了定制化的开发。比如实现公司框架接口,公司框架类。这次我主要升级的是:“在Service层增加增删改查代码”源码说明我们来看看代码:首先我在serviceImpl增加了如下代码:

2021-01-27 16:19:08 116

原创 开源的高性能本地缓存-Caffeine

高性能本地缓存在将本地缓存前你肯定在想,本地缓存有么好讲的,不就是一个map么。把要缓存的数据存入map中,自己就能实现。但是这里有几个点我们要考虑:“ 并发-使用普通的Map还是线程安全的ConcurrentMap? 容量-Map的容量需要有多大? 过期策略-Map里的数据如果很久不用是不是需要定时清除? 驱逐策略-如果数据还没有过期,但是容量满了该怎么处理? ”如果你也有这些问题那么请看下面的文章。之前我介绍了Google的本地缓存Guava Ca

2021-01-27 15:59:30 952

原创 SpringBoot中如何让实体类的List属性自动转成Json入库

之前业务开发时,有一个字段接收的数据是Json格式的,并且需要以Json形式入库:数据库中是这样存储的,这里实际是一个Json数组。[{"label":"result1","name":"较好","readonly":false},{"label":"result2","name":"一般","readonly":false},{"label":"result3","na...

2021-01-05 10:20:49 2833

原创 SpringBoot中如何实现接口的统一返回和异常的统一捕获

接口的统一返回在开发公司接口时,发现Controller层的接口返回都需要用一个Result包裹,如下图所示:图示代码中无论是创建接口或者查询接口,这里都需要用一个Result去接收,我们来看看Result的结构:这个Result中有几个字段:“ code:状态码 message:状态信息 data:装载正真返回的数据 exception:异常数据 ”然后我们测试下接口,看看返回样式:调用接口,返回格式为:{"cod..

2020-12-29 09:10:52 639

原创 高并发下如何生成随机数

在平时的开发中我们经常会用到随机数,比如使用new Random()、Math.random()等生成,然而在高并发环境中(比如电商项目,中间件系统等)使用上面的方法并不是最优的,会影响系统性能。那么在高并发环境下我们如何让生成随机数呢?使用Random生成随机数@TestpublicvoidtestRandom(){for(inti=0;i<10;i++){doublerandom=Math.random();S...

2020-12-29 09:03:15 1580 1

原创 如何实现延迟队列

业务背景在平时的业务中我们可能会碰到这样的需求,用户A将任务分配给用户B,如果30天后用户B还没有处理这个任务,那么系统自动将这个任务转发给用户C,或者将任务退回给任务A。这里我们就可以使用延迟队列,我们写好转发方法或者退回方法,用户A分配任务时将时间记录放入延迟队列。当30天后用户B没有处理,我们获取从延迟队列里面获取这个记录,能获取得到,就执行转发方法或退回方法。如果30天内用户B处理了任务,那么就将延迟队列对应的时间记录删掉。任务转办当然延迟队列还有很多使用场景,比如用户下单30分

2020-12-15 17:10:03 405

原创 还在用StringBuilder进行字符串拼接?那你就OUT了

我们在开发中会经常拼接字符串,例如我们现在有一个数组:privatestaticfinalString[]names={"我","大意了啊","年轻人","不讲武德","来骗"};我们需要将元素提取出来,然后拼接成一个整字符串,目标效果如下:我,大意了啊,年轻人,不讲武德,来骗"+"拼接那么,你准备怎么做:@Testpublicvoidtest(){Stringstr=names[0]+","+names[1]+",...

2020-12-11 15:52:13 641

原创 Google的这个本地缓存真好用

在平时的开发中,我们会经常用到字典,比如我们数据库里面存的是设备编码,展示需要的是设备名称;数据库中存的是用户id,展示的是用户名称。这样的字段我们会频繁的调用,那么就会频繁的查询数据库,为了保证访问速度,我们会使用缓存。但是如果使用Redis之类的中间件缓存,又有点大材小用。当然我们也可以自己将需要的数据存入Map中,但是要考虑Map的预计容量,数据缓存的时间等等。这样对Map的设计就比较麻烦。这里我推荐Google的类库框架Guava里面的本地缓存。使用前我们先引用Guava的Maven依赖:

2020-12-11 15:48:43 469

原创 这款插件让我的SpringBoot项目实现了热部署

热部署相信你肯定被【修改代码后还要重新部署项目才能测试】这个问题困扰过。有些大项目部署启动一次可能要花个几分钟,我们写完代码后需要自测,测试人员来测试,前后端联调测试。这些过程都需要修改代码,然后重启系统。这样算下来,一天一大半的时间都花在了重新部署上了。那么有没有热部署方案,我修改了代码,不需要重新启动系统也能测试呢。市面上也有很多热部署的方案,比如devtools热部署、springloaded等。这些部署需要引入对应的Maven包,配置相关的配置文件,而且时灵时不灵。关于这些热部署方式网上有很

2020-12-07 08:42:11 185

原创 我用stomp框架写了一个即时聊天工具

WebSocket技术可以让服务端主动将信息推送给客户端,不必像Http协议那样客户端想要获取服务端数据,必须要向服务端发起一个请求。WebSocket是全双工协议,类似于Socket通信,双方都可以在任何时刻向另一方发送数据。适合用于即时通信。这次我打算用stomp(基于WebSocket)框架来实现一个类似QQ的即时通讯工具,功能比较简陋,但是主体功能没有问题,有兴趣的童鞋可以进行改造。代码实战导入stomp框架工程目录WebSocketConfigGlobalC

2020-11-30 10:06:32 302

原创 连续写了一个月的设计模式,现在我把它汇总成PDF了

嗨,经历一个月我的设计模式系列终于告一段落啦。如上图这是我在微信公众号【Lvshen_9】上发表的设计模式系列文章,我写设计模式的目的也是在于自己学习,还有和大家一起交流,一起进步。之前就只知道一些单例、代理、观察者等代理模式。写完了确实对设计模式有了更深的认识。除了在公众号上面发表,我还在头条上【Lvshen的技术小屋】也发表了。下面来看看我整合的PDF:里面的图都是自己画的,代码我都上传到Github了。对图和代码有兴趣的可以私聊。部分目录:我写这个系列的文章

2020-11-27 08:50:17 130

原创 设计模式23之桥接模式(终章)

背景在现实生活中,一个物体往往具有多个方面的属性。如果我们将人进行归类。我们可以按性别分类,也可以按肤色分类,也可以按所处的地区分类,还可以按自己的母语分类。在代码中我们如何让表示这个人呢。如果以继承的方式表示,就会出现很多子类,这样扩展就会很麻烦。我们可以使用桥接模式来解决这些问题。什么是桥接模式“Decouple an abstraction from its implementation so that the two can vary independently.(将抽象和实现

2020-11-26 08:22:43 132

原创 设计模式22之享元模式

背景在我们编码开发过程中可能会遇到需要创建大量相同或相似对象实例问题。如果我们把这些对象都创建出来,会耗费系统资源。但是我们可以将这些公共的部分抽取出来,就会节省大量的系统资源。因此享元模式就这样出来了。什么是享元模式“Use sharing to support large numbers of fine-grained objects efficiently.(使用共享对象可有效地支持大量的细粒度的对象。)”享元模式的核心思想就是共享,相同的对象只保留一份。但是为了实现共享,不同的状

2020-11-25 15:41:24 129 1

原创 设计模式21之解释器模式

背景在软件开发中,可能会出现某些相似的功能多次出现,这些功能有一定的相似性与规律性。这是我们就可以将其归纳成一种简单的语言。这就是解释器模式的来源。上面的讲述是不是云里雾里的,那我们来举个例子。我们要开发一个功能,要求输入公式,输入参数,返回正确结果。例如我们输入参数:a=2;b=4;c=10我们再输入表达式:a+b-c输出结果:-4。我们再来输入一个表达式:a*b/c输出结果:0.8。如果要你开发这个功能,你会怎么做?如果使用解释器模式,会有很好...

2020-11-24 08:41:54 130

原创 设计模式20之状态模式

背景在开发过程中,对象会有根据不同的情况做出不同的行为,而影响行为的属性称之为状态属性,这个对象也就是状态对象。我们在编码时,可能会使用if-else来做状态判断。例如我有一个活动类Activity,这个类里面有一个活动开始字段,活动结束字段,还有一个状态字段,现在我们要来判断活动的状态:未开始、进行中、已结束。示例代码如下:当状态很多,那么程序会变得很复杂。如果有新的状态增加,就要添加新的if语句,违背设计原则中的开闭原则。所以我们采用状态模式来解决这个问题,我们将对象状态的判断逻辑抽

2020-11-23 09:43:51 215

原创 我用注解实现接口的操作流水日志

在项目中,我们会需要获取接口的操作日志。比如获取接口的接口名、操作人,接口运行时间、所属的服务、接口的类型(增删改查)等等。初级的做法是在接口方法执行完后将这些操作记录存入库中,这段代码写在接口中,但是这样违反了设计原则中的单一职责原则。常用的做法是使用AOP来做,在运行时动态的插入日志记录的代码。这里我是用注解来做。创建日志记录表首先我们来创建日志记录表:operation表当然后编写实体类:编写日志记录注解我们先定义一个注解OperationLog这个注解里面定义

2020-11-17 08:26:06 4023

从 0 开始学习 GitHub 系列.pdf

github相关使用,行内大神出品,从最近开始的github认识到,熟练使用github,本教程都给了完整的说明

2017-10-19

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除