自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

frozenpenguin的博客

冰冻三尺,非一日之寒;水滴石穿,非一日之功。

  • 博客(129)
  • 收藏
  • 关注

原创 「 高并发系统设计 」海量数据下未读数系统的设计与实现

在上一篇文章「 高并发系统设计 」基于海量数据计数器的设计与实现中,我们了解到了一套支撑高并发访问和存储大数据量的通用计数系统。我们通过缓存技术、消息队列技术以及对于 Redis 的深度改造,就能够支撑万亿级计数数据存储以及每秒百万级别读取请求了。然而有一类特殊的计数并不能完全使用我们提到的方案,那就是未读数。

2023-12-05 17:46:01 308

原创 「 高并发系统设计 」基于海量数据计数器的设计与实现

对于初级阶段的计数系统,数据库与缓存的方案是可行的,并能够支撑中小访问量和存储量的需求。特别是通过对原生 Redis 组件的改造,我们能够显著减小存储数据的内存开销。

2023-12-05 10:00:00 217

原创 「 高并发系统设计 」如何用好消息队列?

高并发系统设计的三个核心目标:性能、可用性和可扩展性。在性能方面,我们一直聚焦于系统的查询性能,主要原因在于我们通常遇到的场景都是读多写少的,尤其是在系统的初期。举例来说,在社区系统初期,可能只有少量种子用户在生成内容,而大多数用户处于“围观”状态。在这个阶段,整体流量相对较小,写流量可能只占整体流量的百分之一。因此,即使整体查询每秒达到 10000 次,写请求也只有每秒 100 次,优化写请求的性能可能并不是最高效的选择。然而,随着业务的发展,可能会遇到一些高并发写请求的场景,比如秒杀抢购活动。

2023-11-30 09:30:00 181

原创 「 高并发系统设计 」 如何提高系统性能

高性能是系统设计的灵魂所在。它意味着系统能够处理更多的用户并发请求,背后承载着对系统响应时间的极致追求。想象一下,每秒一次请求和每秒一万次请求,两者之间的差距,不仅仅是数字上的增长,更是用户体验上的天壤之别。可用性是系统正常服务用户的时间,它直接关系到用户对系统的信赖度。全年不停机、无故障,这是用户对一个高可用系统的期待。在设计阶段就考虑系统的稳定性,是实现高可用的关键一步。可扩展性是面对峰值流量时系统的自我调整能力。

2023-11-24 08:30:00 237

原创 「 系统设计 」 为什么要做架构分层?

分层架构是一种将系统划分为多个层次的设计模式,每个层次专注于特定的功能。这样的设计使得系统的不同部分能够更好地组织和管理,从而提高了系统的可维护性、可扩展性和可理解性。

2023-11-23 16:00:00 1292 1

原创 【东软实训Day04】Java UDP通信

UDP是传输层的协议,该协议主要为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法,功能即为在IP的数据报服务之上增加了最基本的服务:复用和分用以及差错检测。

2023-09-08 14:47:46 267 1

原创 【东软实训Day3】Servlet

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。

2023-09-08 14:47:01 153

原创 【东软实训Day2】用Java实现客户端与服务器交互

1个应用 = 1个服务器进程 + 1…N个客户端进程,其中服务器管理资源,并通过操作这种资源为客户端服务。客户端-服务器模型中的基本操作是事务(transaction)(注:不同于数据库中的transaction)。Step1:客户端向服务器发送一个请求,发起一个事务;Step2:服务器收到请求后,进行解释,并以适当的方式操作它的资源;Step3:服务器给客户端发送一个响应,并等待下一个请求;Step4:客户端收到响应并处理。

2023-09-08 14:46:29 302

原创 【东软实训Day1】多线程

在谈及多线程之前先简单提及一下进程与线程。进程是程序的一次执行过程。线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程中可以并发多个线程,一个线程只能属于一个进程。

2023-09-08 14:45:57 122

原创 为什么ConcurrentHashMap不允许插入null值而HashMap可以?

在Java中,我们通常使用Map来存储键值对数据,而ConcurrentHashMap作为一个高效的线程安全的Map,其使用在并发场景下非常广泛。但是,ConcurrentHashMap有一个特殊的限制,那就是它不允许key或value为null,这与普通的HashMap有所不同。

2023-07-20 16:44:56 636

原创 「 Redis入门 」Redis和MySQL的差异?

