自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

大厂小码农的博客

分享后端技术栈、计算机底册、数据结构和算法、网络等~~~

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

原创 图解Redis 07 | HyperLogLog数据类型的原理及应用场景

Redis HyperLogLog 是从 Redis 2.8.9 版本开始引入的一种数据结构,主要用于“基数统计”,即统计数据集中不重复元素的数量。需要注意的是,HyperLogLog 的统计结果是基于概率的,因此不能保证完全准确,其标准误差约为 0.81%。简单来说,HyperLogLog 提供了一种估算不重复元素数量的方法,这种方法在数据量非常大的情况下也能保持较小的内存消耗。

2024-10-30 11:30:00 805 1

原创 图解Redis 08 | GEO数据类型的原理及应用场景

在我们的日常生活中,我们越来越依赖于位置服务(Location-Based Service, LBS),例如查找附近的商场、餐厅,或者在出行时使用打车软件。这些服务都离不开精确的地理位置信息。LBS应用主要是根据目标人物或物体相关的一组经纬度等地理位置信息,然后根据这些经纬度数据查询目标附近的位置。Redis GEO 就是专门用于存储和操作地理位置信息的数据类型,它是 Redis 3.2 版本新增的功能,提供了高效的方式来处理和查询这些地理位置信息。

2024-10-30 11:30:00 1322

原创 图解Redis 06 | Hash数据类型的原理及应用场景

Hash 类型特别适合存储对象,例如用户信息等。

2024-10-29 07:44:07 1158

原创 图解Redis 05 | Zset数据类型的原理及应用场景

Zset 类型(有序集合)与 Set 类型相比,增加了一个排序属性 score。对于有序集合 Zset,每个元素由两个部分组成:一个是元素的值,另一个是用于排序的分数 score。有序集合继承了Set中成员唯一(元素值不能重复,分数可以重复)的特性,但不同之处在于,有序集合中的元素是按分数进行排序的。

2024-10-29 07:42:59 703

原创 Java并发编程实战 08 | 彻底理解Shutdown Hook

释放资源(如文件句柄、网络连接)。关闭数据库连接。保存未完成的数据或状态。我们可以通过钩子线程实现这一点,钩子线程是指在程序结束时,JVM 会自动执行的一类线程。这些线程会被预先“挂钩”在程序退出事件上,一旦 JVM 检测到程序即将退出,就会启动这些线程来执行特定的操作。钩子线程是通过 Runtime.getRuntime().addShutdownHook(Thread hook) 方法来注册的。当 JVM 检测到应用程序即将退出时,就会运行所有注册的钩子线程。@Override。

2024-10-15 07:47:17 1065

原创 Java并发编程实战 07 | 如何正确停止线程

生活中,我们经常会遇到类似的情况。在主线程中调用 interrupt 方法来中断目标线程时,目标线程可能无法感知到中断标志,也就是说,即使主线程发出了中断请求,目标线程可能继续运行,不会及时停止或做出其他响应。可以看到,使用 stop 方法强制结束线程可能会导致操作不完全:上面的例子中,只有三批物品被移动,而这些物品在线程停止后没有被移回原处,这种情况可能带来数据不一致的问题。实际上,当我们停止一个线程时,通常希望它至少能完成一些必要的收尾工作,如保存数据、切换状态等,而不是立即停止,以免导致状态混乱。

2024-10-15 07:46:37 1044

原创 图解Redis 04 | Set数据类型的原理及应用场景

Redis 的 Set 类型是一个不允许重复元素的集合,元素存储的顺序不按照插入的顺序,因此属于无序集合。一个 Set 最多可以存储 2^32 - 1 个元素,这与数学中的集合概念类似。Set 类型不仅支持增、删、改、查等操作,还支持多个Set之间的交集、并集和差集运算。

2024-10-10 22:53:07 1170 1

原创 图解Redis 03 | List数据类型的原理及应用场景

List是一个简单的字符串列表,按照元素的插入顺序进行排序。您可以从头部或尾部添加元素到这个列表中。列表的最大长度为2^32 - 1,即支持多达40亿个元素。

2024-10-10 22:52:16 922

原创 小白快速上手 Docker 03 | Docker数据卷

数据卷是宿主机中的一个目录或者文件,当容器目录挂载到宿主机的某个目录之后,宿主机的这个目录就成为了一个数据卷,这样容器和宿主机之间的文件就会同步。这就解决了以上的问题。下面通过Bind Mount形式启动一个nginx容器,并将宿主机目录/Users/qin/docker/volume/nginx_90映射到容器的/usr/share/nginx/html/目录。下面介绍如何通过匿名数据卷形式启动一个nginx容器,并将容器的/usr/share/nginx/html/目录映射到宿主机指定目录。

