MySQL数据库

数据库的常用命令 #在MySQL中查看MySQL版本号 select version(); #查看当前数据库中都有哪些库 show databases; #切换到MySQL库 use mysql #查看库中有几个表 show tables; SQL语句概述 SQL语言 Structured Query Language的缩写,及结构化查询语言 关系型数据库的标准语言 用于维护管理数据库 包括数据查询,数据更新,访问控制,对象管理等功能 SQL分类 DDL:数据定义语言 DML:数据操纵语言 DQL:数据查询语言 DCL:数据控制语言 创建数据库和表 DDL语句可用于创建数据库对象,如库,表,索引等。 使用DDL语句新建库,表 创建数据库 CREATE DATABASE 数据库名 创建数据表 CREATE TABLE 表名 (字段定义......) #创建数据库 create databates kgc; #查看数据库 show database; #创建表并且创建内容设置条件 create table kgc.kc65 (id int(11) not null, name varchar(255) ,age int(11)); #切换到数据库 use kgc #查看数据库中的表 show tables 删除数据库和表 使用DDL语句删除库,表 删除指定的数据表 DROP TABLE [数据库名] 表名

python-爬虫实例(4):获取b站的章若楠的视频

目录 前言 道路千万条,安全第一条 爬虫不谨慎,亲人两行泪 获取b站的章若楠的视频 一、话不多说,先上代码 二、爬虫四步走 1.UA伪装 2.获取url 3.发送请求 4.获取响应数据进行解析并保存 总结 前言 道路千万条,安全第一条 爬虫不谨慎,亲人两行泪 获取b站的章若楠的视频 不要问,问就是博主喜欢,嘿嘿嘿嘿(流口水) 一、话不多说,先上代码 # 请求b站视频 import json import requests from lxml import etree if __name__ == '__main__': head = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0" , # 防盗链 "Referer": "https://www.bilibili.com/" , "Cookie": "buvid3=3EEF3EE1-472C-F430-105F-0E4F321F331C25161infoc; b_nut=1720613925; _uuid=46847D108-EFD1-9828-99910-32119EADB6EB26022infoc; enable_web_push=DISABLE; buvid4=E9918A3A-008D-2748-2B1F-78B04E8CCA5825688-024071012-IYJQtQw8DTdtrI0uY1UGvQ%3D%3D; buvid_fp=adf3cfaf35396cd4f051041d58ea252d; DedeUserID=455536180; DedeUserID__ckMd5=ece5cba51b3582b0; header_theme_version=CLOSE; rpdid=|(Y|RJRRJ~m0J'u~k|YuR|k); hit-dyn-v2=1; CURRENT_BLACKGAP=0; CURRENT_FNVAL=4048; CURRENT_QUALITY=80; b_lsid=FA4254F2_190DA67F5A6; bmg_af_switch=1; bmg_src_def_domain=i0.

【QT】事件分发器 & 事件过滤器

qt 系统 - 事件分发器 and 事件过滤器 一、事件分发器1. 事件分发器概念2. 事件分发器工作原理 二、事件过滤器 一、事件分发器 1. 事件分发器概念 在 Qt 中,事件分发器(Event Dispatcher) 是一个核心概念,用于处理 GUI 应用程序中的事件。事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消。每个继承自 QObject 类或 QObject 类本身都可以在本类中重写 bool event(QEvent *e) 函数,来实现相关事件的捕获和拦截。 2. 事件分发器工作原理 在 Qt 中,我们发送的事件都是传给了 QObject 对象,更具体点是传给了 QObject 对象的 event() 函数。所有的事件都会进入到这个函数里面,那么我们处理事件就要重写这个 event() 函数。event() 函数本⾝不会去处理事件,而是根据 事件类型(type值)调用不同的事件处理函数。事件分发器就是工 作在应用程序向下分发事件的过程中,如下图: 如上图,事件分发器⽤于分发事件。在此过程中,事件分发器也可以做拦截操作。事件分发器主要是通过 bool event(QEvent *e) 函数来实现。其返回值为布尔类型,若为 ture,代表拦截,不向下分发。 Qt 中的事件是封装在 QEvent 类中,在 Qt 助手中输入 QEvent 可以查看其所包括的事件类型,如下图示: 示例代码: 1、在 “widget.h” 头⽂件中声明 ⿏标点击事件 和 事件分发器;如下图⽰: class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); // 鼠标点击事件 void mousePressEvent(QMouseEvent* event); // 通过事件分发器拦截鼠标按下事件 bool event(QEvent* event); private: Ui::Widget *ui; }; 2、在 “widget.