Redis和MySQL在多个方面存在明显的差异。Redis适用于需要快速读写操作和较小数据集的场景,如缓存、会话管理和实时排行榜。它以内存存储和多种数据结构支持为特点,具有出色的性能表现。相比之下,MySQL适用于需要处理大量结构化数据、进行复杂查询和支持事务处理的应用程序。它使用磁盘存储数据,并提供了丰富的SQL查询语言和ACID事务支持。无论选择Redis还是MySQL,都应根据具体的需求和应用场景来做出决策。对于需要高性能、灵活的键值对存储和简单查询的场景,Redis是一个优秀的选择。

2023-07-12 09:13:28 555 1

原创 「 MySQL 入门」使用联表查询代替子查询的原因(附案例分析)

子查询的执行顺序是先执行子查询,然后将其结果作为外部查询的条件或数据源。传统的子查询是一种常见的解决方案,但随着数据量和复杂性的增加,使用联表查询来替代子查询的方式变得越来越受欢迎。通过减少查询次数、优化查询计划、减少数据传输和利用索引优化,使用联表查询代替子查询可以显著提高数据库查询的性能和效率。通过将子查询放在联表查询的子查询中,我们可以更清晰地表达查询意图,并帮助优化器生成更优化的执行计划。子查询在某些场景下是非常有用的,比如在查询满足一定条件的行时,可以使用子查询来过滤结果集。

2023-07-06 15:59:44 1237

原创 「计算机网络」HTTP1.0、HTTP1.1和HTTP2.0的演变

本文首先整体概述了一遍HTTP各版本功能的演变,说明了学习不同版本HTTP协议有助于把握技术发展的方向;其次从简化版的HTTP网络请求入手,介绍了各个环节对请求的影响,提出了影响网络请求的两个因素——带宽和延迟;

2023-05-16 14:08:02 641 1

原创 「 操作系统 」CPU缓存一致性协议MESI详解

说回CPU缓存,缓存行(cache line)是CPU缓存的基本单位,缓存行通常是 32/64 字节,前面说了局部性原理。当我们访问一个数据时,获取一个值后,其相邻的值也被缓存到就近的缓存行中。比如访问一个long类型数组,当数组中的一个值被加载到缓存中,它会额外加载另外7个,以致你能非常快地遍历这个数组。因此可以非常快速的遍历在连续的内存块中分配的任意数据结构。但是没有任何是完美的存在,比如:当有多个线程操作不同的成员变量,但正好这多个变量处于相同的缓存行。

2023-05-15 07:30:00 3487 1

原创 「 计算机网络 」Cookie、Session、Token、JWT 原理详解

本文介绍了 Web 开发中常见的几种认证方式,包括 Cookie、Session、Token 和 JWT。其中,Cookie、Session 和 Token 都是客户端存储在浏览器中的认证方式,而 JWT 是基于 JSON 格式的消息令牌,可以在不同的编程语言和应用程序之间进行互操作。在分布式场景下,JWT 更加安全和可靠,因为它包含了头部信息和数字签名等保护机制。此外,文章还介绍了 SSL/TLS 和 OAuth2 等认证协议,它们可以用于保护 Web 应用程序之间的通信安全和授权访问。

2023-05-14 11:28:19 598

原创 「 Redis 」大key对持久化有什么影响?

当 AOF 写回策略配置了 Always 策略,如果写入是一个大 Key,主线程在执行 fsync() 函数的时候,阻塞的时间会比较久,因为当写入的数据量很大的时候,数据同步到硬盘这个过程是很耗时的。AOF 重写机制和 RDB 快照(bgsave 命令)的过程,都会分别通过fork()函数创建一个子进程来处理任务。创建子进程的途中,由于要复制父进程的页表等数据结构,阻塞的时间跟页表的大小有关,页表越大,阻塞的时间也越长;

2023-05-06 17:34:59 1026

原创 「 计算机网络 」TCP的粘包拆包问题

当我们在进行网络传输时,由于各种原因,数据包的发送和接收可能会出现粘包和拆包的问题。粘包和拆包都是数据分组错误的情况,其中粘包指的是多个数据包被合并成一个,而拆包则是一个数据包被拆成了多个数据包。这些问题会导致数据的解析和处理变得困难,进而影响整个系统的稳定性和可靠性。TCP协议是一种面向连接、可靠的传输协议,在网络传输中被广泛应用。TCP采用了一系列机制来解决粘包和拆包问题,保证数据的可靠传输。本文将介绍TCP协议如何解决粘包和拆包问题,让读者更深入地了解TCP协议的传输特点和实现方式。

2023-04-27 15:28:47 1937

原创 「 Redis 」RDB和AOF持久化全面解析