2024-10-05 07:23:11 780

原创 小白快速上手 Docker 02 | Docker 容器生命周期

通过运行docker create命令,我们可以在指定的镜像上创建一个薄的可写层,并准备运行主进程(由 CMD 和/或 ENTRYPOINT 定义)。需要注意的是,在创建状态下,容器已经存在,但并没有开始执行。如果容器正在运行或暂停时尝试删除,会收到错误提示说明,容器需要先停止。在此命令中,echo "hi"在 alpine 容器内执行,打印“hi”后立即退出,导致容器自动停止。这是容器生命周期的第一个状态,在这个阶段,容器被创建但尚未启动。暂停时,容器的状态保持完整,包括磁盘和内存的内容。

2024-10-04 07:48:47 664

原创 万字长文 | 什么是虚拟机?它们如何工作?

在谈到Docker时,主要是指Docker引擎。Docker引擎就是用于运行和编排容器的基础设施工具。其作用在于创建、管理和编排容器。让你更容易地使用容器。也就是说,Docker本身并不是容器,它是创建和管理容器的工具。通过 Docker,开发者可以快速构建一个应用程序的容器,假设你有一个网页应用需要运行在某个服务器上。使用 Docker,你可以创建一个包含应用代码、运行时环境(如 Node.js)和所有库的容器。这个容器可以在开发机、测试机和生产环境中无缝运行,而不必担心每个环境的差异。

2024-10-04 07:46:41 1386

原创 什么是虚拟化?| 裸机 vs 虚拟机 vs 容器

云计算!DevOps!Docker!Kubernetes!……”如果您是一名软件工程师,还没有遇到过以上这些流行词,那么您可能一直生活在与世隔绝的地方。所有这些技术都与同一样东西有关,对,就是虚拟化!!!但是,虚拟化到底是什么?我认为最好用一个例子来描述——让我们接着往下看……假设公司“XYZ”需要运行两个不同的应用程序—应用程序 A 和应用程序 B。但这两个应用可能对操作系统和库的要求不同。在没有虚拟化的情况下,公司需要为每个应用各自配备一台物理机器,这不仅成本高昂,而且管理复杂。

2024-10-03 06:16:59 939

原创 万字长文 | 什么是虚拟机?它们如何工作?

虚拟化是通过软件创建抽象层的过程,它将操作系统与物理硬件平台及相关应用程序分离。虚拟化是云计算的核心,允许生成虚拟资源,如服务器、桌面、操作系统、文件、存储和网络。下图说明在非虚拟化计算机中,宿主机操作系统(及其驱动程序)和物理硬件之间保持直接连接。各个应用程序则与宿主机操作系统进行交互。然而,在虚拟化环境中,虚拟机监视器 (VMM) 软件是虚拟化计算机中的中介,它将软件应用程序的操作系统和硬件分开。因此,VMM 软件有助于虚拟机的创建、管理和调节,监督物理主机上虚拟化环境的运行。

2024-10-03 06:15:28 4596

原创 图解Redis 02 | String数据类型的原理及应用场景

在 Redis 中,String 是一种重要的数据类型,是最基本的 key-value 结构,在这个结构中, value 是一个字符串。value 所能容纳的数据最大长度为512M。需要注意的是,这里的字符串不只指文本数据,它还可以是数字、JSON 对象、二进制数据等。

2024-09-17 11:16:05 1650

原创 图解Redis 01 | 初识Redis

Redis 是一种基于内存的数据库,所有的数据读写操作都在内存中完成,因此读写速度非常快。它被广泛应用于缓存、消息队列、分布式锁等场景。Redis 提供了多种数据类型来支持不同的业务需求,如 String、Hash、List、Set、Zset、Bitmaps、HyperLogLog、GEO、Stream 等。Redis 对这些数据类型的操作都是原子的——因为Redis是单线程架构,一条命令的执行是由单个线程完成,不会出现并发竞争的问题。

2024-09-17 11:14:07 1546

原创 优化你的MySQL查询:12个必备的SQL书写习惯!

总之,良好的 SQL 书写习惯可以提高数据库系统的效率、安全性和可维护性,使开发人员和最终用户都能从中受益。

2024-09-12 07:11:06 663

原创 比 GPT-4 便宜 187 倍的Mistral 7B (非广告)

