算法、语言混编、分布式锁与分布式ID、IO模型

news2024/11/26 5:36:22

一、算法初识

数据结构和算法是程序的基石。我们使用的所有数据类型就是一种数据结构(数据的组织形式),写的程序逻辑就是算法。

算法是指用来操作数据、解决程序问题的一组方法。

对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源(空间复杂度)和时间(时间复杂度)却会有很大的区别。

时间维度:是指执行当前算法所消耗的时间,我们通常用「时间复杂度」来描述。
空间维度:是指执行当前算法需要占用多少内存空间,我们通常用「空间复杂度」来描述。
常见的时间复杂度量级有(大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 cdll

lib = 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 Redlock

dlm = 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_time
    lock = "string:lock:" + lock_name
    while time.time() < end:
        if redis_client.setnx(lock, identifier):
            # 给锁设置超时时间, 防止进程崩溃导致其他进程无法获取锁
            redis_client.expire(lock, time_out)
            return identifier
        elif 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_name
    pip = redis_client.pipeline(True)
    while True:
        try:
            pip.watch(lock)
            lock_value = redis_client.get(lock)
            if not lock_value:
                return True

            if lock_value.decode() == identifier:
                pip.multi()
                pip.delete(lock)
                pip.execute()
                return True
            pip.unwatch()
            break
        except redis.excetions.WacthcError:
            pass
    return 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 非阻塞
指调用函数时候,当前线程不会被挂起,而是立即返回

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1122554.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++笔记之初始化二维矩阵的方法

C笔记之初始化二维矩阵的方法 —— 2023年5月20日 上海 code review! 文章目录 C笔记之初始化二维矩阵的方法一.常见方法1. 使用数组2. 使用向量3. 使用数组的动态分配4. 使用嵌套的 std::vector 并使用resize方法5. 初始化固定大小的 std::array 二.C中使用vector初始化二维矩…

Python基础入门例程3-NP3 读入字符串

描述 小白正在学习Python&#xff0c;从变量输出开始。请使用input函数读入一个字符串&#xff0c;然后将其输出。 输入描述&#xff1a; 输入一行字符串。 输出描述&#xff1a; 将读入的变量输出。 示例1 输入&#xff1a; Nowcoder 复制输出&#xff1a; Nowcoder…

本周技术概要20231016-20231022与生活点滴

本周包了饺子&#xff0c;辣椒油整的也不错&#xff0c;不过包饺子上升的空间还很大。 饺子美照&#xff1a; 一、linux下Qt treeView内存泄漏 当把原来Qt程序由ubuntu 32位的程序迁移到ubuntu 64位时&#xff0c;测试程序发现了内存泄漏问题&#xff0c;经过排查&#xff0c;最…

java版opencv之Javacv各种场景使用案例

文章目录 1.关于Javacv~~2. [官网下载最新OpenCV4.8](https://opencv.org/releases/)&#xff0c;并解压~~ *不一定要安装opencv*~~3. 将opencv的jar包及动态库dll文件引入项目~~4.pom引入javacv库5.测试5.1 图片美颜5.2 图片人脸检测5.3 提取视频中的语音5.4 音视频剪辑5.5 录…

Python基础入门例程2-NP2 多行输出

描述 将字符串 Hello World! 存储到变量str1中&#xff0c;再将字符串 Hello Nowcoder! 存储到变量str2中&#xff0c;再使用print语句将其打印出来&#xff08;一行一个变量&#xff09;。 输入描述&#xff1a; 无 输出描述&#xff1a; 第一行输出字符串Hello World!&a…

N——>BatchSize 数据维度理解和处理(chun, cat, squeeze, unsqueeze)

数据处理之N——>BatchSize N——>batch_size train_data TensorDataset(torch.Tensor(x_train).double(), torch.Tensor(y_train).double()) train_loader DataLoader(train_data, batch_sizeargs.bs, shuffleTrue, drop_lastTrue) for batch_idx, (inputs, results…

计算机网络第二章习题_物理层

1.用香农公式计算一下,假定信道带宽为为3100Hz,最大信道传输速率为35Kb/s ,那么若想使最大信道传输速率增加60%,问信噪比S/N应增大到多少倍?如果在刚才计算出的基础上将信噪比S/N再增大到十倍&#xff0c;问最大信息速率能否再增加20%? 问题刨析: (1)香农公式是什么? 带宽受…

css伪类元素使用技巧 表达input父级聚焦css实现

:focus-within 可以让它自己被聚焦或者它的后代元素被聚焦input 中有required 加星号在这里插入图片描述

TCP--拥塞控制

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家来访。 TCP中另一个重要的点就是拥塞控制&#xff0c;TCP是无私的当它感受到网络拥堵了&#xff0c;就…

【计算机网络】IP协议的相关特性

IP协议&#xff1a;互联网的核心组件 在当今高度数字化的世界中&#xff0c;互联网已成为人们生活、工作不可或缺的一部分。而在这个庞大的网络中&#xff0c;IP协议&#xff08;Internet Protocol&#xff09;作为核心的通信协议&#xff0c;发挥着至关重要的作用。本文将详细…

ES6有何新特性?

目录 介绍 let 和 const 解构 模板字符串 箭头函数 Set Map 介绍 ES 全称是ECMAScript&#xff0c;它是JavaScript基础构建的一种语言&#xff0c;JavaScript正是建立在ECMAScript语言的基础规范中建立使用的。ES6实际上是一个泛指&#xff0c;泛指ES2015及后续的版本…

【BP-Adaboost预测】基于BP神经网络的Adaboost的回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

20231022 - Day42 总结 Week06 周结

20231022 - Day42 总结 && Week06 周结 今日计划&#xff1a; 早起看JavaEE√午饭前看看复习计组√午睡前背单词√下午复习Java√晚上前跑步√晚上复习JavaEE和Java基础√睡前看英语抽空看书 今日进度&#xff1a; Java&#xff1a;上课看韩顺平老师P910&#xff0…

Linux-管道、环境变量、常用命令

文章目录 管道概念要点与文件重定向的区别 环境变量概念查看 常用命令查看系统状况权限文件查找 用户相关工具 管道 概念 管道的作用类似于文件重定向&#xff0c;可以将前一个命令的stout做为下一个命令的stdin 要点 管道命令进处理stdout&#xff0c;会忽略stderr管道右边…

【PyTorch实战演练】自调整学习率实例应用(附代码)

目录 0. 前言 1. 自调整学习率的常用方法 1.1 ExponentialLR 指数衰减方法 1.2 CosineAnnealingLR 余弦退火方法 1.3 ChainedScheduler 链式方法 2. 实例说明 3. 结果说明 3.1 余弦退火法训练过程 3.2 指数衰减法训练过程 3.3 恒定学习率训练过程 3.4 结果解读 4. …

Jenkins 相关内容

Jenkins 相关内容 什么是 Jenkins&#xff0c;它是如何工作的&#xff1f;Jenkins 中自由式项目和管道之间的区别什么是Jenkins管道&#xff0c;它们如何工作&#xff1f;第一次如何安装Jenkins并进行设置&#xff1f;什么是 Jenkins 插件&#xff0c;如何安装它们&#xff1f;…

中间件安全-CVE复现WeblogicJenkinsGlassFish漏洞复现

目录 服务攻防-中间件安全&CVE复现&Weblogic&Jenkins&GlassFish漏洞复现中间件-Weblogic安全问题漏洞复现CVE_2017_3506漏洞复现 中间件-JBoos安全问题漏洞复现CVE-2017-12149漏洞复现CVE-2017-7504漏洞复现 中间件-Jenkins安全问题漏洞复现CVE-2017-1000353漏…

【问题记录】解决Qt连接MySQL报“QMYSQL driver not loaded”以及不支持MySQL事务操作的问题!

环境 Windows 11 家庭中文版&#xff0c;64 位操作系统, 基于 x64 的处理器Qt 5.15.2 MinGW 32-bitmysql Ver 14.14 Distrib 5.7.42, for Win32 (AMD64) 问题情况 在Qt 5.15.2 中编写连接MySQL数据库代码后&#xff0c;使用 MinGW 32-bit 构建套件进行编译运行后&#xff0c;报…

Python基础入门例程5-NP5 格式化输出(一)

描述 牛牛、牛妹和牛可乐正在Nowcoder学习Python语言&#xff0c;现在给定他们三个当中的某一个名字name&#xff0c; 假设输入的name为Niuniu&#xff0c;则输出 I am Niuniu and I am studying Python in Nowcoder! 请按以上句式输出相应的英文句子。 输入描述&#xff1…

驱动开发1 概念、内核模块编程、内核消息打印函数printk函数的使用、内核模块传参、内核导出符号

1 驱动相关概念 2 内核模块编程 内核模块编写实例代码注释 #include <linux/init.h> #include <linux/module.h>//入口函数&#xff0c;安装内核模块时执行 static int __init mycdev_init(void) {//static 修饰当前函数只能在本文件使用//int 函数的返回值类型&a…