标签: Java

Qbian | 1周前 | 后端相关Java

破解遗留系统重构问题的 6 步心法

本文由极客时间整理自 Thoughtworks DTO Advisory 黄俊彬在 [QCon+ 案例研习社](https://link.zhihu.com/?target=https%3A//time.geekbang.org/qconplus/home)的演讲[《MV\ 模式重构演进》](https://link.zhihu.com/?target=https%3A//time.geekbang.org/qconplus/detail/100110437) 你好,我是 Thoughtworks 团队的技术教练黄俊彬,目前主要在智能硬件、通讯互联网、金融等领域企业提供敏捷转型、系统架构改造以及大型遗留系统重构等服务。今天给你分享的话题是 MV 模式的重构演进。 我会从以下四个部分来分享,第一部分给大家分享遗留系统典型特征,介绍这类系统的特征以及对团队的影响。第二部分是 MV\ 模式重构的策略,针对这类系统里面的一些特征,我们有哪些重构的...

 101 |  1 |  0 后端相关Java

他在笑_1 | 2周前 | RedisJava

Redis "高级"应用场景 -- 限流、延时队列、幂等处理

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 6 天,[点击查看活动详情][Link 1] 🍳引言 自Redis入门篇过后,已经好久没更Redis了,接下来应该从实战篇,原理篇,面试篇几个层次来展开,本篇主要是实战篇环节,以问题展开,应对面试场景作答【melo称其为"手撕面答"】,尽量简短,某些部分可能不会进行详细介绍。 emmm,但后边有些部分还是干脆整合在一起了,可观性好一点,不至于看得一头雾水 🎨本篇脑图速览 🎯🎈Redis限流是怎么做的? 固定窗口计数 固定窗口计数是指,假设我们的限流规则是:1min内最多只能访问10次,那么固定窗口就是固定了【 1min-2min】这个窗口内,只能有10次访问 ,相应的我们就要给这个窗口维护一个计数器。 为了节省空间,其实我们不需要维护一个个窗口,只需要维护当前访问时间所在的窗口即可,以及对应的计数...

 129 |  3 |  0 RedisJava

Qbian | 2个月前 | 后端相关Java

CountdownLatch 和 CycliBarriar 有什么区别?

1、CountdownLatch 先来看CountDownLatch,它是一个组合词。CountDown 的意思是 倒计时,Latch 的意思是 门闩 ,也被翻译成发令枪。在JDK 注释中是这样的: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes。 翻译过来就是说,让一个或多个线程持续等待,直到其他多线程执行的一组操作全部完成以后,这些等待的线程才会继续执行。 就好比是,有多位选手参加一场百米赛跑,裁判员需要等待全部选手就绪,并且在同一起跑线上。然后,裁判会发出号令:“各就位,预备跑”,随着发令枪响,所有选手才能全部起跑。在这个场景中,各位参赛选手就是线程,而裁判就是CountDownLatch。 我们在实际开发中,有以下两个使用场景可以用CountDownLatch来实现: (1)让单个线程等待多个线程的场景。 比如,一个服务需要从多个远程接口获取...

 270 |  1 |  4 后端相关Java

Qbian | 2个月前 | 后端相关Java

Executor框架

一、Executor框架的作用 Executor是线程池的调度工具,线程池是Executor的一部分 二、Executor框架的结构 Executor框架由三大部分组成 1、 任务 :即被执行任务需要实现的接口: Runnable 接口或 Callable 接口 2、 线程池 :主要通过 ExecutorService 接口调用线程池,有2个关键实现类 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 3、 异步计算的结果 : Future 接口及其实现类 FutureTask 三、Executor框架的执行过程 -------------------------- 1、通过实现Runnable接口或Callable接口创建任务 2、通过Executors的工厂方法创建线程池 3、通过ExecutorService.submit()提交一个有返回结果的任务,返回类型为一个实现Future接口的对象;或通过ExecutorService.execute()方法执...

 266 |  0 |  0 后端相关Java

Qbian | 2个月前 | 后端相关Java

在JVM中,为什么要把堆与栈分离?栈不是也可以存储数据吗?

(1)从软件设计的角度来看,栈代表了处理逻辑,而堆代表了数据,这样分离使得处理逻辑更为清晰。这种 隔离、模块化的思想 在软件设计的方方面面都有体现。 (2)堆与栈的分离,使得堆中的内容可以被多个栈共享。这种共享有很多好处,一方面提供了一种有效的数据交互方式(如 内存共享 ),另一方面,节省了内存空间。 (3)栈因为运行时的需要(如保存系统运行的上下文),需要进行址段的划分。由于栈只能向上增长,因此会限制住栈存储内容的能力。而堆不同,堆的大小可以根据需要动态增长。因此,堆与栈的分离,使得 动态增长 成为可能,相应栈中只需要记录堆中的一个地址即可。 (4) 堆和栈的完美结合就是面向对象的一个实例 。其实,面向对象的程序与以前结构化的程序在执行上没有任何区别,但是面向对象的引入使得对待问题的思考方式发生了改变,是更接近于自然的思考方式。当把对象拆开会发现,对象的属性其实就是数据,存放在堆中,而对象的方法就是处理逻辑,存放在栈中。我们编写对象的时候,其实即编写了数据结构,也编写了处理数据的逻辑。 总结:栈主要用来执行程序,堆主要用来存放对象,为栈提供数据存储服务。 也正是因为堆与栈分...

 247 |  0 |  0 后端相关Java

Qbian | 2个月前 | 后端相关Java

堆中存什么?栈中存什么?

      堆中存的是 对象 。栈中存的是 基本数据类型 和 堆中对象的引用 。一个对象的大小是不可估计的,或者说是可以动态变化的,但是在栈中,一个对象只对应了一个4btye的引用(堆栈分离的好处:))。 为什么不把基本类型放堆中呢?因为其占用的空间一般是1 8个字节——需要空间比较少,而且因为是基本类型,所以不会出现动态增长的情况——长度固定,因此栈中存储就够了,如果把他存在堆中是没有什么意义的(还会浪费空间,后面说明)。可以这么说,基本类型和对象的引用都是存放在栈中,而且都是几个字节的一个数,因此在程序运行时,他们的处理方式是统一的。但是基本类型、对象引用和对象本身就有所区别了,因为一个是栈中的数据一个是堆中的数据。最常见的一个问题就是,Java中参数传递时的问题。

 218 |  0 |  0 后端相关Java