在现代的互联网应用中,数据的持久化和可靠性是至关重要的。在 Redis 中,RDB 和 AOF 两种持久化方式可以确保数据的持久化和可靠性。但是,这两种方式各有优缺点,需要根据具体的业务场景和需求来选择。本文将全面解析 RDB 和 AOF 持久化的原理、使用方法、优缺点以及如何进行配置和调优。无论你是 Redis 的初学者还是有一定经验的开发者,都能从本文中获得有益的知识和实践经验,帮助你更好地使用 Redis。

2023-04-26 08:21:51 954

原创 「 计算机网络 」HTTP和RPC的区别与联系

HTTP(Hypertext Transfer Protocol)(超文本传输协议)是一种用于传输超媒体文档(例如HTML)的应用层协议。它是Web应用程序开发中最常用的协议之一,也是互联网上数据交换的基础。HTTP使用TCP/IP协议作为其传输层协议,主要用于Web浏览器和服务器之间的通信,以及在移动应用程序和Web服务之间进行数据交换。HTTP 协议规定了浏览器和服务器的一种通信格式,让任何浏览器和服务器都可以以这种形式正常交流,比如:数据传输通常是基于 TCP/IP 协议的。

2023-04-20 08:35:34 1316

原创 「 JVM 」常见的垃圾收集器Garbage collector(GC)

垃圾收集机制是 Java 的招牌能力,极大地提高了开发效率。这当然也是面试的热点。那么,Java 常见的垃圾收集器有哪些?GC 垃圾收集器是和 JVM 一脉相承的,它是和 JVM 进行搭配使用,在不同的使用场景对应的收集器也是有区别垃圾回收器发展史有了虚拟机,就一定需要收集垃圾的机制,这就是 Garbage Collection,对应的产品我们称为 Garbage Collector。1999年随JDK 1.3.1 一起来的是串行方式的 SerialGc,它是第一款 GC。

2023-04-17 08:08:36 1094

原创 「 JavaSE 」说说什么是泛型的类型擦除?

Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。先看一道常见的面试题,下面的代码的执行结果是什么?首先,我们知道getClas方法获取的是对象运行时的类(Class),那么这个问题也就可以转化为和的对象在运行时对应的Class是否相同?

2023-04-14 13:22:46 1112

原创 「 分布式技术 」一致性哈希算法(Hash)详解

在分布式系统中,数据的存储和访问是很重要的问题。为了提高系统的可用性和扩展性,常常需要将数据分布到不同的节点上,而且这些节点也可能会动态地加入或离开集群。一致性哈希算法就是一种常用的解决方案,它可以解决节点的动态变化和负载均衡的问题。本文将深入探讨一致性哈希算法的底层原理,包括其基本思想、关键步骤以及优缺点等,同时结合实际场景进行举例说明。一致性哈希算法是一种用于分布式系统中的数据分片和负载均衡的算法。它将整个哈希空间划分为一个环,并且每个节点在这个环上都有一个对应的位置。

2023-04-12 08:32:50 4420 1

原创 「 Java并发编程 」 线程停止的方式

在Java中,线程暂停是一种常见的操作,它可以使一个线程暂停执行一段时间,然后再继续执行。这种操作主要用于控制线程的运行状态和调度。线程暂停可以通过多种方式实现,例如:使用Thread.sleep()方法、使用Object.wait()方法等。不同的线程暂停方式适用于不同的场景,开发者需要根据具体情况选择合适的方式。在本篇博文中,我们将会介绍Java中常用的线程暂停方式以及它们的应用场景。

2023-04-11 07:30:00 2547

原创 「 操作系统 」聊聊进程调度算法

进程调度算法是操作系统中非常重要的一部分,它决定了操作系统中各个进程的执行顺序和时间片。在单核CPU下,任何时刻都只可能有一个程序在执行,比如正在计算1*2这个程序A,那么就不能运行1+…+n这个求和程序B,这个时候程序A处于执行状态,而程序B处于非执行状态。我们在任意时刻到底是执行哪个程序呢?我们运行的地铁列车,有指挥中心统一控制调度,到底由哪些地铁执行哪一天的任务,这是因为轨道等资源有限,不可能全放进去。类似到进程调度,CPU等硬件资源有限,也不可能全部一起执行。这就引出了我们的进程调度。

2023-04-08 11:34:31 4228

原创 「 JavaSE 」String、StringTable、String.intern()详解

