自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(43)
  • 收藏
  • 关注

原创 Spring 复习笔记

Spring IoC 容器管理的资源就是对象,这个对象也叫做 Bean。Spring 作为一个 IoC 容器,最基础的功能就是将对象存储到容器里以及从容器中拿对象。DI 依赖注入,就在程序运行期间,动态的将依赖对象获取到的过程就是依赖注入。IoC 与 DI:描述的都是同一件事,就是我们当前程序的运行需要另一个对象的时候我们不需要在手动创建这个对象,而是从框架中直接获取,然后注入到当前程序。其实本质就是对象的这个生命周期交给框架来控制而不是当前程序或者说开发者的代码。

2023-10-07 22:51:10 118

原创 Redis 学习笔记之通用命令操作

此时我们可以知道,exists hello + exists hallo 等同于 exists hello hallo,虽然结果是一样的(或者说达到的效果是一样的),但是这两种方式区别还是挺大的,原因就是redis是一个客户端服务器结构的程序,客户端和服务器之间通过网络来进行通信,既然如此,每一个命令其实客户端都会包装成一个请求给服务器,然后服务器再返回响应。Redis 支持多种数据结构。还有一个命令是用来查询过期时间的,ttl(time to live),单位是秒,也可以是 pttl,单位是毫秒。

2023-09-10 11:59:18 55

原创 JVM 学习笔记(1)

JVM(Java Virtual Machine),java 程序的运行环境(java 二进制字节码的运行环境)。好处一次编写,到处运行。我们都知道java是可以跨平台运行的,这个跨平台就是实现在JVM层面,JVM对外提供了一致的运行环境。自动内存管理,垃圾回收功能数组下标越界检查(越界了就抛异常而不是覆盖其他元素)多态,JVM底层使用虚方发表实现了多态。

2023-09-04 12:17:55 57

原创 Redis 原理篇之内存回收

Redis 之所以性能强,最主要的原因就是基于内存存储。然而单节点的 redis 其内存大小不宜过大,会影响持久化或者主从同步性能。我们可以通过修改配置文件来设置 redis 的最大内存:当内存使用达到上限后,就无法存储更多的数据了。那么要想继续存储,就需要想办法搞出空间来,Redis提供了两种策略:过期策略、淘汰策略。

2023-09-03 14:56:02 38

原创 HTTPS 学习笔记

HTTPS 基于 HTTP,只是比 HTTP 多了一个“加密层”。HTTP 协议以明文的方式发送数据,在网络上存在被劫持、篡改的风险。为了改善这个问题,就引入了加密,HTTPS 应运而生。一组概念:明文:实际要传达的信息密文:加密转换后的信息明文 =》密文 :加密密文 =》明文:解密加密和解密的过程中,需要一个关键的钥匙 =》秘钥。

2023-09-03 10:32:47 26

原创 Redis 原理篇之数据结构篇之网络模型

阻塞IO与非阻塞IO 的区别在于无数据时的处理方案:阻塞 IO 在系统调用时会一直等待数据到达才能继续其他操作(进程阻塞),非阻塞 IO 在系统调用时如果没有请求到数据则会直接返回,但是会不停的请求数据(CPU 空转)。显然这两种 IO 都不能很好地发挥CPU 的作用。Redis 是单线程,所以当一个线程陷入阻塞的时候,后面的线程即使数据准备好了也要陷入阻塞,效率很差。此时在单线程的情况下可以让数据准备就绪的线程先请求这个数据。此时就有这么个问题,就是用户进程如何知道内核中数据是否就绪呢?

2023-09-02 20:40:45 32

原创 Redis 原理篇之数据结构篇

我们知道Redis是一个键值型(Key-Value Pair)的数据库,我们可以根据键实现快速的增删改查。而键与值的映射关系正是通过Dict来实现的。Dict由三部分组成,分别是:哈希表(DictHashTable)、哈希节点(DictEntry)、字典(Dict)当我们向Dict添加键值对时,Redis首先根据key计算出hash值(h),然后利用h& sizemask来计算元素应该存储到数组中的哪个索引位置。这里发生哈希碰撞的时候采用头插法压缩列表可以看做是一种连续内存空间的“双向链表”

2023-09-02 19:15:36 43

原创 InnoDB 引擎