Mistral 7B 是一种设计用来快速处理较长文本的人工智能模型。它采用了一些特别的技术来提高速度和效率,比如“分组查询注意力(grouped-query attention)”和“滑动窗口注意力(sliding-window attention)”。这些技术帮助模型在生成输出时保持较高的质量和速度,同时还能处理更多的上下文信息(最多 8,000 个单词左右)。相较于一些更大的模型,Mistral 7B 的运算速度更快,内存要求更低,也更节省成本,而且它是免费提供的,使用没有限制。

2024-09-12 07:08:48 1072

原创 最通俗的语言搞懂”大模型“的来龙去脉

人工智能时代,有很多时髦、相互容易混淆概念的科技名词:AI、Machine Learning、Deep Learning、Generative AI、Large Model,它们指的是同一个概念么?不是的。AI(artificial intelligence人工智能),它的概念最广泛,所有研究人类智能的技术都可以归为其中。ML(machine learning机器学习),是AI的一个子集,具体指的是通过计算机从数据中学习规律的技术。

2024-09-11 07:32:20 1638

原创 从LIFO到LFU,8种缓存淘汰策略,一张图搞懂!

按照LRU策略,14小时之前被访问的那个数据项会被优先淘汰,因为它是最久没有被访问的。按照MRU策略,5秒之前被访问的数据会被优先淘汰,因为它是最近使用过的。例子:如果缓存中的数据项是按照以下顺序加入:数据1、数据2、数据3、数据4、数据5,那么数据1将会是第一个被淘汰的,因为它是第一个加入缓存的。例子:常见于CPU缓存系统,L1缓存存放经常使用的数据,而L2缓存用于较不频繁的数据。L1缓存命中失败时,会查询L2缓存。LRU策略会淘汰最近最少使用的缓存项,也就是说,最久没有被访问到的数据会被首先删除。

2024-09-11 07:31:12 535

原创 一个例子彻底搞懂对线程模型的理解 !

想象一下,工厂的管理层(操作系统)不允许JVM部门(Java虚拟机)直接雇佣多个工人(内核线程),而是规定:“你们部门的所有工作只能由一个人完成。” JVM部门为了多做一些事情,只能创建很多虚拟工人(用户线程),然后这些虚拟工人排队,由一个真正的工人(操作系统内核线程)来轮流完成所有的任务。在这个模型中,工厂管理系统(操作系统)允许JVM部门(Java虚拟机)创建多个工人(用户线程),但管理系统不需要为每个虚拟工人分配一个真正的工人(内核线程)。多对一线程模型是指多个用户线程映射到一个操作系统内核线程。

2024-09-10 06:54:04 462

原创 Java并发编程实战 11 | 线程活跃问题(死锁,活锁和饥饿)

第二种活跃度问题是活锁。活锁与死锁非常相似,都是指程序永远得不到最终结果,但它们的表现形式有所不同。活锁中的线程不会像在死锁中那样完全卡住,而是不断地尝试某些操作,但这些操作会导致它们无法继续前进。比如,在路上我们相遇,都会礼貌地让路,结果你往右走,我往左走,又撞在一起,最后谁也过不去。情况是这样的:为了演示活锁的情况,我们可以对之前的死锁示例代码进行一些修改。以下是修改后的逻辑:类似地,两个线程都需要两个锁才能完成工作。每个线程都获取了第一个锁,但发现第二个锁不可用。

2024-09-10 06:51:09 1716

原创 Java并发编程实战 10 | 线程安全问题

Java并发实践》的作者 Brian Goetz 对线程安全的定义是:当多个线程访问同一个对象时,如果无需考虑这些线程在运行时的调度策略和交替执行顺序,也不需要进行额外的同步处理,仍然能够得到正确的结果,那么这个对象就是线程安全的。简单来说,线程安全意味着:无论有多少线程同时访问业务中的某个对象或方法,都不需要做额外的处理(就像编写单线程程序一样),程序依然能够正常运行,不会因多线程的并发访问而出现错误。

2024-09-09 12:13:54 1407

原创 Java并发编程实战 09 | 为什么需要

守护线程(Daemon Thread)是Java中的一种特殊线程,那么相对于普通线程它有什么特别之处呢?在了解守护线程之前,我们先来思考一个问题:JVM在什么情况下会正常退出?答案是:当Java虚拟机(JVM)中只剩下守护线程在运行时,JVM就会自动退出。上面这句话出自JDK官方文档,原话翻译过来是这样:当JVM中没有正在运行的非守护线程(用户线程)时,JVM进程就会自动退出。这句话可能有些难以理解,但通过下面的代码示例,你就能更清楚地了解它的含义。// 创建一个用户线程try {});