go-kratos 学习笔记(7) 服务发现服务间通信grpc调用

服务发现 Registry 接口分为两个,Registrar 为实例注册和反注册,Discovery 为服务实例列表获取 创建一个 Discoverer 服务间的通信使用的grpc,放到data层,实现的是从uses服务调用orders服务 app/users/internal/data.go 加入 NewDiscovery和 NewOrderServiceClient,需要把新加的2个方法加入到 ProviderSet 需要把新生成的orderClient注入到Data里面 orderClient orders.OrderClient package data import ( "context" "github.com/go-kratos/kratos/contrib/registry/nacos/v2" "github.com/go-kratos/kratos/v2/log" "github.com/go-kratos/kratos/v2/middleware/recovery" "github.com/go-kratos/kratos/v2/registry" "github.com/go-kratos/kratos/v2/transport/grpc" "github.com/google/wire" "github.com/nacos-group/nacos-sdk-go/clients" "github.com/nacos-group/nacos-sdk-go/common/constant" "github.com/nacos-group/nacos-sdk-go/vo" "gorm.io/driver/mysql" "gorm.io/gorm" "time" "xgs_kratos/gen/config/users" "xgs_kratos/gen/orders" ) // ProviderSet is data providers. var ProviderSet = wire.NewSet(NewData, NewDiscovery, CreateRegister, NewOrderServiceClient, NewUserRepo) // Data . type Data struct { // TODO wrapped database client db *gorm.DB log *log.Helper orderClient orders.OrderClient } // NewData .

安装nfs和rpcbind设置linux服务器共享磁盘

1、安装nfs和rpcbind 1.1 检查服务器是否安装nfs和rpcbind,执行下命令,检查服务器是否安装过。 rpm -qa|grep nfs rpm -qa|grep rpcbind 说明服务器以安装了,如果没有就需要自己安装 2、安装nfs和rpcbind 将rpm安装包: libtirpc-0.2.4-0.10.el7.x86_64、nfs-utils-1.2.3-54.el6.x86_64、nfs-utils-lib-1.1.5-9.el6.x86_64、rpcbind-0.2.0-11.el6.x86_64 4个包传到服务器(nfs服务端:172.31.5.130 客户端:172.31.5.134) 用rpm –ivh 安装包名 --nodeps 命令安装这个4个包,优先装libtirpc-0.2.4-0.10.el7.x86_64 2.1检查nfs和rpcbind执行命令查看: rpm -qa|grep nfs rpm -qa|grep rpcbind 将172.31.5.130 /home/download 目录共享给172.31.5.134服务器 现在172.31.3.130 /home/下建立download文件夹:mkdir download 给文件赋较大的权限 在nfs服务端172.31.5.130服务上执行命令,vi /etc/exports编辑。内容如下 /home/download 172.31.5.134(insecure,rw,sync,no_root_squash) :wq! 保存 2.2 启动nfs和rpcbind 2台服务器都要启动 先启动rpcbind: service rpcbind start 检查rpcbind 状态: service rpcbind status 在启动nfs: service nfs start 检查nfs状态: service nfs status 3、到客户端挂载(172.31.5.134) 为方便记忆我们建一个和172.31.5.130一样的文件路径,/home/download mount -t nfs 172.31.5.130:/home/download /home/download 或者 mount -t nfs -o nolock,nfsvers=3,vers=3 172.

AWS免费层之后:了解和管理您的云服务成本

