设计模式——创建型模式
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。
这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。
创建型模式分为:
单例模式
工厂方法模式
抽象工程模式
原型模式
建造者模式
单例模式这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
即在整个程序中,同一个类始终只会有一个对象来进行操作。比如数据库连接类,实际上只需要创建一个对象或是直接使用静态方法就可以了,没必要去创建多个对象。
单例设计模式分类两种:
饿汉式:类加载就会导致该单实例对象被创建
懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建
饿汉式
/** * 饿汉式 * 静态变量创建类的对象 */public class Singleton { //私有构造方法 private Singleton() {} //在成员位置创建该类的对象 private static Singleton in ...
设计模式——设计原则
设计模式分类
创建型模式
用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”。含有单例、原型、工厂方法、抽象工厂、建造者5种创建型模式
结构型模式
用于描述如何将类或对象按某种布局组成更大的结构,即类或对象的组合,含有代理、适配器、桥接、装饰、外观、享元、组合7种结构型模式
行为型模式
用于描述类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责,即类或对象之间的交互和通信。含有模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器11种行为型模式
类别
模式
核心思想
典型应用场景
创建型
单例模式
确保一个类只有一个实例
全局唯一对象(如配置管理器)
工厂方法模式
由子类决定实例化哪个类
框架中对象的创建
抽象工厂模式
创建相关对象的家族
跨平台的 UI 组件库
建造者模式
分离复杂对象的构建与表示
复杂对象的创建(如 HTML 文档生成器)
原型模式
通过复制现有对象创建新对象
对象的创建成本较高时
结构型
适配器模式
将一个接口转换成客户端期望的另一个接口
兼容旧 ...
redis内存回收
Redis内存回收机制Redis中的内存策略主要包含下列四点:
内存清除策略(Eviction Policy):当Redis内存空间不足时,会根据特定的算法删除一些key来释放内存。其中,常用的算法有LRU(最少最近使用)、LFU(最少使用频率)和随机算法
内存淘汰策略(Expiration):在插入或更新key的时候,可以指定key的过期时间(expire)时间。过期后,Redis会自动将key删除,释放内存
内存回收策略(Memory Reclamation):在使用Redis时,可能会因为未正确释放内存而导致内存泄漏。Redis针对这种情况实现了自动内存回收机制来防止内存泄漏的问题
内存优化策略(Memory Optimization):Redis提供了各种内存优化策略,例如使用压缩(压缩整数值、压缩非常短的字符串)、使用哈希对象来优化内存使用等,以最大限度地减少内存使用。Redis也使用专门的数据结构来实现某些特定的数据类型,例如基数计数器和位数组,这些也是为了优化内存使用而设计的
过期key处理Redis之所以性能强,最主要的原因就是基于内存存储。然而单节点的Redis其 ...
redis网络模型
Linux网络模型在《UNIX网络编程》一书中,总结归纳了5种IO模型:
阻塞IO(Blocking IO)
非阻塞IO(Nonblocking IO)
IO多路复用(IO Multiplexing)
信号驱动IO(Signal Driven IO)
异步IO(Asynchronous IO)
阻塞IO应用程序想要去读取数据,他是无法直接去读取磁盘数据的,他需要先到内核里边去等待内核操作硬件拿到数据,这个过程就是1,是需要等待的,等到内核从磁盘上把数据加载出来之后,再把这个数据写给用户的缓存区,这个过程是2,如果是阻塞IO,那么整个过程中,用户从发起读请求开始,一直到读取到数据,都是一个阻塞状态。
用户去读取数据时,会去先发起recvform一个命令,去尝试从内核上加载数据,如果内核没有数据,那么用户就会等待,此时内核会去从硬件上读取数据,内核读取数据之后,会把数据拷贝到用户态,并且返回ok,整个过程,都是阻塞等待的,这就是阻塞IO
非阻塞IO非阻塞IO的recvfrom操作会立即返回结果而不是阻塞用户进程
阶段一:
用户进程尝试读取数据(比如网卡数据)
此时数据尚未到达,内核 ...
redis数据结构
简单动态字符串SDSRedis中保存的key是字符串,value往往是字符串或者字符串的集合。可以说字符串是Redis中最常见的数据结构。
不过Redis中没有直接使用C语言中的字符串,而是构建了一种新的字符串结构,称为简单动态字符串(Simple Dynamic String)。
比如我们执行命令set name Jack,那么Redis将在底层创建两个SDS,其中一个是包含name的SDS,另一个是包含Jack的SDS。
Redis是C语言实现的,其中SDS是一个结构体,源码如下:
struct __attribute__((packed)) sdshdr8 { uint8_t len; // buf已保存的字符串字节数,不包含结束标示\0 uint8_t alloc; // buf申请的总字节数,不包含结束标示\0 unsigned char flags; // 不同的SDS的头类型,用来控制SDS头大小 char buf[];};
flag对应的种类有五五种
#define SDS_TYPE_5 0#define SDS_TYPE_ ...
redis分布式缓存
分布式缓存之前学的都是单点Redis,而这种单点Redis存在一些问题:
数据丢失
并发能力差
存储量小
故障恢复能力弱
我们可以使用Redis分布式缓存解决以上问题。
Redis持久化解决数据丢失问题RDB持久化RDB全称 Redis Database Backup file(Redis数据备份文件),也可以称为叫Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。快照文件称为RDB文件,默认是保存在当前运行目录。
RDB持久化的执行条件有save命令、bfsave命令、Redis手动停机、触发系统内置RDB条件时。
save命令使用redis-cli链接到redis中后使用save命令可以立刻执行一次RDB。save命令会导致主进程执行RDB,这个过程中其它所有命令都会被阻塞。只有在数据迁移时可能用到。
bgsave命令与save命令的执行步骤相同,但bgsave命令执行是异步的,执行后会开启独立进程完成RDB,主进程可以持续处理用户请求,不受影响。
停机主动停机时会自动执行一次RDB
Redis内置RDB ...
二分查找算法入门
二分查找可以有几种写法:
闭区间
开区间
半开半闭区间(左开右闭/左闭右开)
所谓开闭区间,指的是二分查找中的left和right的值,如果取值在数组内部(大部分情况下),就可以成为闭区间,反之为开区间。
展示这三种写法,我们从一道题目开始:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
这道题就是纯粹的二分查找板子题,数组有序,数组中无重复元素。
这里使用Java进行展示,首先是闭区间写法。
class Solution { public int search(int[] nums, int target) { int n = nums.length; int l = 0, r = n - 1; while(l <= r){ int mid = l + (r - l >> 1); // 防止爆int ...
强化学习基础知识
记录一些强化学习基础名词解释,理解的不深
基本概念强化学习(Reinforcement Learning,RL)是一种机器学习方法,旨在通过与环境的交互来学习如何采取行动以最大化累积奖励。与监督学习不同,强化学习没有预先标注的输入输出对,而是通过试错和从反馈中学习
Agent:做出动作的角色,即智能体
state(状态):智能体当前所处的环境,包含环境当前的全部或部分信息,在玩游戏时,state就是当前的游戏画面,如果状态,动作,奖励等变量被观测到了,用s表示;没观测到就表示随机变量,用S表示
action(动作):智能体在每个时间步可以采取的操作
policy(决策):agent在当前做出的动作
policy function(策略函数):在某种state下,agent采取某种action的概率$\pi(s.a)$,函数值范围为[0,1]
Reward(奖励):是指采取动作后,环境给agent的奖励,它可能为正、负、0
state transition(状态转移):agent在某个状态采取某个动作后,可能发生的状态变化
强化学习是agent与环境互动的过程。我们观测到状态$s_t$, ...
pytorch基础入门
两个实用函数假如pytorch是一个大型工具箱,我们想查看工具箱中有什么工具,这时就可以使用dir()函数查看,如果我们想知道某一个工具是如何使用的,就可以使用help()函数查看
dir():可以查看指定对象包含的全部内容,包括变量、方法、函数和类等。不仅包含可供我们调用的模块成员,还包含所有名称以双下划线“__”开头和结尾的“特殊”命名的私有成员,这些成员是在本模块中使用的,不能在类的外部调用。
help():查看指定对象(类型、模块、变量、方法等)的详细使用说明
Pytorch在学习和使用pytorch时,要经常使用官方文档,里面有详细的使用说明
加载数据集加载数据方法及label形式Pytorch中加载数据需要Dataset、Dataloader
Dataset提供一种方式去获取每个数据及其对应的label和编号,以及总共有多少个数据
Dataloader为后面的网络提供不同的数据形式,可以将数据进行打包
label形式
文件夹名即为label。文件夹中存放若干条数据
一个文件夹存放数据,数据有编号,另一个文件夹存放数据对应编号的说明文本(txt),文本中有label ...
numpy常用api
NumPy,全称Numerical Python,是一个开源的Python库,它为Python提供了强大的多维数组对象和用于处理这些数组的函数。NumPy的核心是ndarray,它是一个高效的多维数组容器,用于存储和处理大规模的数据。NumPy还提供了许多数学函数,用于数组之间的操作,以及用于线性代数、傅立叶变换和随机数生成等功能。
基本使用创建数组ndarraynumpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
上面的构造器接受以下参数:
参数
描述
object
返回一个数组或任何(嵌套)序列
dtype
数组的所需数据类型,可选
copy
可选,默认为true,对象是否被复制
order
C(按行)、F(按列)或A(任意,默认)
subok
默认情况下,返回的数组被强制为基类数组。 如果为true,则返回子类
ndmin
指定返回数组的最小维数
示例import numpy as np a = np.array([1,2,3 ...