2024-09-09 12:11:00 1148

原创 Java并发编程实战 08 | 彻底理解Shutdown Hook

释放资源(如文件句柄、网络连接)。关闭数据库连接。保存未完成的数据或状态。我们可以通过钩子线程实现这一点,钩子线程是指在程序结束时,JVM 会自动执行的一类线程。这些线程会被预先“挂钩”在程序退出事件上,一旦 JVM 检测到程序即将退出,就会启动这些线程来执行特定的操作。钩子线程是通过 Runtime.getRuntime().addShutdownHook(Thread hook) 方法来注册的。当 JVM 检测到应用程序即将退出时,就会运行所有注册的钩子线程。@Override。

2024-09-08 19:31:54 1731

原创 Java并发编程实战 07 | 如何正确停止线程

生活中,我们经常会遇到类似的情况。在主线程中调用 interrupt 方法来中断目标线程时,目标线程可能无法感知到中断标志,也就是说,即使主线程发出了中断请求,目标线程可能继续运行,不会及时停止或做出其他响应。可以看到,使用 stop 方法强制结束线程可能会导致操作不完全:上面的例子中,只有三批物品被移动,而这些物品在停止后没有被移回原处,这种情况可能带来数据不一致的问题。实际上,当我们停止一个线程时,通常希望它至少能完成一些必要的收尾工作,如保存数据、切换状态等,而不是立即停止,以免导致状态混乱。

2024-09-08 19:30:24 1405

原创 Java并发编程实战 06 | 为什么不建议使用线程优先级?

线程优先级是一个标识,用来提示操作系统或线程调度器哪个线程更重要、更需要优先执行。优先级通常是一个整数值。在 Java 中,线程优先级的设置范围从 1 到 10,其中 1 是最低优先级,10 是最高优先级。Java 默认情况下,线程的优先级是 5。优先级高的线程通常会获得更多的 CPU 时间片,从而优先执行。但这不是绝对的,操作系统的线程调度器可能会因为其他因素(如操作系统的负载、线程的状态等)来决定实际的执行顺序。

2024-09-07 08:55:35 729

原创 Java并发编程实战 05 | 什么是线程组?

在 Java 中,ThreadGroup 用于表示一组线程。通过 ThreadGroup,我们可以批量控制和管理多个线程,使得线程管理更加方便。ThreadGroup 和 Thread 的关系就像它们的字面意思一样简单:每个线程 (Thread) 必定属于一个线程组 (ThreadGroup),线程不能脱离线程组而单独存在。

2024-09-07 08:54:54 742

原创 Java并发编程实战 04 | 使用Wait&Notify时要注意什么?

在 Java 中,wait()、notify() 和 notifyAll()方法在多线程编程中主要用于线程间的协作和同步。理解这些方法的使用特点对于编写稳定的多线程程序至关重要。

2024-09-06 19:03:52 1213

原创 Java并发编程实战 03 | Java线程状态

在本文中,我们将深入探讨 Java 线程的六种状态以及它们之间的转换过程。其实线程状态之间的转换就如同生物生命从诞生、成长到最终死亡的过程一样。也是一个完整的生命周期。首先我们来看看操作系统中线程的生命周期是如何转换的。

2024-09-06 19:02:09 1334

原创 Java并发编程实战 02 | 为什么创建线程只有一种方法?

在 Java 中,我们如何创建和使用线程?为什么说线程的创建方式本质上只有一种呢?本文将从并发编程的基础——如何创建线程开始,希望大家能够打好基础。虽然线程的创建看起来很简单,但其中还是有很多细节值得深入探讨。最后,我们将揭开线程实现的面纱,看清它的本质。首先,大家可以思考一个问题:线程的实现方式有几种?大多数人会回答 2 种、3 种,甚至 4 种,但很少有人会说只有 1 种。我们先来看看常见的两种线程实现方式,以及它们背后的本质。

2024-09-05 16:43:53 1367

原创 Java并发编程实战 01 | 进程和线程

最早的计算机就像一个新手服务员,只有在接收到每一条指令时才会开始执行。当用户输入指令时,计算机会执行这条指令,然后等待下一条指令。如果用户在思考或者犹豫时,计算机就会乖乖地等待,虽然这很规范,但效率实在是有点低,因为计算机有很多时间是闲着的。

2024-09-05 16:43:09 1401

原创 fail-fast 和 fail-safe 迭代器的区别是什么?

fail-fast 和 fail-safe 是两个在Java中常用的集合遍历机制的概念,主要用于描述在迭代集合时如何处理集合结构的修改。