Amazon Web Services (AWS) 为新用户提供了12个月的免费层服务,这是许多人开始使用云服务的绝佳方式。但是,当这一年结束后,您的AWS使用会如何变化?我们九河云通过本文将探讨免费层结束后的AWS成本情况,以及如何有效管理您的云支出。 免费层结束后的情况: 1. 收费开始:一旦12个月免费期结束,您将开始为使用的所有AWS服务付费。 2. 按使用付费:AWS采用按需付费模式,您只需为实际使用的资源付费。 3. 部分服务仍免费:某些服务(如Amazon CloudWatch)在有限范围内永久免费。 潜在成本来源: 1. 计算资源:如EC2实例运行时间。 2. 存储:如S3存储空间使用量。 3. 数据传输:进出AWS的数据流量。 4. 数据库服务:如RDS实例运行时间。 5. 其他专业服务:如机器学习或IoT服务。 管理AWS成本的策略: 1. 了解您的使用情况: - 使用AWS Cost Explorer分析支出。 - 设置预算警报,防止意外超支。 2. 优化资源使用: - 关闭不需要的实例和服务。 - 使用自动扩展根据需求调整资源。 3. 选择合适的定价模式: - 考虑预留实例或Savings Plans以降低长期成本。 - 对于可中断工作负载,使用Spot实例。 4. 利用AWS成本管理工具: - 使用AWS Budgets设置支出限制。 - 应用标签策略,跟踪不同项目的成本。 5. 定期审核和优化: - 定期检查账单,识别异常支出。 - 考虑使用AWS Trusted Advisor获取优化建议。 6. 教育和最佳实践: - 确保团队了解云成本优化的重要性。 - 实施FinOps实践,将财务责任融入技术决策。 结论: AWS免费层结束后,您的云使用确实会开始产生成本。然而,通过深入了解AWS的定价模型,积极管理资源使用,并利用AWS提供的成本管理工具,您可以有效控制和优化云支出。记住,云计算的灵活性意味着您可以精确调整资源以匹配实际需求,从而实现成本效益的最大化。

美团后端二面

美团后端二面 ……………………………… 两道场景 一道 数字转中文读法(1000-》一千) 0八股0自我介绍 反问 “您觉得我能过吗?” “这个需要横行对比之后才能有结果” ……………………………… 什么时候到岗 场景题 1 假设我有一个文本文件。这个文本文件每一行都是一个长度不固定的,由英文字符跟阿拉伯数字组成的字符串。但是它的长度不固定。就是文件也比较大。我现在需要您在内存有限的情况下去统计出这个文本文件当中出现次数最多的5个字符串。 分治 分小文件hash ,然后每个取top5,然后总的取top5 ……………………………… 场景题 2 比如说我们现在在搞一个大促对吧?我们现在在卖商品,然后商品卖商品通常都会有一个这样的一个功能,就是榜单。就是说我们每卖一件商品,我往一个文件当中去写一个这个商品的 ID 对吧?然后商品的编码。然后我是进行大促的那一刻开始到当前我们卖的最好的100件商品的一个榜单。啊那这是一个实际的业务场景了。 一开始没答道点子上,面试官引导他没限制内存, 然后又引导 (在不影响业务的情况下,降低成本) 排行榜不需要很精准 排行榜需要尽快返回 面试官:其实我想问的是说如何尽量地节约成本 后面又提到pipeline的思想 不要一次一次传输,累计传输一下 编程精选网(www.codehuber.com),程序员的终身学习网站已上线! 如果这篇【文章】有帮助到你,希望可以给【JavaGPT】点个赞👍,创作不易,如果有对【后端技术】、【前端领域】感兴趣的小可爱,也欢迎关注❤️❤️❤️ 【JavaGPT】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💝💝💝!

LeetCode206 反转链表

前言 题目: 206. 反转链表 文档: 代码随想录——反转链表 编程语言: C++ 解题状态: 有了思路以后没敢尝试 思路 需要注意的是创建指针不会申请额外的内存空间。 代码 方法一: 双指针法/迭代 我的理解是创建了三个指针,前中后各一个,进行滑动。先把 n e x t next next节点保存在后面的指针中,再把当前节点的 n e x t next next指针指向前面一个节点,然后一起平移这三个指针。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { ListNode* tmp; ListNode* cur = head; ListNode* pre = nullptr; while (cur) { tmp = cur -> next; cur -> next = pre; pre = cur; cur = tmp; } return pre; } }; 时间复杂度: O ( n ) O(n) O(n)空间复杂度: O ( 1 ) O(1) O(1) 方法二: 递归 有点抽象,不是特别理解递归代表的具体含义,应该是封装了平移指针的操作。

LeetCode 2844.生成特殊数字的最少操作(哈希表 + 贪心)

给你一个下标从 0 开始的字符串 num ,表示一个非负整数。 在一次操作中,您可以选择 num 的任意一位数字并将其删除。请注意,如果你删除 num 中的所有数字,则 num 变为 0。 返回最少需要多少次操作可以使 num 变成特殊数字。 如果整数 x 能被 25 整除,则该整数 x 被认为是特殊数字。 示例 1: 输入:num = "2245047" 输出:2 解释:删除数字 num[5] 和 num[6] ,得到数字 "22450" ,可以被 25 整除。 可以证明要使数字变成特殊数字,最少需要删除 2 位数字。 示例 2: 输入:num = "2908305" 输出:3 解释:删除 num[3]、num[4] 和 num[6] ,得到数字 "2900" ,可以被 25 整除。 可以证明要使数字变成特殊数字,最少需要删除 3 位数字。 示例 3: 输入:num = "10" 输出:1 解释:删除 num[0] ,得到数字 "0" ,可以被 25 整除。 可以证明要使数字变成特殊数字,最少需要删除 1 位数字。 提示

