算法、语言混编、分布式锁与分布式ID、IO模型
一、算法初识
数据结构和算法是程序的基石。我们使用的所有数据类型就是一种数据结构(数据的组织形式),写的程序逻辑就是算法。
算法是指用来操作数据、解决程序问题的一组方法。
对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源(空间复杂度)和时间(时间复杂度)却会有很大的区别。
时间维度:是指执行当前算法所消耗的时间,我们通常用「时间复杂度」来描述。
空间维度:是指执行当前算法需要占用多少内存空间,我们通常用「空间复杂度」来描述。
常见的时间复杂度量级有(大O符号表示法):
- 常数阶O(1)
- 对数阶O(logN)
- 线性阶O(n)
- 线性对数阶O(nlogN)
- 平方阶O(n²)
- 立方阶O(n³)
- K次方阶O(n^k)
- 指数阶(2^n)
上面从上至下依次的时间复杂度越来越大,执行的效率越来越低。(具体参考此博客)
Python:常用的排序算法
二、Python和Go/Java/C语言混编
1.动态链接库(dll,so文件)
Linux下的动态库以.so 结尾
Windows下的动态库以.dll结尾
2.Go语言写的代码,把所有代码都编译到一个可执行文件
3.C语言写的程序,支持不同的代码编译到动态链接库中
4.Python调用动态链接库(so,dll)
from ctypes import *
#----------以下四种加载DLL方式皆可—————————
# pDLL = WinDLL("./myTest.dll")
# pDll = windll.LoadLibrary("./myTest.dll")
# pDll = cdll.LoadLibrary("./myTest.dll")
pDll = CDLL("./myTest.dll")#调用动态链接库函数
res = pDll.sum(1,2)
#打印返回结果
print(res)
5.Python调用Java的jar包
6.Go写的代码编译成动态链接库文件(参考此博客)
package main
import "C" //必须引入C库
import "fmt"
//加入下面注释代码,表示导出,可以被python调用
//export PrintDll
func PrintDll() {fmt.Println("我来自dll")
}
//
//export Sum
func Sum(a int, b int) int {return a + b
}
func main() {//必须加一个main函数,作为CGO编译的入口,无具体实现代码
}
编译成so库:
go build -buildmode=c-shared -o s1.so s1.go
编译成dll库:
go build -buildmode=c-shared -o s1.dll s1.go
python调用so文件:
from ctypes import cdlllib = cdll.LoadLibrary('./s1.so')# 调用go语言的Sum
result = lib.Sum(100, 200)
print(result)# 调用go语言的PrintDll
lib.PrintDll()
7.什么场景使用
1)生成支付连接的方法---->so文件
2)雪花算法
三、分布式锁
在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式锁,那具体什么是分布式锁?
分布式锁具备的条件:
1、在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行;
2、高可用的获取锁与释放锁;
3、高性能的获取锁与释放锁;
4、具备可重入特性;
5、具备锁失效机制,防止死锁;
6、具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败。
如何实现?
1、基于数据库实现分布式锁
2、基于缓存(Redis等)实现分布式锁,官方提供了redlock
示例:
from redlock import Redlockdlm = Redlock([{"host": "localhost", "port": 6379, "db": 0}, ])# 获得锁
my_lock = dlm.lock("my_resource_name", 1000)print("锁被我拿到了,你们任何人都拿不到了")dlm.unlock(my_lock)
底层基于SETNX,当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。封装如下:
#连接redis
import redis
import uuid
import time
redis_client = redis.Redis(host="localhost",port=6379,# password=,db=10)#获取一个锁
# lock_name:锁名称
# acquire_time: 客户端等待获取锁的时间
# time_out: 锁的超时时间
def acquire_lock(lock_name, acquire_time=10, time_out=10):"""获取一个分布式锁"""identifier = str(uuid.uuid4())end = time.time() + acquire_timelock = "string:lock:" + lock_namewhile time.time() < end:if redis_client.setnx(lock, identifier):# 给锁设置超时时间, 防止进程崩溃导致其他进程无法获取锁redis_client.expire(lock, time_out)return identifierelif not redis_client.ttl(lock):redis_client.expire(lock, time_out)time.sleep(0.001)return False#释放一个锁
def release_lock(lock_name, identifier):"""通用的锁释放函数"""lock = "string:lock:" + lock_namepip = redis_client.pipeline(True)while True:try:pip.watch(lock)lock_value = redis_client.get(lock)if not lock_value:return Trueif lock_value.decode() == identifier:pip.multi()pip.delete(lock)pip.execute()return Truepip.unwatch()breakexcept redis.excetions.WacthcError:passreturn False
3、基于Zookeeper实现分布式锁(参考此博客)
四、分布式ID
在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。
具备条件:
全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。
趋势递增:mysql主键
单调递增:保证下一个ID一定大于上一个ID
信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要ID无规则、不规则。
平均延迟和TP999延迟都要尽可能低(TP90就是满足百分之九十的网络请求所需要的最低耗时。TP99就是满足百分之九十九的网络请求所需要的最低耗时。同理TP999就是满足千分之九百九十九的网络请求所需要的最低耗时);可用性5个9(99.999%);高QPS。
如何实现?
mysql自增、UUID、Redis生成ID、snowflake(雪花算法)方案(比较主流)
五、IO模型
数据复制的过程中(IO)不会消耗CPU
网络IO、磁盘IO
用户缓冲区和内核换冲突:
1、内存分为内核缓冲区和用户缓冲区
2、用户的应用程序不能直接操作内核缓冲区,需要将数据从内核拷贝到用户才能使用
3、而IO操作、网络请求加载到内存的数据一开始是放在内核缓冲区的
IO模型有哪些?
1、BIO-阻塞模式I/O
2、NIO-非阻塞模式I/O
3、IO多路复用模型
注意:
1.IO多路复用是阻塞式IO
2.select poll和epoll的区别
select poll:基于轮询,最多监听1024个文件的变化
epoll:基于回调,无限制监听
3.IO多路复用epoll模型是比较成熟的IO模型
4、AIO-异步I/O模型
注意:
AIO指用户缓冲区到内核缓冲区不等待,从内核缓冲区到用户缓冲区也不等待;
市面上没有成熟的框架,因为内核缓冲区copy到用户缓冲区过程性能消耗很低,基本忽略。
阻塞与非阻塞、同步与异步区别:
同步和异步是消息通讯的机制,阻塞和非阻塞是函数调用机制。
又分为同步阻塞、同步非阻塞、异步阻塞、异步非阻塞
1 并发
并发是指一个时间段内,有几个程序在同一个cpu上执行,但是同一时刻,只有一个程序在cpu上运行
比如跑步,鞋带开了,停下跑步,系鞋带
2 并行
指任意时刻点上,有多个程序同时运行在多个cpu上
比如跑步,边跑步边听音乐
3 同步:
指代码调用io操作时,必须等待io操作完成才返回的调用方式
4 异步
异步是指代码调用io操作时,不必等io操作完成就返回调用方式
5 阻塞
指调用函数时候,当前线程别挂起
6 非阻塞
指调用函数时候,当前线程不会被挂起,而是立即返回
相关文章:

算法、语言混编、分布式锁与分布式ID、IO模型
一、算法初识 数据结构和算法是程序的基石。我们使用的所有数据类型就是一种数据结构(数据的组织形式),写的程序逻辑就是算法。 算法是指用来操作数据、解决程序问题的一组方法。 对于同一个问题,使用不同的算法,也…...

代码随想录 Day26 贪心 01 全集 LeetCode455 分发饼干 LeetCodeT346摆动序列 LeetCdoe T53 最大子数组和
前言:贪心无套路 本质: 局部最优去推导全局最优 两个极端 贪心算法的难度一般要么特别简单,要么特别困难,所以我们只能多见识多做题,记住无需数学证明,因为两道贪心基本上毫无关系,我们只需要去思考局部最优即可 贪心的小例子 比如有一堆钞票,你可以拿走十张&#x…...
【前端vue面试】TypeScript
目录 快速入门0、TypeScript简介1、TypeScript 开发环境搭建2、基本类型3、编译选项4、webpack5、Babel面向对象1、类(class)2、面向对象的特点3、接口(Interface)4、泛型(Generic)快速入门 0、TypeScript简介 TypeScript是JavaScript的超集。它对JS进行了扩展,向JS中引…...
vue-next-admin框架的认识
最近利用这个框架二开了一个后台管理系统,这里简单介绍一下,后续会进行框架的修改等文章 1:介绍 Vue-next-admin是一个基于Vue3和Element-Plus的后台管理系统框架。它提供了一套完整的、易于扩展的后台管理界面解决方案,可用于快…...
【2024秋招】2023-9-14 最右线下后端开发二面
1 OS 1.1 讲讲什么是虚拟内存,怎么实现的 虚拟内存是一种存储器管理能力,它使得一个应用程序似乎有更多的物理内存(RAM)可用,而实际上,系统使用了一部分硬盘空间来模拟额外的 RAM。通过使用虚拟内存&…...
LeetCode 2678. 老人的数目
【LetMeFly】2678.老人的数目 力扣题目链接:https://leetcode.cn/problems/number-of-senior-citizens/ 给你一个下标从 0 开始的字符串 details 。details 中每个元素都是一位乘客的信息,信息用长度为 15 的字符串表示,表示方式如下&#…...

java--三元运算符、运算符的优先级
1.三元运算符介绍 1.格式:条件表达式?值1:值2; 2.执行流程:首先计算关系表达式的值,如果值为true,返回值1,如果为false,返回值2 2.运算符优先级 1.在表达式中…...
在推荐系统中,BPRloss、Embloss、CrossEntropyloss是怎么计算的,代表的意义是什么
一、BPRloss(Bayesian Personalized Ranking loss)是一种用于推荐系统中的损失函数,用于衡量预测的排序与真实的用户行为排序之间的差异。BPRloss的计算过程如下: 输入:BPRloss的输入包括用户u、物品i和物品jÿ…...

【Python语言速回顾】——异常文件操作
目录 一、异常 1、检测异常try语句 2、抛出异常 3、异常处理流程 二、文件操作 1、打开文件 ①文件模式acess_mode ②文件缓冲区 2、基本的文件方法 ①读和写、关闭文件 ②读取行 ③文件重命名 ④删除文件(系统中已存在的文件) 3、基本的目…...

SAP POorPI RFC接口字段调整后需要的操作-针对SP24及以后的PO系统
文章目录 问题描述解决办法 问题描述 在SAP系统的RFC接口结构中添加了字段,RFC也重新引用到了PO系统,Cache和CommunicationChannel都刷新或启停了,但是新增的字段在调用接口的时候数据进不到SAP系统,SAP系统内的值也出不来。经过…...

【ArcGIS模型构建器】03:多个shp批量按属性分割(多个县区批量提取乡镇)
文章目录 一、数据预览二、模型构建三、保存模型一、数据预览 加载实验数据: 本试验实现将两个县区的数据分割为乡镇数据。 二、模型构建 1. 添加数据文件夹 将县区数据所在的根目录文件夹拖进模型。 2. 添加要素类迭代器 插入→迭代器→要素类。 用连接工具,将数据文件…...
JavaScript中JSON和Bom对象模型
JSON JSON是一种轻量级的数据交换格式 简洁和清晰的层次结构使得JSON成为理想的数据交换语言 易于人们解析和生成,并有效的提升网络传输效率 javaScript一切皆为对象,任何js支持的对象都可以使用JSON来表示 格式: 对象都用[] 数组都用{}…...

Ubuntu下载、安装QGIS软件的方法
本文介绍在Linux操作系统Ubuntu版本中,通过命令行的方式,配置QGIS软件的方法。 在Ubuntu等Linux系统中,可以对空间信息加以可视化的遥感、GIS软件很少,比如ArcGIS下属的ArcMap就没有对应的Linux版本(虽然有ArcGIS Serv…...
spring sharding JDBC 动态调整数据库连接
spring sharding JDBC 动态调整数据库连接 通过重写ShardingSphereDataSource类来实现 代码 package org.apache.shardingsphere.driver.jdbc.core.datasource;import com.alibaba.druid.pool.DruidDataSource; import lombok.extern.slf4j.Slf4j; import org.apache.shardi…...

解决CondaHTTPError HTTP 000 CONNECTION FAILED for url解决方法
解决CondaHTTPError: HTTP 000 CONNECTION FAILED for url解决方法 问题:使用conda install命令安装包提示CondaHTTPError: HTTP 000 CONNECTION FAILED for url 分析:网络连接问题,大概率是网速不行或者源没有换 解决方案:修改国…...

10 创建型模式-原型模式
引言: 创建对象的五种方式: 通过new关键字通过Class类的newInstance()方法通过Constructor类的newInstance()方法利用Clone方法反序列化 Clone方法: 其实现方式正是通过调用 Object 类的 clone() 方法来完成。 protected native Object cl…...

MSQL系列(七) Mysql实战-SQL语句Join,exists,in的区别
Mysql实战-SQL语句Join,exists,in的区别 前面我们讲解了索引的存储结构,BTree的索引结构,以及索引最左侧匹配原则及讲解一下常用的SQL语句的优化建议,今天我们来详细讲解一下 我们经常使用的 join, exist&…...

最新壁纸自动采集系统网站PHP源码/360壁纸官方数据接口采集/ZHEYI采集源码
源码介绍: 最新壁纸自动采集系统网站PHP源码,它是ZHEYI自动采集源码,能够在360壁纸官方数据接口采集。很好用的壁纸网站源码分享,仅供学习,请勿商用。 ZHEYI自动采集壁纸PHP源码,能全自动采集高清壁纸网源…...

Redis在分布式场景下的应用
分布式缓存 缓存的基本作用是在高并发场景下对应服务的保护缓冲 – 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题: redis由于高强度性能采用内存 但是意味着丢失的风险单结点redis并发能力有限分布式服务中数据过多 依赖内存的redis 明显单机不…...

2316. 统计无向图中无法互相到达点对数
2316. 统计无向图中无法互相到达点对数 难度: 中等 来源: 每日一题 2023.10.21 给你一个整数 n ,表示一张 无向图 中有 n 个节点,编号为 0 到 n - 1 。同时给你一个二维整数数组 edges ,其中 edges[i] [ai, bi] 表示节点 ai 和 bi 之间…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...