Java中的字符串(String)是一种不可变对象,它在许多应用程序中扮演着重要角色。为了更有效地处理和操作字符串,Java提供了一些有用的工具和方法,如StringTable和String.intern()。StringTable是String类内部使用的一种高效机制,它允许JVM共享相同的字符串以节省内存。String.intern()允许将字符串添加到StringTable中,并返回指向该字符串的引用。这两个工具都非常有用,但也需要小心使用,因为它们可能会导致内存问题或性能问题。

2023-04-05 11:07:34 1091

原创 「 Redis 」 SkipList 跳表底层实现及应用

跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其它节点的指针,从而达到快速访问节点的目的。和链表、字典等数据结构被广泛地应用在 Redis 内部不同,Redis 只在两个地方用到了跳跃表,一个是实现有序集合健,另一个是在集群节点中用做内部数据结构,除此之外,跳跃表在 Redis 里没有其它用途。我们来想一下,为啥 Redis 中这两个场景要选择 skiplist?如果该序列用支持随机访问的线性结构(数组)存储,那么我们很容易地用二分查找来做。

2023-04-04 07:30:00 963

原创 「 Redis 」缓存过期策略及内存淘汰策略

在计算机科学中,缓存是一种优化技术,用于提高系统的性能。通过将经常访问的数据存储在快速访问的介质(如快速内存)中,可以减少读取慢速存储介质(如硬盘)的次数,从而加快了程序的响应时间。然而,缓存也带来一个问题:缓存中存储的数据可能会过期或变得不再有用。为了解决这个问题,我们需要使用缓存淘汰策略。这些策略控制着缓存中哪些数据应该被删除以及何时删除它们。除了缓存淘汰策略之外,内存淘汰机制也是一个重要的概念。当缓存满了并且新数据需要被添加到缓存中时,缓存中的旧数据必须被替换。

2023-04-03 09:13:51 1408 1

原创 解决Hash(哈希表)冲突的四种方案

哈希是一种通过对数据进行压缩, 从而提高效率的一种解决方法,但由于哈希函数有限,数据增大等缘故,哈希冲突成为数据有效压缩的一个难题。本文主要介绍哈希冲突、解决方案,以及各种哈希冲突的解决策略上的优缺点。哈希冲突即不同key值产生相同的地址,即发生了hash冲突。一般来说,哈希冲突是无法避免的,所以就有了解决方案。常见的解决Hash冲突的方案有开放寻址法、链地址法和再哈希法。

2023-04-02 11:25:41 8365

原创 「操作系统」彻底理解零拷贝Zero-Copy技术

早期 I/O 操作,内存与磁盘的数据传输的工作都是由 CPU 完成的,而此时 CPU 不能执行其他任务,会特别浪费 CPU 资源。于是,为了解决这一问题,DMA 技术就出现了,每个 I/O 设备都有自己的 DMA 控制器,通过这个 DMA 控制器,CPU 只需要告诉 DMA 控制器,我们要传输什么数据,从哪里来,到哪里去,就可以放心离开了。后续的实际数据传输工作,都会由 DMA 控制器来完成,CPU 不需要参与数据传输的工作。

2023-03-31 10:14:09 1114

原创 「 JVM 」 图解三色标记算法(增量更新与原始快照的实现)

在说 JVM 的三色标记算法之前,我们先来说下 JVM 对于常见对象存活判定算法与垃圾收集算法。常见对象存活判定算法有引用计数算法和可达性分析算法。引用计数法会产生循环引用问题,JVM 默认是通过可达性分析算法来判断对象是否存活的。标记-清除、标记-复制、标记-整理算法以及在此基础上的分代收集算法(新生代/老年代),每代采取不同的回收算法,以提高整体的分配和回收效率。这些垃圾收集算法首先做的都是通过可达性分析算法。

2023-03-30 07:15:00 1706

原创 「计算机网络」浅谈HTTP和HTTPS、HTTP2(概述、区别与联系)

HTTP(HyperText Transfer Protocol),即超文本运输协议,是实现网络通信的一种规范在计算机和网络世界有,存在不同的协议,如广播协议、寻址协议、路由协议等等…而HTTP是一个传输协议,即将数据由A传到B或将B传输到A,并且 A 与 B 之间能够存放很多第三方,如: AXYZB传输的数据并不是计算机底层中的二进制包,而是完整的、有意义的数据,如HTML 文件, 图片文件, 查询结果等超文本,能够被上层应用识别在实际应用中,HTTP常被用于在Web。

2023-03-29 12:18:16 1877

原创 「 计算机网络 」说说TCP和UDP的区别及其应用场景