【C++】深度解析:用 C++ 模拟实现 list 类,探索其底层实现细节

目录 list介绍 list模拟实现 list 节点类 list 的迭代器 定义 构造函数 解引用 operator前置++和--与后置++和-- operator==与operator!= list 类 构造函数 begin()和end() 拷贝构造 erase() clear() 析构函数 insert push_back 和 push_front pop_back 和 pop_front 完整代码 ⭐list介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list 的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)。 ⭐list模拟实现 list的底层是双向链表结构,包含有一个哨兵节点。模拟实现list,要实现下列三个类: ①list节点类 ②迭代器的类 ③list主要功能的类(size(),empty()...) 模拟实现list的类的基本功能(增删等操作)要建立在迭代器类和节点类均已实现好的情况下才得以完成。 ✨list 节点类 定义list中的节点ListNode,包含前驱指针,后驱指针和数据变量;使用struct而不使用class定义类,是为了方便访问每个一个节点 ,struct默认是pbulic,而class中成员变量要定义为private,不方便访问。 template<class T> struct ListNode { ListNode<T>* _next; ListNode<T>* _prev; T _data; ListNode(const T& x = T()) :_next(nullptr) ,_prev(nullptr) ,_data(x) {} }; ✨list 的迭代器 迭代器有两种实现方式,具体应根据容器底层数据结构实现: 1. 原生态指针,比如:vector 2. 将原生态指针进行封装,因迭代器使用形式与指针完全相同,因此在自定义的类中必须实现以下方法:

Ubuntu22.04安装Go语言的几种方式

在 Ubuntu 22.04 上安装 Go 语言可以通过几种不同的方法,以下是两种常见的安装方法: 方法1:使用 go 官方安装脚本 打开终端。 下载 Go 语言的安装脚本: curl -O https://go.dev/dl/go1.22.5.linux-amd64.tar.gz 请检查 Go 官方网站以获取最新版本的下载链接。 解压下载的文件: sudo tar -xzf go1.22.5.linux-amd64.tar.gz -C /usr/local 这将把 Go 安装到 /usr/local/go 目录。 配置 Go 环境变量。将以下行添加到你的 ~/.profile 或 ~/.bashrc 文件中: export PATH=$PATH:/usr/local/go/bin export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin 应用配置更改: source ~/.profile # 或者如果你使用的是 .bashrc source ~/.bashrc 验证安装: go version 方法2:使用包管理器(如果可用) 虽然 Ubuntu 22.04 的默认仓库可能没有 Go 语言的最新版本,但你可以尝试使用包管理器来安装: 更新包列表: sudo apt update 安装 Go 语言:

【ffmpeg命令入门】视频的旋转与翻转

文章目录 前言什么时候需要使用旋转与翻转1. 视频拍摄方向不正确2. 视频编辑特效使用什么参数1. 旋转视频 - `transpose`2. 水平翻转视频 - `hflip`3. 垂直翻转视频 - `vflip` 总结 前言 在视频编辑的过程中,我们经常会遇到需要旋转或翻转视频的情况。无论是因为拍摄时相机方向不正确,还是为了实现特定的视觉效果,掌握视频旋转与翻转的技巧都是十分必要的。在这篇文章中,我们将简要介绍 FFmpeg 命令中用于旋转与翻转视频的参数和使用场景。 什么时候需要使用旋转与翻转 1. 视频拍摄方向不正确 有时我们在用手机或相机拍摄视频时,由于设备方向没有调整好,导致视频播放时方向不正确。这时需要通过旋转视频来修正其方向。 2. 视频编辑特效 在一些视频编辑项目中,我们可能需要通过旋转或翻转视频来实现特定的视觉效果。例如,为了创造镜像效果,可以对视频进行水平翻转;为了实现一些独特的动画效果,可能需要对视频进行旋转。 使用什么参数 FFmpeg 提供了多种视频旋转和翻转的滤镜,主要包括 transpose、hflip 和 vflip。下面我们详细介绍这些参数及其取值。 1. 旋转视频 - transpose transpose 滤镜用于旋转视频,可以有以下取值: transpose=0:将视频顺时针旋转 90 度并水平翻转。这意味着视频不仅被旋转了 90 度,还被左右颠倒了。 transpose=1:将视频顺时针旋转 90 度。这只是一个简单的顺时针旋转,没有额外的翻转操作。 transpose=2:将视频逆时针旋转 90 度。这个操作只是逆时针旋转 90 度,没有额外的翻转。 transpose=3:将视频逆时针旋转 90 度并水平翻转。这意味着视频不仅被逆时针旋转了 90 度,还被左右颠倒了。 示例: ffmpeg -i input.mp4 -vf "transpose=1" -c:a copy output.mp4 此命令将视频顺时针旋转 90 度。 2. 水平翻转视频 - hflip hflip 滤镜用于将视频水平翻转(左右镜像)。