客栈小K | 2022-07-28 | 前端相关VueJava

思考vue3和react18的区别

前言 个人认为框架的初衷是带给开发者更好的开发体验,更快的性能,更简单的操作。 vue3 和 react18 都是最新的框架版本,两者虽然底层原理和思想不同,但是更多的是相同之处,比如都是声明式的,一般多用于 spa ,都用 hooks 来逻辑复用等等 用vite初始化vue3和react18项目 ----------------------------- pnpm create vite 然后删除无用的代码之后,再改造成同样功能的HelloWorld组件,这个组件做如下事情: 定义数据 count ,点击按钮可以是 count+1 ,页面也会响应式改变; 还有一个监听数据改变,在控制台打印改变的数据; 有一个数组 ['apple', 'orange', 'pear'] ,用于列表渲染到页面。 ![image-20220727144746261....

 475 |  1 |  0 前端相关Vue

但丁. | 2022-06-29 | RedisJava

自定义注解防止重复提交

场景:假设多个人同时点击或者单人多次点击导致并发请求,存在幂等性问题,我们可通过redis加锁来控制并发处理。 创建注解类 lockTime用作扩展属性,可供不同业务场景进行不同时间设置 创建切面类 @Aspect 定义切面类 @Around 定义切入逻辑处理 可根据当前路径+登录人token控制并发限制,写入redis超时设置。 ![e97dc4...

 308 |  5 |  2 RedisJava

努力努力再努力s | 2022-06-28 | Spring 全家桶Java

SpringBoot如何在启动后执行初始化配置

SpringBoot初始化项目后执行初始化配置 方案一 自定义类实现CommandLineRunner接口,重写run()方法 代码实现 java / @author :Shuker @date :Created in 2022/4/12 10:05 @description:初始化方法 @version: 1.0 / @Slf4j @Component @Order(2) public class initMethod implements CommandLineRunner { @Override public void run(String... args) throws Exception { log.info(" 初始化 {}",projectRunner()); } public static String projectRunner(){ return "项目启动后初始化配置...."; } } 方案二 自定义类实现A

 322 |  4 |  8 Spring 全家桶Java

被发现了 | 2022-06-23 | 后端相关Java

关于配置七牛的注意事项

配置七牛之后发现,图片可上传到云服务器但是浏览时打不开图片 原因如下:Domain设置http://域名/ 一定在最后加上/才行 小注意事项,不确定都是这个原因

 195 |  0 |  0 后端相关Java

Qbian | 2022-06-08 | 后端相关Java

JVM主要组成部分及其作用

一、JVM主要组成部分及其作用 JVM包含两个子系统和两个组件,两个子系统为Class loader(类装载器)、Execution engine(执行引擎);两个组件为Runtime data area(运行时数据区)、Native Interface(本地库接口)。 Class loader(类加载器):根据给定的全限定名类名(如:java.lang.Object)来装载class文件到运行时数据区中的方法区; Execution engine(执行引擎):执行引擎也叫解释器,负责解释命令,交由操作系统执行; Native Interface(本地接口):与native libraries交互,是其它编程语言交互的接口。 Runtime data area(运行时数据区域):这就是我们常说的JVM的内存,...

 501 |  1 |  0 后端相关Java

Qbian | 2022-06-08 | 后端相关Java

并发容器的实现

何为同步容器:可以简单地理解为通过synchronized来实现同步的容器,如果有多个线程调用同步容器的方法,它们将会串行执行。比如Vector,Hashtable,以及Collections.synchronizedSet,synchronizedList等方法返回的容器。 可以通过查看Vector,Hashtable等这些同步容器的实现代码,可以看到这些容器实现线程安全的方式就是将它们的状态封装起来,并在需要同步的方法上加上关键字synchronized。 并发容器使用了与同步容器完全不同的加锁策略来提供更高的并发性和伸缩性,例如在ConcurrentHashMap中采用了一种粒度更细的加锁机制,可以称为分段锁,在这种锁机制下,允许任意数量的读线程并发地访问map,并且执行读操作的线程和写操作的线程也可以并发的访问map,同时允许一定数量的写操作线程并发地修改map,所以它可以在并发环境下实现更高的吞吐量。

 404 |  1 |  0 后端相关Java

Qbian | 2022-06-07 | 后端相关Java

Future和Callable的使用总结

在默认的情况下,线程Thread对象不具有返回值的功能,如果在需要取得返回值的情况下是极为不方便的,但在Java1.5的并发包中可以使用Future和Callable来使线程具有返回值的功能。 1.Future和Callable的介绍 接口Callable与线程功能密不可分,但和Runnable的主要区别为: (1) 接口Callable的call()方法可以有返回值,但Runnable接口的run()方法没有返回值。 (2) Callable接口的call()方法可以声明抛出异常,而Runnable接口的run()方法不可以声明抛出异常。 执行完Callable接口中的任务后,返回值是通过Future接口进行获得的。 2.方法get()结合ExecutorService中的submit(Callable<T )的使用 方法submit(Callable<T )可以执行参数为Callable的任务,方法get()用于获得返回值,示例如下: java package mycallable; import java.util.concurrent.

 602 |  0 |  0 后端相关Java