基于字节流传输的数据没有长度限制,就像一根无限长的水管一样,数据可以源源不断的从通信的一端流向另一端,发送端可以逐个字节的向数据流中写入数据,接收端也可以逐个字节的从数据流中读出数据。当你下载文件时,希望获得的是完整的文件,而不仅仅是文件的一部分,因为如果数据丢失或乱序,都不是你希望得到的结果,于是就用到了TCP。TCP/IP 是互联网相关的各类协议族的总称,比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 族内的协议。,处于IP协议的上一层。

2023-03-28 13:07:51 3377

原创 「 MySQL 」InnoDB和MyISAM的区别与联系

在MySQL数据库中,InnoDB和MyISAM是两种主要的存储引擎。存储引擎是MySQL中最底层的组件,负责管理数据的存储和检索。不同的存储引擎具有不同的特性和适用场景。本文将重点探讨InnoDB和MyISAM两种存储引擎的区别与联系。比较项InnoDBMyISAM存储引擎类型事务型存储引擎,支持事务和行级锁不支持事务和行级锁的非事务型存储引擎并发控制机制采用多版本并发控制 (MVCC) 和行级锁采用表级锁并发控制机制索引结构采用 B+ 树 分类索引采用 B+ 树 分类索引。

2023-03-27 07:30:00 1318

原创 「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)

死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。

2023-03-26 14:10:52 2498

原创 「操作系统」全面剖析进程、线程、协程(区别与联系)

我们都知道计算机的核心是CPU,它承担了所有的计算任务;而操作系统是计算机的管理者,它负责任务的调度、资源的分配和管理,统领整个计算机硬件;应用程序则是具有某种功能的程序,程序是运行于操作系统之上的。

2023-03-25 17:24:18 1273

原创 「 JVM 」Java虚拟机是如何判断对象是否死亡的?

我们都知道Java和C++有一个非常大的区别就是Java有自动的垃圾回收机制,经过半个多世纪的发展,Java已经进入了“自动化”时代,让使用者只需要注重业务逻辑的开发而不需要担心内存的使用情况。那么我们为什么还要学习Java的垃圾回收机制呢?原因很简单:我们不想止于“增删改查工程师”这样的初级水平,一旦程序发生了内存溢出、内存泄漏等问题时,我们可以用已掌握的知识更好的调节和优化我们的代码。方法区、Java堆、虚拟机栈、本地方法栈、程序计数器。试想一下,GC(垃圾回收机制)在清理内存的时候第一件事要做什么。

2023-03-23 14:35:05 1221

原创 「操作系统」什么是用户态和内核态?为什么要区分

简单来说内核态就是操作系统运行线程,用户态就是线程执行用户自己的程序。用户态不能直接使用系统资源,也不能改变 CPU 的工作状态,并且只能访问这个用户程序自己的存储空间!内核态系统中既有操作系统的程序,也有普通用户程序。为了安全性和稳定性,操作系统的程序不能随便访问,这就是内核态。即需要执行操作系统的程序就必须转换到内核态才能执行内核态可以使用计算机所有的硬件资源为什么要区分用户态和内核态?在CPU的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃。比如:清内存、设置时钟等。

2023-03-20 08:29:03 7052

原创 「操作系统」进程间的通信方式全面解析

匿名管道顾名思义,它没有名字标识,匿名管道是特殊文件只存在于内存,没有存在于文件系统中,shell 命令中的「」竖线就是匿名管道,通信的数据是无格式的流并且大小受限,通信的方式是单向的,数据只能在一个方向上流动,如果要双向通信,需要创建两个管道,再来匿名管道是只能用于存在父子关系的进程间通信,匿名管道的生命周期随着进程创建而建立,随着进程终止而消失。命名管道。

2023-03-16 10:16:21 3213 2

原创 「并发编程技术」线程池中各参数含义及具体执行流程

线程池是为了避免线程频繁的创建和销毁带来的性能消耗,而建立的一种池化技术,它是把已创建的线程放入“池”中,当有任务来临时就可以重用已有的线程,无需等待创建的过程,这样就可以有效提高程序的响应速度。但如果要说线程池的话一定离不开。

2023-03-15 09:33:47 1301

原创 「分布式技术」分布式锁的最佳实践

在传统的单体服务中,我们经常会遇到多线程对于单一资源的抢占导致的线程安全问题以及对数据库数据操作的一致性问题,如果是在单体系统中,我们可以很方便的使用编程语言提供的锁以及数据库事务来解决这些问题。

2023-03-13 12:48:22 1226

空空如也

空空如也

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

TA关注的人

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