2024-09-01 11:00:58 596

原创 HashSet中hashCode 与 equals 的关系?

hashCode 方法:返回对象的哈希码(一个整数)。hashCode 方法用于在哈希表中确定对象的存储位置。当向 HashSet 添加一个新对象时,Java 会先调用该对象的 hashCode 方法来计算出哈希码,用来定位对象在哈希表中的存储桶(bucket)。equals 方法:用于判断两个对象是否在逻辑上相等。当两个对象的哈希码相同(即它们可能在同一个存储桶中),Java 会进一步使用 equals 方法来检查这些对象是否真的是相等的。

2024-09-01 11:00:13 662

原创 图解Kafka | 彻底弄明白 Kafka消费者分区策略

PartitionAssignor并不复杂,只有四个主要方法。当启动一个Kafka消费者并订阅一个或多个主题时,Kafka消费者客户端会调用PartitionAssignor的subscription方法来创建订阅信息。然后,消费者组的leader(即组内的一个消费者)会接收到所有消费者的订阅信息,并通过 assign() 方法来执行分区分配。接下来,所有消费者将从leader那里接收他们的分配,并且每个消费者都会调用onAssignment()方法来处理分配的分区,通常用于更新内部状态。

2024-08-26 15:39:29 1485

原创 图解Kafka | 16张图讲透生产者交付语义

下表总结了所有交付语义的行为。

2024-08-26 15:35:22 1248

原创 图解Kafka | 5张图讲透Kafka 消费者交付语义

Kafka 消费者交付语义指的是 Kafka 消费者在处理消息时如何保证消息的可靠性和一致性。这涉及到消息是否被丢失、重复处理或者按顺序消费。当消费者组/消费者从 Kafka 消费数据时,仅支持最多一次和至少一次这两种语义。但是您可以通过选择适当的数据存储来实现类似于精确一次的交付语义,例如,任何键值存储、RDBMS(主键)、Elasticsearch或任何其他支持幂等写入的存储。

2024-08-25 17:37:49 846

原创 图解Kafka | 28张图彻底搞懂消费者

在下图中,消费者设置了自动提交,CONSUMER-1成功拉取到了PARTITION 0的消息0-4,消费偏移量已经自动提交了,但是在真正处理消息的时候,CONSUMER-1宕机了,经过重新平衡之后,组内的CONSUMER-2接管了PARTITION 0,将会从消息5开始拉取消息,这样消息0-4用于也没机会消费了。这个主题有两个分区(分区 0 和分区 1)。如果协调员在一段时间内未收到某个消费者的心跳信号,就会认为该消费者已失联,并启动重新平衡过程,以重新分配该消费者负责的分区给其他活跃的消费者。

2024-08-25 17:35:47 2024

原创 三张图解释清楚分布式系统的一致性模型

在分布式系统中,数据通常分布在多个服务器或数据库中,而这些服务器之间可能位于不同的地理位置,因此分布式系统具有可扩展性和容错性等优点。然而当系统需要处理写入操作(如更新、删除数据)时,如何确保所有服务器上的数据保持一致,成为一个重要的问题。这就是一致性模型要解决的。

2024-08-21 07:45:10 897

原创 全网最易懂 !用人话讲给初中生听的线性回归LinearRegression !

当我们学习一门新课程、接触一个新专业时,总会对该领域的专有名词感到困惑,甚至看完解释仍难以理解其含义。在我们一起学习machine learning的过程中,我会尽量对相关名词用“人话”做一遍解释,以减少学习的“痛苦感”。譬如今天要学的线性“回归”,这个**回归(regression)**和我们平时说的“回归祖国”的回归(return)是两个含义完全不同的词,它有“倒推”的含义在里面。我们学习的时候一定要抛开现有的认知,这样才能对新知识有更高的接受度。那么,这个回归究竟是什么意思呢?其实回归算法是相对。

2024-08-21 07:20:36 1081

原创 2W字,100张图,100个例子吃透机器学习100个核心概念 !

训练集用于模型学习,验证集用于模型调优,测试集用于最终评估模型的表现。通用逼近定理(Universal Approximation Theorem)通用逼近定理(Universal Approximation Theorem)是机器学习和神经网络领域的一个重要理论,它的核心思想是:具有足够复杂度的神经网络可以逼近任何连续函数。换句话说,一个足够复杂的神经网络可以学到任何复杂的模式或关系。想象你有一个非常复杂的数学函数,它很难直接描述。

2024-08-20 20:31:56 1521

空空如也

空空如也

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

TA关注的人

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