Change Buffer:更改缓冲区(针对于非唯一的二级索引页),在执行DML(增删改)语句时,如果这些数据Page没有在Buffer Pool中,不会直接操作磁盘,而会将数据变更存在更改缓冲区Change Buffer中,在未来数据被读取时,再将数据合并恢复到Buffer Pool中,再将合并后的数据刷新到磁盘中。Log Buffer:日志缓冲区,用来保存要写入到磁盘中的log日志数据(redo log . undo log),默认大小为16MB,日志缓冲区的日志会定期刷新到磁盘中。

2023-08-31 17:24:43 42

原创 SQL 优化

此时 MySQL 需要排序前 2000010 条数据,但是仅仅返回 2000000-2000010 这 10 条数据,其他记录丢弃,这样的代价是很大的。》InnoDB 引擎就比较麻烦了,它在执行count(*)操作的时候,需要将数据一行一行的读出来,然后累计个数。对于这个的优化思路只能是自己计数了,比如利用 redis 的键值对存表和表中记录数,增加就加一,删除就减一。InnoDB 的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁,降低并发性能。

2023-08-30 10:25:39 32

原创 MySQL 锁介绍

从锁的粒度上分,MySQL 的锁可以分为全局锁、表锁和行锁。

2023-08-30 09:43:53 36

原创 http 协议学习笔记

HTTP 是一个使用非常广泛的应用层协议。应用层协议经常是需要进行“自定义协议”的,但是很多时候也不一定非得从零开始设计,可以基于一些大佬们设计好的协议,在这个基础上进行定制。HTTP 之所以应用非常广,主要原因就是HTTP可定制性非常强。

2023-08-27 16:25:07 21

原创 Redis 学习笔记(2)

In-memory data structures:在内存中使用一些数据结构来存储数据,以键值对的型式存储,这种形式组织数据我们一般称之为“非关系型数据库”。Programmability:可编程的,针对 Redis 的操作,可以直接通过简单地交互是命令进行操作,也可以通过一些脚本的方式,批量执行一些操作(可以带有一些逻辑)Extensibility:扩展能力,可以再 Redis 原有的功能基础上再进行扩展。

2023-08-23 19:57:51 15

原创 IP 协议简单介绍

每个网络上的设备,要能分配一个地址(唯一)。下图是 IP 协议的报文格式:这个地址其实就是 IP地址,本质上是一个 32 位的整数,但是 32 位比较长,看起来不是很友好,通常情况下会把 32 位的整数转换成 点分十进制 的格式来表示,就是使用 三个点 把这个整数 分成 四个部分,每个部分一个字节,每个部分的取值是 0- 255。

2023-08-17 10:15:59 37 1

原创 MySQL 的存储引擎

这两个都是线程安全的 哈希表。

2023-08-15 18:38:59 31

原创 网络原理篇 - 网络层

以这个图为例,1-1000 是正常传输的,此时B就会返回 确认序号 1001,但是A发送的 1001-2000 的数据丢了,此时由于滑动窗口机制,消息就会继续发,于是就把 2001 - 3000 发送给 B 了,但是 确认序号还是 1001,不会变成 3001,就这样连续又发了一些数据之后,A 发现收到的 确认序号 一直是 1001,就意识到了事情不简单,1001-2000 的数据怕是丢了,于是 A 就会重传 1001- 2000 这个数据。由此可见拥塞控制并不是一个固定不变的速率,是一个动态的过程。

2023-08-13 13:54:08 64 1

原创 MySQL 索引事务

举个例子,假设正在考试,学生1 在做一道选择题,在 C 和 D 选项中徘徊不定,虽然写下了 C 但是还没确定,此时学生 2 偷瞄了同学1 的答案,于是写了 C,但是同学1 思考中确定了 D 是正确答案,又是改成了 D,那么此时 同学2 的偷瞄就相当于是脏读,读到的 C 就相当于是 脏数据。此时考虑一个极端场景,假设在执行转账的过程中,执行完 1) 之后,数据库崩溃了/主机宕机了,此时 2)操作就没有执行,也就是说 1 的钱扣了,但是 2 的钱没到账,显然这是很不科学的。而事务就是为了解决这个问题的。

2023-08-11 21:02:11 238 14

原创 模拟实现消息队列(以 RabbitMQ 为蓝本)

