- 博客(71)
- 资源 (1)
- 收藏
- 关注
![](https://csdnimg.cn/release/blogv2/dist/pc/img/listFixedTop.png)
原创 懒人如何用爬虫批量把CSDN的博客导出成markdown文件
最近博主搞了一个博客网站,但是遇到一个头疼的事情,就是要把以前写在csdn上的博客批量导出成markdown文件,但是csdn上只支持单个导出,而且我的博客网站是用jekyll搭的,还需要在每个md里面另外加一些配置信息,要是得一个个导出一个个改那可得累死我喽。于是我网站搜了一些资料,发现网上有一些用python写的爬虫,我想为什么我不自己用java写一个爬虫实现这个功能呢?一. 思路打开博...
2020-03-10 22:09:54
1699
6
原创 学习ddd(一)-- 领域驱动设计相关概念
我之前一直对领域驱动设计(DDD)相关的知识有零散的认识,没有系统性地学习过。最近抽空系统地学习了一下,发现这块知识比较抽象,很难读懂。加上我自己的理解,我整理了一些知识,希望能够分享给大家第一期先讲些了DDD的一些基础概念。
2024-04-11 20:20:40
935
原创 模板模式实现分布式锁实战
分布式锁相信大家都有用过,常见的分布式锁实现方式例如redis、zookeeper、数据库都可以实现,而我们代码中强引用这些分布式锁的代码,那么当我们以后想替换分布式锁的实现方式时,需要修改代码的成本会很高,于是我们需要借鉴一些设计模式思想来设计,下面我介绍下这三个分布式锁的实现逻辑以及我们项目中是怎么实现。
2024-01-05 17:10:10
827
原创 注册中心ZK、nameServer、eureka、Nacos介绍与对比
微服务架构是存在着很多跨服务调用,每个服务都存在着多个节点,如果有多个提供者和消费者,当提供者增加/减少或者消费者增加/减少,双方都需要感知发现。所以诞生了注册中心这个中间件。市面上有很多注册中心,如 Zookeeper、NameServer、Eureka、Nacos,下面我来讲一下它们的特点、应用和区别。
2023-11-01 17:34:34
1071
原创 设计模式之责任链模式
责任链模式是常见的行为型设计模式。当我们需要实现的业务逻辑需要通过多个步骤来处理,并且这些步骤有排列组合的场景时,就可以使用责任链模式。
2023-10-12 10:37:57
444
原创 记一次线上oom排查过程
我们服务器的jvm配置是-xms 128m -xmx4096m,当时我们查看机器的可用内存已经只有1g了(当然这里也有问题),于是判断是xms设置的太小了,xms是jvm初始堆内存,刚开始只有128m的大小,后来随着对象越来越多,jvm会进行扩容,但是扩容到1g大小的时候,服务器资源就不够了,于是开始fullgc清理垃圾,经过几次fullgc也没有回收足够的空间,所以导致了oom。我们查看了oom的报错是overhead limit exceeded,即gc超过一定次数,没有回收出足够的垃圾导致的。
2023-03-17 14:54:58
219
原创 优雅数据同步--canal实现mysql同步demo
当需要两张表数据同步的时候,我们会想到几种方案?最简单的一种方式就是触发器的方式。例如A同步到B,可以通过下面的sql来添加触发器但是这种方式有一定的弊端和局限性,首先就是只局限同库,并且会增大数据库开销,以及无法实现一些自定义的逻辑。canal是阿里推出的一个开源的中间件,它的原理类似于mysql主从的原理,它把自己伪装成mysql的从库,这样就可以从主库中获取binLog来复制数据接下来我们自己搭建一个canal同步mysql的一个demo。
2022-12-23 17:56:17
2179
原创 设计模式之观察者模式
这样写看似没什么问题,某一天产品经理突然说,商品改名需要把采购单据的相关商品名称也要同步修改,那么我们在itemChangeName 方法里又要进行修改,添加修改采购单相关方法。我们执行main方法执行结果跟老方法相同。这样如果后续商品改名需要同步修改采购单的商品名称,我们只需要再增加一个事件实现类添加进去就ok了,无需修改代码,这样遵从了开闭原则。首先我们要明白为什么需要观察者模式,我们举个例子分析。观察者模式是我现在公司用的很广泛的一种设计模式,同时也十分好用,下面我推荐给大家。...
2022-08-16 21:04:57
291
原创 学习ES搜索引擎(二)--ES基础了解
MySQL是关系型数据库,里面的数据是一行行数据。而ES是以一条条Document(文档)为单位存储的。Document的结构就是Json数据结构。上一节我们学习了怎么安装ELK,好了接下来我们可以通过Kibana学习下ES的增删改查语句。我们对数据库比较熟悉,刚开始了解ES时可以跟MySQL进行对比。下面重点讲下ES的查询语句,对比MySQL方便理解。我们举例一条Document分析下结构。ES是一个分布式的全文搜索引擎。相对应MySQL存储的话如下。...
2022-08-03 14:02:39
615
原创 github action使用
当我们需要发布服务时,往往是怎么操作的?最古老的方法无非是本地打包,然后ssh到服务器上,上传新包,删除老包,执行脚本启动。这个过程自己操作起来十分复杂,而且容易出错。后来我们了解到,可以通过一些持续集成工具比如Jekins来运行脚本进行打包上传到服务器。但是还是不够便捷,有什么方法可以更便捷?下面就引出这次使用的新工具,github的action工具。它的功能十分强大,我这边只介绍它的一部分功能来帮我实现CICD。当我提交代码合并到某个分支后,github action就可以自动帮我拉下代码打包,上传
2022-05-20 15:07:28
1304
原创 用Java给女友自动提交工作内容的自动化脚本
女朋友每天早上都需要登录某工作网站提交一项内容,其实在程序员看来,这些都是可以用代码自动化解决的,于是我开始加班加点搞了起来。整理需求首先我们需要整理一下需求,首先她需要早上登录某网站,然后进入某一目录,点击提交。这就是整理的需求技术选型&& 功能设计首先需要挑选框架,我这边用的是springboot,因为这个搭建和部署都比较方便然后发起登录请求网站获得cookie,然后再发起提交请求。我这边用的是httpclient的工具来做的,因为这个我比较熟悉其次,需要用定时任务框架来每天
2022-02-06 13:21:53
402
原创 单元测试--Mockito+JUnit
最近领导开始要求写代码需要写单元测试了。于是花了点时间研究下单元测试。一、目的单元测试适合一些项目复杂,启动一次项目要花很大成本的项目,这样我们可以通过单元测试去很快的测试它,而不需要启动项目来调试。二、测试范围单元测试最适合测试一些util方法,以及一些判断逻辑。如果碰到一些比较难写单测的方法,可能需要我们把方法进一步拆解后再进行测试。三、怎么写单元测试方法里每个if逻辑的正反两面都可以测试,以及一些边界值。同一个测试方法,可以通过传入参数的不同,测试不同的逻辑。最后通过assert或者Ver
2021-12-21 00:00:26
661
原创 捞取大量数据慢查询优化
场景双11期间这家客户积压了5w笔订单没有发货,所以客户反映每次计算都很慢,需要几十秒的时间。波次计算的代码需要把系统中审核的订单捞出来后进行计算分组划分到不同的批次中。排查过程首先我们通过链路和althas排查,发现查询子订单的sql需要in 5w个id。导致这个sql异常的慢,需要17s。方案于是我们商量了方案,首先这个sql就是一个简单的单表查询,in的字段也加了索引,所以不需要额外加索引,主要问题还是in的数量太多,查询很慢。采取多线程分批并行查sql这个方案,2000一批。查完后再聚合数
2021-11-07 16:56:59
284
2
原创 学习ES搜索引擎(一)--Mac安装ES和Kibana及简单实用
最近打算研究下ES和Kibana,打算先自己安装学习一下。通常我们服务器会通过log4j会把服务器日志输出到到控制台上来或者log文件中。但是如果是分布式系统,我们查看日志会很不方便,所以我们可以通过es+logstash+kibana来管理日志,首先通过logstash来将log文件写入到es中,然后通过kibana终端来搜索es中的日志1.安装ESmac下安装软件非常方便,我们只需要输入下面命令即可安装brew install elasticsearch安装完毕后输入下面命令就可以启动elas
2021-11-07 16:48:44
2746
原创 公司open api对接遇到的问题解决
之前在写开放平台的接口的时候,碰到了一些问题,记录一下api接口速度优化由于工期很赶,所以还没来得及自己测试,接口匆匆忙忙上线,当客户在用时,发现查询接口使用特别慢。然后分析原因,发现有慢sql引起的。首先,接口调用的是我们系统的一个现成接口,主表的数据量很大,又冗余了一些不需要的关联表,于是我决定用自己的sql来执行,其次我们接口给出的时间参数发现没有加索引,导致全表扫描。所以加了索引后接口从5s降低到1s,其次,我使用althas发现接口的时间一半多的时间都在请求count,而调用方只需要第
2021-10-31 12:11:21
728
原创 记一次长事务问题排查思路
今天早上dba群里抛出一个问题说,有一个长事务一直在重复执行我们的一个语句。于是问题抛给我们,我们开始排查。首先dba告知我们这句sql是重复在调用,然后还有这个事务的其他sql语句,还有开始的时间点。我的想法是先从请求入手,看看这个时间点有没有耗时特别长的,或者跟这些sql相关的请求,但是一开始并没有找到,原因后面再说。第一步失败后,就只能从代码找起了,先找到对应sql的位置,然后找到对应的接口,一步步找。这个过程是比较痛苦的,还好我运气不错,找到了跟这个长事务中的sql十分相似的代码,是订单导出。
2021-07-27 17:37:43
413
原创 通过数据库唯一索引实现分布式锁
伪代码// 需要加事务@Transactional@Overridepublic <T> T lock(XxxLock lock, ILockCallback<T> callback) { // 数据库加锁 lock(lock); // 加锁逻辑 T result = callback.callback(); //释放锁 try { lockDao.batchDelete(locks); } catch
2021-05-27 11:06:14
687
转载 如何设计一个安全的对外开放接口
前言最近有个项目需要对外提供一个接口,提供公网域名进行访问,而且接口和交易订单有关,所以安全性很重要;这里整理了一下常用的一些安全措施以及具体如何去实现。安全措施个人觉得安全措施大体来看主要在两个方面,一方面就是如何保证数据在传输过程中的安全性,另一个方面是数据已经到达服务器端,服务器端如何识别数据,如何不被攻击;下面具体看看都有哪些安全措施。1.数据加密我们知道数据在传输过程中是很容易被抓包的,如果直接传输比如通过http协议,那么用户传输的数据可以被任何人获取;所以必须对数据加密,常见的做法对
2021-01-15 15:50:20
1654
1
原创 事务隔离级别实现-行锁与MCCC
我们都知道数据库在并发同时执行的时候,就可能出现脏读、不可重复读、幻读的问题,为了解决这些问题,设置了四种事务的隔离级别,分别是读未提交:A事务【能】看到B事务【未提交】的修改读已提交:A事务【能】看到B事务【已提交】的修改可重复读:A事务【不能】看到B事务【已提交】的修改串行化:所有事务按顺序执行,不能并行我们以Mysql为例,Mysql是怎么实现这些隔离级别的呢?1. 通过数据库行锁实现Mysql的行锁有两种,【读锁】(共享锁)和【写锁】(排它锁)。如果有一行数据如果加了【读锁】,那么
2020-11-04 20:52:55
307
原创 匿名内部类使用
在我们开发中,匿名内部类用的还是比较多的,笔者有点忘了一些细节,所以今天带大家复习一下匿名内部类匿名内部类既没有名字的内部类正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口场景一: 不使用匿名内部类/** * 场景一:不使用匿名内部类 * @Auther: zntzhang * @Date: 2020/8/4 12:47 * @Description: */public class Demo1 {
2020-08-04 16:48:41
299
原创 JVM相关知识点总结
1. 内存结构每个线程都有:程序计数器:记录了上下文切换的位置虚拟机栈:由栈帧组成,入栈出栈本地方法栈:Native方法每个线程共享:堆:对象方法区(jdk8后改名元空间):类信息、常量、静态变量2. 对象创建的过程new 一个对象经历了哪些步骤?类加载检查:使用双亲委派模式,从子类往父类询问是否已经加载到内存?如果都没有加载过。那么再从父类到子类依次尝试加载,把类加载到内存分配内存:从堆中划一片区域。根据堆内存是否碎片化,划分成两种方法a. 指针碰撞:堆
2020-08-03 17:13:35
199
原创 SpringBoot之Starter
SpringBoot之所以流行,是因为Spring Starter模式的提出。Spring Starter的出现,可以让模块开发更加独立化,相互间依赖更加松散以及可以更加方便地集成。什么是Starter?SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置,发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对
2020-07-27 09:57:14
285
原创 总结自己常用的JDK8写法(stream,function,optional)
1. 判空特别要注意的是list集合,我们sql查询返回的list或者stream处理完的list都不可能是null,所以不需要判断是否为null遍历列表处理Optional.ofNullable(list) .orElseGet(Lists.newArrayList()) .forEach(...);获取对象属性String value = Optional.ofNullable(data) .map(da
2020-07-27 09:56:44
938
原创 高可用方案和一致性hash
其实大部分中间件都逃不过这两种模式中心化模式这种模式的特点是有一Master多slave,一般采用读写分离的方式,只从master中写,然后同步给slave(主从同步)。读是通过负载均衡从所有的slave中读。一般能保证CP,既强一致性缺点:master挂了就很烦常见场景:redis主从、哨兵,mysql,zk去中心化模式既所有机子都是通过负载均衡来承担读写。一台机子写入后同步给其他机子(P2P同步)。这样的好处是可拓展性强,如果机子内存不足,就再买一台就ok了。缺点:数据的一致性一
2020-07-27 09:56:16
523
原创 SPI机制应用
为什么要使用SPI?我的理解它其实是一种设计模式的体现。比如一个好的框架,我作为框架的使用者,在添加一个新功能时,不需要去修改框架的源码,在自己的工程中添加代码即可。系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。SPI机制其实就是我们的框架会通过ClassLo
2020-07-27 09:55:42
305
原创 OOM、CPU飙升、Java进程被杀 线上故障分析
OOM关于OOM出现的情况,一般可以猜想是内存泄露,或者是加载了过多class或者创建了过多对象,给JVM分配的内存不够导致dump分析首先用top、ps-ef|grep java等命令查看java进程的pid然后使用一下命令可以内存信息dump下来jmap -dump:format=b,file=文件名 [pid]使用JConsole或者其他软件查看堆中是否有大对象没被释放。如果没有大对象的话那么考虑是否是堆外内存,都没有问题的话考虑调大JVM内存配置。CP
2020-07-27 09:55:11
890
转载 如何判断一个元素在亿级数据中是否存在?---布隆过滤器
前言最近有朋友问我这么一个面试题目:现在有一个非常庞大的数据,假设全是 int 类型。现在我给你一个数,你需要告诉我它是否存在其中(尽量高效)。需求其实很清晰,只是要判断一个数据是否存在即可。但这里有一个比较重要的前提:非常庞大的数据。常规实现先不考虑这个条件,我们脑海中出现的第一种方案是什么?我想大多数想到的都是用 HashMap 来存放数据,因为它的写入查询的效率都比较高。写入和判断元素是否存在都有对应的 API,所以实现起来也比较简单。为此我写了一个单测,利用 HashSet 来存
2020-07-24 15:27:38
303
原创 Redis面试常考题
1. MySQL 和 Redis的区别2. Redis 和 memcached 的区别Redis 和 memcached 都是从内存中读取,memcached比Redis读取更快,但是redis有很多优点redis支持更丰富的数据类型,memcached只支持String。Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,而Memecache不支持。memcached没有原生的集群模式,但是 redis支持集群.Memcached是多线程;Redis使用单线程的多路 IO 复用模
2020-07-24 14:27:29
153
原创 超详细,从零开始搭建阿里云服务器(centos7)第六章 安装Maven和RocketMq
RocketMq是真的难搭,废了好多功夫才搭建完,碰到了好多坑,下面我把我吃到的坑记录下来安装流程1. 安装Maven1.1 下载mavenwget http://mirrors.shu.edu.cn/apache/maven/maven-3/3.6.0/source/apache-maven-3.6.0-src.tar.gz解压maventar -zxvf apache-maven-3.6.0-src.tar.gz1.2 编辑环境变量vim /etc/profile添加以下配置
2020-07-23 09:45:10
345
原创 为什么我两次sql查询,查出来的对象引用是同一个?
回答这个问题,我们需要掌握MyBatis的缓存概念,如果我们两次查询,一次是数据库查询,而第二次直接取得缓存中的数据,那么这两次查询查询的数据就是同一个对象一级缓存Mybatis的一级缓存是Session级别的缓存。一级缓存的作用域默认是一个SqlSession。Mybatis默认开启一级缓存。在同一个SqlSession中,执行相同的查询SQL,第一次会去数据库进行查询,并把对象放入缓存中,第二次以后是直接去缓存中取。当执行SQL查询中间发生了事务提交(增删改都会触发自动提交)的操作,都会把当前S
2020-07-22 17:42:39
1792
原创 拦截器、过滤器、AOP的区别
拦截器spring中独有的在SpringMVC的配置文件中配置可对请求和响应处理<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.scorpios.atcrowdfunding.web.LoginInterceptor"></bean> </mvc:interceptor
2020-07-22 17:41:58
224
原创 简单介绍AQS、ReetrantLock、CountDownLatch、CyclicBarrier、Semaphore
AQS,既AbstractQueuedSynchronizer, 是JUC包实现同步的基础工具,是一个抽象类。在AQS中,定义了一个volatile int state变量作为共享资源,并且内置自旋锁实现的同步队列,封装入队和出队的操作,提供独占、共享、中断等特性的方法。如果线程获取资源失败,则进入同步FIFO(先进先出)队列中等待(入队);如果成功获取资源就执行临界区代码。执行完释放资源时,通知队列中的等待线程来获取资源,然后出队。AQS的子类可以定义不停的资源实现不同性质的方法Reetran
2020-07-04 15:29:16
237
原创 Spring容器初始化和解决循环依赖问题的分析
1. Spring IOC容器初始化过程:2. bean的生命周期Bean 容器找到配置文件中 Spring Bean 的定义。(beanDefintion)Bean 容器利用 Java Reflection API 创建一个Bean的实例。(执行构造方法)如果涉及到一些属性值 利用 set()方法设置一些属性值。(set属性)如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName()方法,传入Bean的名字。(aware接口的相关方法)如果 Bean 实现了
2020-06-25 11:57:28
424
原创 项目集成swagger启动报错 Error creating bean with name webMvcRequestHandlerProvider
最近项目集成了swagger以后启动一直报错org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/Users/jasonfeng/.m2/repo...
2020-04-09 22:34:11
18184
2
原创 浅入浅出Netty(三) Netty线程模型
实际上Netty线程模型就是Reactor模式的一个实现,而Reactor模式又是什么呢?Reactor模型Reactor模式是基于事件驱动开发的,核心组成部分包括Reactor和线程池,其中Reactor负责监听和分配事件,线程池负责处理事件,而根据Reactor的数量和线程池的数量,又将Reactor分为三种模型:单线程模型 (单Reactor单线程)多线程模型 (单Reactor多...
2020-04-09 22:33:20
188
原创 浅入浅出Netty(二) Netty
这一遍先简单的讲一些netty是如何实现nio的代码的,后面会详细讲述netty原理一、Netty是什么用一句简单的话来说就是:Netty 封装了 JDK 的 NIO,让你用得更爽,你不用再写一大堆复杂的代码了。用官方正式的话来说就是:Netty 是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。二、为什么要使用Netty而不使用NIO使用 JDK 自带的NI...
2020-04-09 22:32:38
159
原创 浅入浅出Netty(一)BIO与NIO
传统IO模型在开始了解 Netty 是什么之前,我们先来回顾一下,如果我们需要实现一个客户端与服务端通信的程序,使用传统的Socket通信,应该如何来实现?public class BIOServer { public static void main(String[] args) throws Exception { //创建Socket服务,监听8000端口 ...
2020-03-28 21:52:48
149
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人