- 博客(93)
- 收藏
- 关注

原创 为什么别人工资比你高?谷歌大佬的「程序员性能优化手册」你有吗
前言性能优化可以说是我们程序员的必修课,如果你想要跳出CRUD的苦海,成为一个更“高级”的程序员的话,性能优化这一关你是无论无何都要去面对的。为了提升系统性能,开发人员可以从系统的各个角度和层次对系统进行优化。除了最常见的代码优化外,在软件架构上、JVM虚拟机层、数据库以及操作系统层面都可以通过各种手段进行调优,从而在整体上提升系统的性能。这是我挖掘的,谷歌资深架构师Java程序性能优化手册,从软件设计、编码和JVM等维度阐述性能优化的方法和技巧。因为公司的制度问题谷歌架构师被迫离职留下了这份程序性
2021-07-22 02:38:00
2385
8
原创 一文带你了解Spring Actuator
随着微服务架构的普及,Spring Boot 已经成为Java开发人员的首选框架。然而,随着应用的规模不断扩大, 如何有效地监控和管理这些应用成为一个重要的问题。Spring Boot Actuator的出现,为开发人员提供了一个解决方案。本文将详细介绍Spring Boot Actuator的功能、工作原理、使用场景以及应用示例,帮助读者更好地理解和掌握这一工具。
2024-12-12 20:05:44
608
原创 Redis 热 Key 发现以及解决办法
在这一篇文章中我们首先分析了在Redis中热Key带来的一些问题,同时也介绍了在海量的RedisKey中找到热Key的一些方法,最后也提到了在解决热Key问题中我们常用的一些办法;总结来说,Redis热Key问题首先是请求流量过大造成的,但是更深层次原因还是出现了流量倾斜,单个Redis实例承担的流量过大造成的,了解到了本质原因,解决的思路也就简单了,就是要想尽一切办法将单个实例承担的流量打散,让每个机器均衡承担热Key的流量,不要出现流量倾斜,保证系统的稳定性。
2024-12-12 20:04:56
717
原创 现学现用,写个Maven插件用下
在上面的例子中,我们项目包括了system、monitor等多个模块,其中system模块包含了account、role、permission三个子模块, monitor模块包含了database、disk、memory三个子模块,每个子模块又包含了特定的代码结构. 这个属于我们约定的模块划分规则,那么基于这样的规则,我们完全可以通过开发一个插件来自动生成这种约定结构的空项目。那么我们则可以根据这种约定的规范,通过工具来自动化的生成代码,从而减少开发人员的工作量。根据我们预期要求,来设想插件的开发过程。
2024-12-12 20:03:50
352
原创 为什么Java String哈希函数乘数为31?
在实际应用中,使用 31 作为乘数可以提供良好的哈希值分布和计算速度。当然,也可以使用其他质数作为乘数。但是,31 是一个相对较小的质数,因此它在计算速度方面具有优势。此外,31 也是一个常用的质数,因此在许多其他哈希函数中也得到了使用。但是,对于大多数应用程序来说,31 都是一个不错的选择。31 是一个奇数,因此 31 * i 的结果可以只使用 31 位来表示。在哈希函数中,使用质数作为乘数可以提高哈希值的分布均匀性。例如,如果使用 10 作为乘数,那么所有以 5 为尾数的字符串的哈希值将是相同的。
2024-12-12 19:59:42
299
原创 Spring Cloud Gateway中优化Netty线程池,提升系统性能
通过优化 Spring Cloud Gateway 中的 Netty 线程池,我们成功提升了系统的性能,为系统的稳定运行和业务发展提供了强有力的支撑。通过细粒度的控制,确保了每个组件都有足够的线程来处理自己的任务,同时又不会导致线程池过度竞争。这样,每个组件的线程池都可以专用于处理自己的任务,避免了不必要的竞争和性能干扰。然而,默认的 Netty 线程池配置并不适合高并发场景,导致线程池过度竞争,影响了性能。我们根据系统的实际并发量,调整了线程池的大小,使其能够更好地处理高峰时期的请求。
2024-12-12 19:58:57
668
原创 Spring Boot 插件化开发模式
通过这个类,将上述配置文件中的实现类封装到类对象中,方便后续使用;@ToString@Getter@Setter@Getter@Setter使用上述的封装对象通过类加载的方式动态的在程序中引入@Autowiredi++) {自定义一个接口,里面添加一个方法;实现类1@Override实现类2@Override添加一个自定义的接口,有没有发现,这里和java 的spi有点类似,只不过是这里换成了去加载服务;
2024-12-12 19:57:25
958
原创 终于把Spring Boot Starter 讲清楚了
spring-boot的强大之处在于其提供的大量starter组件,基本涵盖了我们开发中的各个技术领域,比如数据库访问有jdbc、jpa,缓存有redis,全文检索有elasticsearch,消息队列有amqp、kafka等等。上面说到了,@Import还可以配置实现了ImportSelector接口的类,进而控制具体需要使用的Configuration,下面是@EnableAsync中@Import配置的类。这不,别人也想到了。
2024-12-11 15:56:30
824
原创 手把手教你写spring boot starter
整个模块的结构如上其中作为一个根模块,主要控制子模块依赖的其他 jar 的版本以及使用到的插件版本。类似于 Spring-Bom,这样我们在后续升级 时,就可以解决各个第三方 jar 的可能存在版本冲突导致的问题。该模块作为外部项目集成的直接引用 jar,可以认为是 pulsar-spring-boot-starter 组件的入口,里面不需要写任何代码,只需要引入需要的依赖(也就是下面的子模块)即可。
2024-12-11 15:54:23
851
原创 Spring AOP是怎么回事?
由于springboot的出现,xml的配置形式使用 得比较少了,但是这种配置的形式更直白地体现了AOP需要的配置以及各个组件的依赖关系。而基于@Aspect的形式代理业务模块中的方法更简单直观,而基于ProxyFactoryBean、ProxyFactory的方式,在编写类似 cache的模块会更加的灵活。我们可以生成基于目标对象的代理。JointPoint(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它joint point。
2024-12-11 15:53:30
748
原创 SpringBoot如何优雅的实现异步调用?
这三种实现异步任务的方法各有优缺点,具体如下:基于注解的方式优点:简单易用,只需要在方法上添加@Async注解即可。依赖Spring框架,集成度高,可以与其他Spring组件无缝协作。缺点:方法必须是public,否则异步执行无效。不能直接获取异步执行结果,需要使用Future或CompletableFuture等类型。实现AsyncConfigurer接口的方式优点:更加灵活,可以配置线程池等异步执行的相关参数。
2024-12-11 15:51:52
421
原创 一个熟悉又陌生的关键字:volatile
在Java多线程编程中,保证线程安全性是至关重要的。而volatile关键字是实现线程安全性的一种关键机制。为什么熟悉又陌生呢?Java开发者几乎全都用到过这个关键字,但是又不记得什么时候用了它。
2024-12-10 19:25:34
736
原创 字节一面:TCP和UDP能使用同一个端口号吗?
今天在知乎看到一个字节跳动的面试题,感觉还有点意思,分享给大家。在回答这个问题之前,我们可以先了解一下 TCP 和 UDP 分别是什么。
2024-12-10 19:24:53
582
原创 MySQL怎么快速插入1亿条数据
综上,提高MySQL插入效率主要可通过调整数据库配置、选择适合的存储引擎以及运用批量插入策略等方式实现。在实际应用中,尤其是在使用ORM框架进行数据操作时,应合理选择并充分利用批量插入功能,以最大程度提升插入效率。省流连接数据时,数据源配置文件url加上数据量很大时,使用mybatisPlus或MybatisFlex提供的saveBatch即可。
2024-12-10 19:23:29
841
原创 MySQL误删数据怎么办?
今天给大家介绍一个很常见的数据库面试题:MySQL误删数据怎么办?大家都知道数据库最重要的就是数据,数据安全是重中之重,对于这种事后面试题,其实面试者回答一些提前规划,比如提前避免误删数据的措施是很加分的。
2024-12-10 19:21:46
276
原创 Java线程池为什么先入队列再增加线程数?
最近项目团队招人,我面试了很多人,非常喜欢问一个问题,Java线程池为什么先入队列再增加线程数?在Java编程中,线程池是一种重要的并发编程工具,能够有效地管理线程的生命周期、控制并发资源的使用情况。关于线程池的理解对Java编程的理解也是非常重要的。为什么Java线程池在任务队列不满的情况下会优先将任务入队列,而不是直接增加线程数。本文将深入探讨这一问题的原因及其背后的设计思想。
2024-12-10 19:20:35
585
原创 JVM 之逃逸分析技术
逃逸分析技术其实也是很复杂的,所以也是一个会耗时的过程,如果经过逃逸分析之后,发现所有对象都逃逸了,就不能做优化处理,那这个逃逸分析的过程就消耗了时间,还不起优化作用,得不偿失。如果分析出加锁的对象不会发生逃逸,即只能被一个线程访问,JIT 是可以优化消除这个锁的。逃逸分析,其实就是分析一个对象是否会逃逸出方法,分析对象的动态作用域。以上演示程序,Object 对象不会发生逃逸,所以也只能当前线程访问到,所以 JIT 编译器可以进行优化锁消除。如果分析一个对象没有逃逸出方法的时候,就有可能被分配到栈上。
2024-12-09 16:24:08
848
原创 Session 和 Cookie 浅谈
Session 是存储在服务端的,可以存储在文件,内存,数据等等,并且有唯一的标识 Session ID。这样同个客户端以后的每一个请求将 Cookie 一起发送给服务端,服务端通过存储在 Cookie 的 Session ID 查出存储在服务端的 Session ,就能知道此次请求的是哪个用户了。这样同个客户端以后的每一个请求会将 Cookie 一起发送给服务端,服务端通过存储在 Cookie 的 Session ID 查出存储在服务端的 Session ,就能知道此次请求的是哪个用户了。
2024-12-09 16:23:36
743
原创 01 设计模式之单例模式
但是如果项目是多人协作的,其他人使用这个配置信息的时候选择每次都去 new 一个新的实例,这样就会导致每次都会生成新的实例,并且重复读取配置文件的信息,多次 IO 操作,系统中存在多个 AppConfig 实例对象,严重浪费内存资源,如果配置文件内容很多的话,浪费系统资源更加严重。在 Java 中,单例模式的实现一般分为两种,懒汉式和饿汉式,它们之间主要的区别是在创建实例的时机上,一种是提前创建实例,一种是使用时才创建实例。所以我们一般推荐饿汉式单例模式,因为由 JVM 实例化,保证了线程安全,实现简单。
2024-12-09 16:22:51
889
原创 02 设计模式之策略模式
在策略模式中,为了让算法独立于使用算法的客户端,引入上下文对象,它持有具体的算法实现类,根据客户端选择具体的算法后,执行对应的具体算法。对于一系列的算法,将具体的算法实现从具体的业务中独立出来,将它们封装成一个个单独的算法类,这些算法是平等的,算法之间可相互替换,并且可独立于使用算法的客户端而变化。只有由客户端来选择具体的策略算法的情况下,客户端才需要知道所有的具体策略,当然上下文也可以结合工厂方法模式,接收客户端传进来的标识,创建相应的具体策略类。然后定义不同的具体策略实现类,并且实现策略接口。
2024-12-09 16:22:19
470
原创 03 设计模式之工厂模式
当然这些结构不一定都是定死的,设计模式表达的是一种思想,思路,具体的落地方案都是得根据实际情况而定的,比如工厂方法模式不一定要定义工厂接口以及多个实现类,也可以直接定义一个工厂具体类,根据客户端传入的参数或者读取其他数据(例如配置文件,数据库等)选择创建具体的实例即可。定义一个用于创建对象的接口,接口实现类决定创建哪一个类的实例,工厂方法使一个类的实例化延迟到接口的实现子类上。工厂模式可以解决以上问题。ConcreteFactory:抽象工厂的具体实现类,负责一系列有相互关系的类的对象的创建。
2024-12-09 16:21:46
932
原创 设计模式之生成器模式
例如上述的生成器对象和被构建的对象是分开的,那其实客户端可以直接使用 new 被构建对象的方式来创建产品对象,这样就导致生成器模式荒废了,所以我们可以将生成器对象合并到被构建的对象中去,称为它的一个内部类。假设我们现在需要一个 Mongo 客户端参数选项对象,来进行 Mongo 客户端的配置,那我们就可以定义一个客户端参选选项类,存放各种参数,并且将生成器定义为它的内部类,用来构建 Mongo 客户端参数选项对象。最后,客户端就选择特定的生成器实现类对象,传递给指导类对象,让它生产我们需要的产品对象即可。
2024-12-09 16:21:13
752
原创 一行Java代码实现两玩家交换装备
Exchanger 对象可理解为一个包含2个格子的容器,通过调用 exchanger 方法向其中的格子填充信息,当两个格子中的均被填充信息时,自动交换两个格子中的信息,然后将交换的信息返回给调用线程,从而实现两个线程的信息交换。Exchager 类可用于两个线程之间交换信息,如果一个线程调用了 Exchanger 对象的 exchange 方法之后,会一直阻塞直到另一个线程来和它交换信息,交换之后的信息返回给调用线程,从而实现两个线程的信息交换。Exchager 在遗传算法和管道设计等应用中是非常有用的。
2024-12-09 16:20:40
198
原创 并发限流利器【Semaphore】
如果是非公平锁,则不保证线程获得许可证的顺序,即使阻塞队列中有等待的线程,一个新调用 acquire 的线程会先尝试获取许可证,如果许可证数量不满足才插入队列中进行排队。即一个线程 a 调用 acquire 方法尝试获取许可时,这时刚好有线程 b 释放了许可,并唤醒阻塞队列中第一个等待的线程 b,此时线程a 和线程 b 会共同竞争释放出来的许可证,即线程 a 没有进阻塞队列等待就和线程 b 一起竞争许可证了。当然,当 semaphore 用于其他类型的同步控制的时候,非公平锁的吞吐量优于公平锁的。
2024-12-09 16:18:06
655
原创 微信小程序加密数据解密算法-Java实现
微信官方提供了多种编程语言的示例代码,但是目前下载的示例代码只有C++,Node,PHP,以及Python语言的,没有Java语言的,所以需要我们自己实现解密算法。Hutool是一个小而全的Java工具类库,封装了很多实用的静态方法,我们可以使用这个依赖包的相关工具类来简单封装,从而实现微信小程序加密数据的解密。这套加密算法是适用于微信小程序的绝大部分加密数据的,所以我们使用带有用户手机号的加密串,进行解密验证。注意,验证测试的时候,需要将以下三个变量的值替换为自己小程序的,不然会报错。
2024-12-09 16:16:26
526
原创 【无标题】
不过需要注意的是,只有当对象的状态会频繁变动或者在其生命周期内需要多次使用时,才考虑进行重用操作。运算符拼接字符串时,Java会在每次拼接时创建新的字符串对象,这种方式可能会对程序运行速度产生负面影响。在多线程编程环境中,同步操作可能会引发延迟现象,应仅在必要情况下使用同步,并确保同步块代码简洁。循环的编写方式对程序性能具有一定影响,在遍历列表时,若条件允许,优先选用索引循环方式。在Java编程过程中,当涉及字符串相加操作,特别是处于循环内部时,推荐使用。当需要对数据进行快速操作时,可考虑使用。
2024-12-09 16:06:37
301
原创 并发编程 13:Java线程池了解?
本文基于面试场景,对于Java线程池展开了解析,相信你如果能将本文的内容做到了然于心,以后面试碰到Java线程池这个问题就再也不会垂头丧气,而且胸有成竹。
2024-12-06 16:06:02
571
原创 并发编程 14:CompletableFuture异步编程没有那么难
在Java开发的web项目中,我们经常会遇到接口响应耗时过长,或者定时任务处理过慢,那在Java中最常见的解决方法就是并行了,想必大家也都不陌生了。今天的分享主要带大家从一个实际的串行场景出发,如何一步步优化,同时也会分享在Java中实现并行处理的多种方式,以及它们之间的区别和优缺点,通过对比总结更加深入的了解并且使用Java中并发编程的相关技术。今天大家学到了哪些知识呢?如何优化接口性能?某些场景下可以使用多线程并行代替串行。如何实现接口并行调用?
2024-12-06 16:05:05
1021
原创 外包干了一个月,技术明显进步
没办法,我找到了我在抖音集团的老哥,作为他的小老表,在他了解了我的情况后,直接甩给我一个网盘,说到:“去吧,这里有你需要的所有东西,不要来找我了,我都嫌丢人!(含:单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式,适配器模式,装饰器模式,代理模式等23种设计模式...)(含:mysql数据库基础知识,数据类型,失误,试图,mysql索引,mysql锁,mysql优化,等...)(含:Java概述,语法,面向对象,IO流,API,集合,NIO,HashMap,基础常见面试题....)
2024-12-06 16:03:08
1029
原创 Spring Boot 源码分析(二):SpringApplication和启动流程
文章主要对 Spring Boot 的源码进行分析,包括 SpringApplication 的创建和启动流程。介绍了 IOC 相关的 API 如 BeanFactory、ApplicationContext、Environment 等。在创建过程中,涉及判断应用类型、设置应用初始化器、事件监听器和确定主启动类。启动过程包括创建前准备、创建空容器、容器初始化、刷新容器、刷新后回调等步骤,并对每个步骤进行了详细阐述。
2024-12-06 16:01:40
644
原创 Spring Boot 源码分析(一):自动装配
至此,Spring Boot自动装配的源码分析了一下。本质就是通过采用Spring的@Import注解方式、@ConditionOnXXX系列注解、Spring SPI机制这三种方法实现了自动装配。源码设计的精巧有趣,跟一遍你会更好的利用Spring Boot这笔资源。
2024-12-06 16:00:21
1058
原创 【深入理解Java集合框架 - (3)】 | LinkedList
LinkedList是Java中常用的集合类之一,其核心价值有如下3高效的增删操作。充分利用内存空间。用作其他数据结构(如栈队列双端队列操千曲而后晓声,观千剑而后识器。虐它千百遍方能通晓其真意。链表是一种物理存储单元上非连续非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。LinkedList是java.util包中的一个类,它实现了List接口。基于双向链表实现,具备高效的增删操作的能力和充分利用内存空间,允许在运行时动态生成结点。高效的增删操作。充分利用内存空间。
2024-12-06 15:58:32
604
原创 【深入理解Java集合框架 - (2)】 | ArrayList
ArrayList是Java中最常用的集合类之一,其核心价值有如下4高效的随机访问。自动扩容机制。自动调整数组大小。灵活的增删改查及遍历操作。操千曲而后晓声,观千剑而后识器。虐它千百遍方能通晓其真意。ArrayList是java.util包中的一个类,它实现了List接口。基于动态数组实现,具备高效的随机访问能力和自动扩容机制,允许在运行时调整数组大小。size:逻辑大小,控制数组内有效元素的个数。capacity:容量,和JDK中的容量一致。:静态数组,先使用简单的int类型实现。
2024-12-06 15:56:42
606
原创 【深入理解Java集合框架 - (1)】 | 数组
想要深入理解一个事物,关键在于理解它的价值和作用。当你明白它的重要性和缺失的弊端时,自然会产生学习的兴趣。死记硬背API和知识点只能停留在表面,而深入理解其核心价值才能真正掌握精髓。数组是Java世界的基石之一,其核心价值有如下3存储和处理大量相同类型的数据。高效的随机访问和实现其他数据结构(如ArrayListHashMap等)。算法的基础(如排序查找)都是基于数组进行操作的。操千曲而后晓声,观千剑而后识器。虐它千百遍方能通晓其真意。在计算机科学中,数组数据结构(),简称数组Array),是由。
2024-12-06 15:53:52
950
原创 (九)MySQL之MVCC机制:为什么你改了的数据我还看不见?
MVCC多版本并发控制,听起来似乎蛮高大上的,但实际研究起来会发现它并不复杂,其中的多版本主要依赖Undo-log日志来实现,而并发控制则通过表的隐藏字段+ReadView快照来实现,通过Undo-log日志、隐藏字段、ReadView快照这三玩意儿,就实现了MVCC机制,过程还蛮简单的~到这里,其实对于MySQL的事务隔离机制,已经拨开一部分迷雾了,下篇《MySQL事务与锁机制原理篇》中,则会彻底讲清楚MySQL锁是怎么实现的,以及不同的事务隔离级别,又是如何借助锁+MVCC处理客户端SQL。
2024-12-06 15:41:39
917
原创 (八)MySQL锁机制:高并发场景下该如何保证数据读写的安全性?
看到这里,相信大家对MySQL中提供的锁机制有了全面的认识,但以目前情况而言,虽对每种锁类型有了基本认知,但本篇的内容更像一个个的点,很难和连成线,而对于这块的具体内容,则会放在后续的《事务与锁机制的实现原理篇》中详细讲解,在后续的原理篇中再将这一个个知识点串联起来,因为想要真正弄懂MySQL事务隔离机制的实现,还缺少了一块至关重要的点没讲到:即MVCC机制。因此会先讲明白数据库的MVCC多版本并发控制技术的实现后,再去剖析事务隔离机制的实现。
2024-12-06 15:38:43
903
原创 全网最全的Java面试场景题,终于整理好了
工厂模式:BeanFactory 就是简单工厂模式的体现,用来创建对象的实 例。单例模式:Bean 默认为单例模式。代理模式:Spring 的 AOP 功能用到了 JDK 的动态代理和 CGLIB 字 节码生成技术。模板方法:用来解决代码重复的问题。比如:RestTemplate, JmsTemplate, JpaTemplate。观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如 Spring 中。
2024-12-05 15:25:32
3843
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人