目录1. 需求分析1.1 介绍一些核心概念核心概念1核心概念21.2 消息队列服务器(Broker Server)要提供的核心 API1.3 交换机类型1.3.1 类型介绍1.3.2 转发规则:1.4 持久化1.5 关于网络通信1.5.1 客户端与服务器提供的对应方法1.5.2 客户端额外需要提供的方法1.6 消息应答模式1.7 需求分析小结2. 系统设计 - 模块设计3. 代码实现3.1 创建项目3.2 项目结构3.3 Exchange 类3.4 MSGQueue 类3.5 Binding 类3.6 M

2023-08-09 16:24:45 1761 22

原创 MySQL 的操作(进阶)

就是一张表自己和自己连接,即自己与自己做笛卡尔积,这个操作本质上是把行转成列,这么做的原因就是 SQL 中进行条件查询,都是指定某一列/多个列之间进行关系运算,无法行与行之间的比较,所以当我们有这样的需求时,就可以进行自连接操作。这里的 select 指定的列(role),要么是带有聚合函数的,要么就是指定的 group by 的列,不能指定一个 非聚合、非 group by 的列,比如写个 name,此时虽然不会报错,但是结果是无意义的。这里有四张表,三个实体(学生,班级,课程)。班级和课程之间没关系。

2023-08-03 10:09:15 185 7

原创 MySQL 的常见操作(基础)

C 即 增加 - create,R 即 查询 - retrieve, U 即更新 - update, D 即删除 - delete。

2023-08-02 08:21:13 274 8

原创 网络编程介绍

Datagram 就是 “数据报”,Socket 说明这个对象是一个 Socket 对象,这个 socket 对象相当于对应到系统中一个特殊的文件(socket 文件)socket 文件并非对应到硬盘上的某个存储区域,而是对应到网卡这个硬件设备,我们要想进行网络通信,就需要有 socket 文件这样的对象,借助这个对象才能够间接地操作网卡。举个例子,比如说 A 和 B 领证结婚,结婚证一式两份,A 一份,此时 A 就知道了 A 的另一半是 B(相当于在 A 这里做了个记录,B 和 A 建立连接了);

2023-08-01 08:00:31 62 5

原创 Redis 学习笔记(1)

本来一个数据库上有多个数据库(create database 创建的),现在就可以引入多个服务器,每个服务器只存储一个或一部分数据库,如上图所示,本来用户表、商品表、交易表可能是在同一个数据库服务器上的,此时通过拆分就可以解决数据存储问题,当然,具体怎么分库分表还是要结合实际的业务场景来展开。其实是可以的,因为负载均衡器只是分发请求,不是处理请求,所以说负载均衡器对于请求的承担能力是很高的,远超过应用程序,当然,是在处理不过来的话,也可以增加其他负载均衡器节点。

2023-07-31 09:05:56 29

原创 Spring 、Spring Boot 与 Spring MVC 介绍

Spring框架是一个用于构建企业级Java应用程序的开源应用程序框架。它提供了一组综合的解决方案,用于开发Java应用程序的各个方面,包括依赖注入(Dependency Injection)、面向切面编程(Aspect-Oriented Programming)、事务管理、数据访问、Web开发等。AOP 的主要作用是将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务管理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可维护性和可扩展性。

2023-07-30 17:55:16 1306 14

原创 常见的锁策略

synchronized 即使悲观锁也是乐观锁,既是轻量级锁也是重量级锁,轻量级锁部分基于自旋锁实现,重量级锁部分基于挂起等待锁实现。原因是 synchronized 会根据当前锁的竞争的激烈程度,调整锁策略(自适应),如果锁冲突不激烈,就以轻量级锁/乐观锁的状态运行,如果锁竞争激烈,就以重量级锁/悲观锁的状态运行。当一个线程尝试获取挂起等待锁时,如果锁已被其他线程占用,该线程会被挂起,进入等待状态,直到锁被释放。当一个线程尝试获取自旋锁时,如果锁已被其他线程占用,该线程会一直循环忙等待,直到锁被释放。

2023-07-29 19:42:45 155 14

原创 在线 OJ 平台

除此之外,测试用例代码一定得是一个完整的可以编译运行的代码,我们这里的做法是:测试用例代码就把它设计成一个 main 方法,我们就在这个 main 方法里面创建 Solution 类的实例,然后调用里面的核心方法,调用核心方法的时候,我们传入我们设计好的不同的参数,并针对返回结果进行判定,如果返回结果符合预期(正确),就打印“Test OK”,否则就打印“Test failed”,同时打印出错信息。一个Problem 对象,就对应这表中的一条记录,有了表和这个实体类,我们就可以对表进行增删改查操作了。