c++初阶知识——string类详解

目录 前言: 1.标准库中的string类 1.1 auto和范围for auto 范围for 1.2 string类常用接口说明 1.string类对象的常见构造 1.3 string类对象的访问及遍历操作 1.4. string类对象的修改操作 1.5 string类非成员函数 2.string类的模拟实现 2.1 经典的string类问题 2.2 浅拷贝 2.3 深拷贝 2.4 string类实现 3.写时拷贝 前言: C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列 的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户 自己管理,稍不留神可能还会越界访问。 1.标准库中的string类 在使用string类时,必须包含#include头文件以及using namespace std; 1.1 auto和范围for auto (1)在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期 推导而得。 (2)用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加& (3)当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。 (4)auto不能作为函数的参数,可以做返回值,但是建议谨慎使用 (5)auto不能直接用来声明数组 #include <map> using namespace std; int main() { std::map<std::string, std::string> dict = { { "apple", "苹果" },{ "orange", "橙子" }, {"pear","梨"} }; // auto的用武之地 //std::map<std::string, std::string>::iterator it = dict.

【动态规划】力扣.213. 打家劫舍 II

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。 给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。 示例 1: 输入:nums = [2,3,2] 输出:3 解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。 示例 2: 输入:nums = [1,2,3,1] 输出:4 解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。 偷窃到的最高金额 = 1 + 3 = 4 。 示例 3: 输入:nums = [1,2,3] 输出:3 代码 class Solution { public: int rob(vector<int>& nums) { if(nums.empty()){ return 0; } if(nums.size() == 1){ return nums[0]; } vector<int>dp1(nums.

数据结构与算法--【数组2】力扣练习 || 双指针 / 移除元素 / 数组排序

注意:官方说法,快慢指针就是双指针。我在文章用两种不同的叫法,主要是根据字面意思更好的区分两个指针初始的指向,以便更快确定算法怎么写。 一、移除元素 对于数组来说,移除元素只是进行元素的“覆盖”。 解法:快慢指针法(两个指针初始位置都指向数组开头) 练习一:数组移除元素 力扣链接 题目描述: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作: 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。 返回 k。 题目分析 题目要求我们移除(删掉)数组中的元素。但我们必须清楚一点:数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。对于数组,“删除”体现在实际算法中就是“覆盖”。 直接忽略要删除的值,重点关注剩下要组成的数组的元素,这句话在下面算法中体现在if判断语句。没有创建新数组,是对旧数组做一个“大扫除”。 代码 int removeElement(int* nums, int numsSize, int val) { int slow = 0; for(int fast = 0; fast < numsSize; fast++){ if(nums[fast] != val){ //如果不是要删除的值,放进数组里 nums[slow++] = nums[fast]; //nums[fast]先赋给nums[slow],后slow++ } } return slow; } 练习二:删除有序数组中的重复项 力扣链接

[C++][STL源码剖析] 详解AVL树的实现

目录 1.概念 2.实现 2.1 初始化 2.2 插入 2.2.1 旋转(重点) 左单旋 右单旋 双旋 2.❗ 双旋后,对平衡因子的处理 2.3 判断测试 完整代码: 拓展:删除 1.概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。 因此,两位俄罗斯的数学家G.M.Adelson-Velskii 和E.M.Landis在1962年 发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右 子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度。 一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树: 它的左右子树都是AVL树 左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1) 高度之差=右子树高度 - 左子树高度 AVL == 高度平衡二叉树搜索树 由于AVL树的自平衡特性,它适用于需要频繁插入和删除操作的场景,尤其是对于需要快速搜索和有序遍历的数据集合。 平衡为什么不是高度差相等,而是高度差不超过 1? 为了涵盖更多的情况,例如为节点个数为 4 如下,高度差 1 也相对平衡了 为什么 满二叉树和 AVL 树是同一个 level? 增删查改:高度次->O(logN) 最后一 h 层有 2^(h-1)个节点 满二叉树 2^h-1=N AVL 树 2^h-X=N //最后一行还存在缺失 X 范围:[1, 2^(h-1)-1] 满二叉树和 AVL 树 在量级上都是约等于 log N 的 2.实现 2.1 初始化 AVL树的节点定义包括以下几个属性:

学Python该看什么书?10本Python好书推荐,10年程序员倾囊相授!

学习Python时,选择合适的书籍对于掌握这门语言至关重要。以下是一些推荐的Python学习书籍,它们涵盖了从入门到进阶的不同阶段,适合不同水平的读者: 入门书籍 1.《Python编程:从入门到实践》 作者:埃里克·马瑟斯(Eric Matthes)简介:这本书是Python入门的经典之作,通过实际项目引导读者学习Python编程,内容涵盖基础语法、面向对象编程、Web编程和数据分析等多个方面。适合完全没有任何编程经验的初学者。 2.《Python基础教程》 作者:Magnus Lie Hetland简介:本书详细讲解了Python的基本语法、流程控制、数据结构以及面向对象编程等知识点,并通过大量示例代码帮助读者加深理解。对于想要系统学习Python的初学者来说,这是一本非常实用的教材。 我私藏了很多技术干货,粉丝白嫖可以点这里 3.《Python编程快速上手 第二版》 作者:Al Sweigart简介:本书是一本面向初学者的Python编程实用指南。本书不仅介绍了Python语言的基础知识,而且通过案例实践教读者如何使用这些知识和技能。 4.《Python程序设计(第3版)》 作者:John Zelle简介:这本书不仅介绍了Python的基本语法,还深入探讨了计算机科学和编程的相关概念。它以最适合初学者的方式呈现这些内容,使得读者能够轻松理解并掌握。 进阶书籍 《流畅的Python》 作者:Luciano Ramalho简介:这本书适合有一定Python编程经验的读者。它深入讲解了Python中的一些高级特性和最佳实践,如迭代器、生成器、装饰器等,并通过实际案例帮助读者提高编程技巧。《Python Cookbook》 作者:Brian Jones, David Beazley简介:这是一本面向中高级程序员的Python技巧手册,提供了大量实用的代码示例和解决方案。它涵盖了网络编程、并发编程、数据处理等多个方面,是Python编程的必备参考书之一。《Python并发编程实战》 虽未直接列出,但此类书籍对于想要深入学习Python并发编程的读者来说非常有用。它们详细介绍了多线程、多进程、协程等并发编程技术,并提供了实际案例进行演示。 其他推荐 《Python数据分析基础》:适合对数据分析感兴趣的读者,介绍了pandas、plotly等实用Python库的应用。《Python网络编程》:全面涵盖了Python网络编程的方方面面,包括Socket编程、HTTP协议等。《Python机器学习》:对于想要学习机器学习并使用Python实现的读者来说,这本书是不错的选择。 小结 选择Python学习书籍时,建议根据自己的学习背景和需求进行选择。对于初学者来说,可以从入门书籍开始学起,逐步掌握Python的基础知识;对于有一定基础的读者来说,可以选择进阶书籍来深入学习Python的高级特性和最佳实践。同时,也可以结合在线教程、视频课程和实战项目来提升自己的编程能力。 这里分享给大家一套免费的学习资料,包含视频、源码/电子书,希望能帮到那些不满现状,想提升自己却又没有方向的朋友,也可以加我微信一起来学习交流。 ① Python所有方向的学习路线图,清楚各个方向要学什么东西 ②Python、PyCharm学习工具包全家桶,环境配置教程视频 ③Python全套电子书籍PDF,全部都是干货知识 ④ 100多节Python课程视频,涵盖必备基础、爬虫和数据分析 ⑤ 100多个Python实战案例,学习不再是只会理论 全套Python学习资料分享:《python安装工具&全套学习资料》免费分享(安全链接,放心点击) ​ 一、Python所有方向的学习路线 Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。 ​ ​ 二、学习软件 工欲善其事必先利其器。学习Python常用的开发软件都在这里了,还有环境配置的教程,给大家节省了很多时间。 ​ 三、全套PDF电子书 书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。 ​ 四、入门学习视频全套 我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。 ​ ​ 五、实战案例 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。 ​ ​ 六、面试资料 我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。 ​ ​ 七、Python副业兼职路线 ​ ​ 这份完整版的Python全套学习资料已打包在这了:《python安装工具&全套学习资料》免费分享(安全链接,放心点击) ​

性能调优 17. GraalVM云原生时代的Java虚拟机

1. GraalVM诞生的背景 1.1. Java在微服务/云原生时代的困境及解决方案 ‌‌‌ 事实 ‌‌‌ Java总体上是面向大规模、长时间的服务端应用而设计的。 ‌‌‌ 即时编译器(JIT)、性能优化、垃圾回收等有代表性的特征需要一段时间来达到最佳性能。 ‌‌‌ 矛盾 ‌‌‌ 微服务时代对启动速度达到最高性能的时间提出了新的要求! ‌‌‌ 在微服务的背景下,提倡服务围绕业务能力构建,不再追求实现上的严谨一致。 ‌‌‌ 单个微服务就不再需要再面对数十、数百GB乃至TB的内存。 ‌‌‌ 有了高可用的服务集群,也无须追求单个服务要7×24小时不可间断地运行,它们随时可以中断和更新。 ‌‌‌ 所以微服务对应用的容器化(Docker)亲和度(包容量、内存消耗等)、启动速度、达到最高性能的时间等方面提出了新的要求,这些恰恰是Java的弱项。 ‌‌‌ 比如:现在启动一个微服务项目(Docker运行6个子服务),动不动就1分钟,如下图: ‌‌‌ 问题根源 ‌‌‌ Java离不开虚拟机。 ‌‌‌ 所以Java应用启动的时候,必须要启动虚拟机,进行类加载,无论是启动时间,还是占用空间都不是最优解。 ‌‌‌ 解决方案 ‌‌‌ 革命派 ‌‌‌ 直接革掉Java和Java生态的性命,创造新世界,譬如Golang。 ‌‌‌ 保守派 ‌‌‌ 保留原有主流Java生态和技术资产,朝着微服务、云原生环境靠拢与适应(GraaIVM)。 2. GraalVM入门 ‌‌‌ GraalVM 是一个高性能 JDK 发行版,旨在加速用Java和其它JVM语言编写的应用程序的执行(JVM不只支持Java语言),并支持 JavaScript、Ruby、Python 和许多其他流行语言(翻译自官网 https://www.graalvm.org/)。 ‌‌‌ GraalVM底层也是HosSpot,只是做了二次开发,打包成JDK。GraalVM能让支持的语言使用HotSpot虚拟机。 ‌‌‌ GraalVM可以代替对应的JDK版本使用。 ‌‌‌ GraalVM想成为一统天下的“最终”虚拟机!而GraalVM要做到原因也很简单: ‌‌‌ 大部分脚本语言或者有动态特效的语言都需要一个语言虚拟机运行,比如CPython,Lua,Erlang,Java,Ruby,R,JS,PHP,Perl,APL等等,但是这些语言的虚拟机水平很烂,比如CPython的VM就不忍直视,而HotSpotVM是虚拟机的大神级别,如果能用上HotSpot,能用上顶级的即时编译器(JIT)、性能优化、垃圾回收等技术,岂不爽歪歪! 3. GraalVM特征 ‌‌‌ 1. GraalVM是一款高性能的可嵌入式多语言虚拟机,它能运行不同的编程语言 ‌‌‌ 能运行基于JVM的语言,比如Java, Scala, Kotlin和Groovy。 ‌‌‌ 能运行解释型语言,比如JavaScript, Ruby, R和Python。

了解高防 IP

一、高防 IP 的基本概念 高防 IP 是指拥有强大防御能力的 IP 地址。它主要通过将攻击流量引流到高防机房进行清洗和过滤,再将正常的流量回注到源站,从而保障源站服务器的稳定运行。 二、高防 IP 的工作原理 当用户的服务器遭受 DDoS 攻击时,攻击流量会首先涌向用户服务器原本的 IP 地址。而配置了高防 IP 后,会在网络层面进行智能的流量牵引,将这些流量全部导向高防 IP。 高防系统会对这些涌入的流量进行实时的深度监测和全面分析。它会检查数据包的源 IP 地址、目标 IP 地址、端口号、协议类型等多个维度的信息。通过复杂的算法和模型,识别出其中的恶意攻击流量。 对于识别出的恶意流量,高防系统会采用多种先进且有效的技术手段进行处理。例如,流量清洗技术能够去除掉那些包含异常特征的数据包,如短时间内大量重复的请求、异常大的数据包等。黑洞牵引技术则会将持续的高强度攻击流量引入一个“黑洞”,使其无法对源站造成影响。限速技术可以对可疑的流量进行限速,防止其瞬间占用过多的网络资源。 在完成清洗和过滤的操作后,高防系统会将经过筛选的正常流量重新回注到用户的真实服务器,确保服务器能够正常接收和处理这些合法的请求,从而维持业务的稳定运行。 三、高防 IP 的技术优势 强大的防御能力: 能够抵御大规模的 DDoS 攻击,包括 SYN Flood、UDP Flood、ICMP Flood 等常见攻击类型,以及复杂的混合攻击。 快速响应: 具备实时监测和快速响应机制,能够在攻击发生的瞬间启动防御策略,最大程度减少攻击对业务的影响。 精准识别: 采用智能的流量分析和识别技术,能够精准区分正常流量和攻击流量,避免误判和漏判。 灵活配置: 可以根据用户的实际需求,灵活调整防御策略和防护等级,满足不同业务场景的安全要求。 四、高防 IP 的应用场景 游戏行业: 保障游戏服务器的稳定运行,防止因攻击导致游戏卡顿、掉线等问题,为玩家提供流畅的游戏体验。 电商平台: 在促销活动等高流量时期,抵御恶意攻击,确保网站的正常访问,保障交易的安全进行。 金融机构: 保护金融业务系统的安全,防止客户信息泄露和资金损失。 企业网站: 防止企业网站因攻击而瘫痪,维护企业的形象和声誉。

多GPU并行处理[任务分配、进程调度、资源管理、负载均衡]

1. 多GPU并行处理设计 设计思路: 实现基于多GPU的并行任务处理,每个GPU运行独立的任务,以加速整体的处理速度。 实现机制: 进程隔离: 利用multiprocessing.Process为每个GPU创建独立的工作进程。 GPU资源限制: 通过设置CUDA_VISIBLE_DEVICES环境变量,确保每个进程仅能访问其对应的GPU。 任务互斥: 每个GPU拥有一个Lock对象,确保同一时间只有一个任务在特定的GPU上运行。 2. 动态任务分配与负载均衡 设计思路: 通过动态分配任务至队列,实现任务的均匀分布,确保负载均衡。 实现机制: 任务队列: 使用Manager().Queue()创建共享队列,允许多进程安全地存取任务。 设备ID计算: 通过calculate_device_id函数,基于文件路径的哈希值和GPU总数,计算出任务应分配至的GPU,确保任务均匀分配。 3. 进程间通信与同步 设计思路: 确保多进程间的安全通信,避免数据竞争和死锁。 实现机制: 任务获取原子性: 利用Lock对象保护任务获取操作,确保任务获取的原子性。 进程同步: 使用task_queue.join()等待所有任务完成,确保主进程不会在所有子任务完成前退出。 优雅退出: 通过向队列中放置None信号,通知工作进程可以安全退出,实现进程间的优雅终止。 4. 异常处理与资源管理 设计思路: 提供异常处理机制,确保资源的有效管理。 实现机制: 异常捕获: 在worker函数中,使用try-except结构捕获Empty异常,处理队列为空的情况。 资源节约: 通过检查输出文件的存在性,避免重复处理,节省计算资源。 5. 性能优化与监控 设计思路: 优化任务处理流程,提供执行状态的实时反馈。 实现机制: 进度监控: 利用tqdm.write在控制台输出任务执行信息,提供直观的进度反馈。 效率提升: 通过合理的任务分配和进程设计,最大化利用多GPU资源,提升整体处理效率。 总结 该代码的关键设计聚焦于多GPU环境下的并行任务处理,通过精细的进程管理、资源调度、负载均衡策略以及异常处理机制,确保了系统的高效、稳定运行。同时,通过进程间通信和同步机制,以及性能优化措施,进一步提升了系统的整体性能和用户体验。 # 多gpu调度 # python multi_swap_10s_v2.py import os import subprocess from tqdm import tqdm import hashlib from multiprocessing import Process, Lock, Manager, Queue from queue import Empty # 用于检查队列是否为空 # Locks for each GPU to ensure only one task runs at a time per GPU gpu_locks = [Lock(), Lock()] # A shared queue for all tasks using Manager's Queue task_queue = Manager().