2023-07-26 18:40:39 116 9

原创 详细又简单的线程池的介绍

线程池:顾名思义,就是放线程的池子。提前准备好线程,用户在使用线程时就不用直接从系统申请,而是从池子中拿。线程不用了,就放回到池子里。回到正题,线程池,java 标准库提供了现成的线程池,我们看看代码怎么写:上面那一行构造一个固定 10 线程的线程池,下面那一行不会设定固定值,按需创建,用完之后也不会立即销毁,留着以备后用。

2023-07-25 11:38:38 154 7

原创 java中的定时器

比较器很简单,不用多说。而为什么我们使用 wait 等待而不用 sleep呢,因为 wait 可以随时唤醒,假设在等待过程中插入了一个新的任务,这个新任务的时间更快,那么 notify 就可以唤醒 wait,下次在从队列里拿任务就会拿到更快的这个任务而如果使用 sleep,就会睡眠 设定好的时间,如果在这期间插入了新的、更快的任务,就会导致这个任务执行晚了,出现 bug。Timer 的核心方法是 schedule,该方法有两个参数,第一个参数就是我们准备执行的任务,第二个参数就是时间,即过多久执行任务。

2023-07-24 23:34:03 1185 5

原创 阻塞队列介绍及手动实现

如果队列空,尝试出队列,就会阻塞等待,等待到队列不为空为止如果队列满,尝试入队列,也会阻塞等待,等待到队列不满为止线程安全下面来看看代码如何实现:BlockingQueue 是一个接口,主要有两个实现类,一个是 ArrayBlockingQueue,基于数组实现,一个是 LinkedBlockingQueue,基于链表实现。我们这里以 LinkedBlockingQueue 为例。

2023-07-24 10:19:15 113 1

原创 单例模式 - java

单例模式是一种常见的设计模式,它保证系统中某个类只有一个实例存在,并且提供一个全局的访问点来获取该实例。通过使用单例模式,可以避免重复创建对象实例,节省系统资源,并且提供了一种方便的方式来访问该实例。例如,在多线程环境下,单例模式可以确保全局只有一个可用的实例,防止多个线程同时创建对象导致的不一致或冲突。java 中的单例模式,借助 java 语法来保证某个类,只能创建出一个实例对象。饿汉式(急迫)懒汉式(从容)

2023-07-23 09:52:22 178 5

原创 线程安全问题

第一步 t1 执行 load,将内存中的 count 值加载到 寄存器中,值为 0, 第二步 t2 执行 load,将内存中的 count 值 加载到寄存器中,值为 0,第三步 t2 执行 add,寄存器中值变为 1, 第四步t 2 执行 save,将 1 写回到内存中,第五步 t1 执行 add,寄存器中值变为 1,第六步 t1 执行 save,将 1 写回到内存中,此时做种结果为1,显然是错的,说明 bug 就产生了,相当于其中一次的自增结果被另一个给覆盖了(不是没有自增)。

2023-07-22 17:03:58 151 18

原创 Thread 类及常见方法

系统对于线程的调度是随机的,假设我们的机器上面存在很多的进程和线程,此时 CPU 调度一圈,消耗的时间可能就比较长,此时就可能导致某个线程隔了很久也没有调度上去,这个可能大多数人都遇到过这种情况:某些时候,电脑卡了,点击某个窗口,提示“未响应”,让我们选择等待还是结束进程。此时会出现这样的提示信息,意思是 isQuit 这个变量不是常量或者“实际常量”,常量就是 final 修饰的,“实际常量”是没有final修饰,但是也没有其他代码尝试修改的变量,但是我们在下面对 isQuit 进行了修改,所以不行。

2023-07-21 15:30:45 886 3

原创 Java 中线程创建的基本方式

此时点击运行 main 方法后,idea 对应的进程创建了一个 java 进程(为idea进程的子进程),这个 java 进程来执行我们刚刚写的代码。此时这各 java 进程里就有两个线程,一个是 main,一个是 t。需要注意的是,我们的类继承 Thread 时,需要重写里面的 run() 方法,这个 run 方法的方法体就是我们要实现的功能,但是我们在创建线程后,启动线程使用的是 start() 方法,而不是 run()。这种 lambda 表达是的写法最为常见。

2023-07-20 09:30:43 78 3

原创 线程的介绍

作为 java 程序员,我们与线程打交道的次数应该是远远大于进程的,因为 java 中非常鼓励多线程编程(多进程编程和多线程编程都能满足“并发编程”需求场景)。下面我们就来聊一聊线程。约定,一个进程中可以包含多个线程,此时着多个线程中的每个线程都是一个独立可以调度执行的“执行流”(这些执行流之间本身就是并发的),同时,这些线程共用同一份进程的系统资源。这就意味着,对于线程而言,系统资源是已经分配好了的,创建线程就省下了分配资源的开销。

2023-07-19 12:42:57 84 1

原创 操作系统中的进程

但是根据上面的电脑正在运行的进程可知,我这台电脑目前是6+113=119个活需要同时干,但是我们只能同时干12个人的活,这显然是不够的,这就产生问题了,为了解决这个问题,聪明的程序员又引入了。上下文就是描述了当前进程执行到哪里的一个“存档记录”,进程在离开 CPU 的时候,就要把当前运行的中间结果进行“存档”,等到下次该进程回来 CPU 上继续执行时,就恢复到之前“存档”时的状态,相当于“读档”,从而可以从上次的结果继续向下执行。内存指针:描述了当前这个进程使用的内存是哪一部分,使用了哪些内存上的资源。

2023-07-18 23:32:01 92 2

原创 Spring 事务和事务传播机制

事务就是将一组操作封装成一个执行单元,要么全部执行成功,要么全部执行失败。Spring 中的事务和 MySQL 中的事务解决的是一个问题,举个例子,如果 a 给 b 转账 100 元, 那么 a 就会少 100元, 同时 b 就会多 100元,不能 a 少了100,但是 b却没有多100,这是不合法的。

2023-06-26 06:30:00 89 3

原创 经典面试题之 MySQL 事务隔离级别

MySQL 事务隔离级别有 4 种:

2023-06-25 17:24:54 149 2

原创 Spring AOP

首先 AOP(Aspect Oriented Programming) 为 面向切面编程 ,它是一种思想,他是对某一类事情的集中处理。比如对用户登录权限的校验,在学 AOP 之前,我们所有需要判断用户登录状态的页面,都要各自去实现或调用用户验证的方法,在有了AOP 之后,我们只需要在某一处配置一下,所有需要判断用户登录的页面就全部可以实现用户登录的验证了,不再需要每个页面都写相同的用户验证登录方法了。而 Spring AOP 是一个框架,是一种对 AOP 思想的实现,它们的关系和 IoC 与 DI 类似。

2023-06-24 11:15:11 62 2

原创 MyBatis 的介绍及简单功能的实现与演示

MyBatis 是一款非常好的持久层框架, 它支持自定义 SQL、存储过程以及高级映射。MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象) 为数据库中的记录。简单来说 MyBatis 是更简单完成程序和数据库交互的工具,也就是更简单的操作和读取数据库工具。

2023-06-21 23:22:10 221 2

原创 SpringBoot 的创建和使用

Spring 的诞生是为了简化 Java 程序的开发, 而 SpringBoot 的诞生是为了简化 Spring 的程序开发。

2023-06-18 00:15:00 80 3

原创 Bean 的作用域 和 生命周期

这个原型模式又叫做多例模式, 和单例模式相对应. 官方给出就得我说明是: Scopes a single bean definition to any number of object instances. 大概意思是每次对该作⽤域下的 Bean 的请求都会创建新的实例: 获取Bean(即通过 applicationContext.getBean 等方法获取)及装配 Bean(即通过@Autowired注入)都是新的对象实例. 通常有状态的 Bean 使用该作用域.

2023-06-16 23:29:04 165 3

原创 JVM的垃圾回收机制

作为 Java 程序猿, 大家都知道 Java 中的对象, 都是通过引用来指向并访问的, 经常是一个引用指向一个对象, 这个对象里的成员, 又指向别的对象. 比如说二叉树, 链表等. 整个 Java 中的对象, 就通过类似于上述的关系, 通过这种链式/树形结构, 整体给串起来.刚被 new 出来的对象, 放在伊甸区, 熬过一轮 GC, 对象就要被放到幸存区. 虽然看起来幸存区比伊甸区小了很多, 但是根据上述经验规律, 大部分的java 对象都是"朝生夕死", 生命周期非常短, 所以说一般够放.

2023-06-12 14:26:16 224 4

空空如也

空空如也

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

TA关注的人

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