C语言中#和##操作符用法 答:在C语言中,#和##是预处理器(preprocessor)的操作符,主要用于宏(macro)的定义中。这两个操作符提供了字符串化和字符串连接的功能。
#操作符 #操作符用于将其后的宏参数转换为一个字符串字面量,在编译时将宏参数转换为字符串。
下面根据一个简单的示例分析一下。
#include <stdio.h> #define STRINGIFY(str) #str int main(void) { printf("STRINGIFY(hello)=%s\n", STRINGIFY(hello)); return 0; } 执行如下预处理命令:
gcc -E main.c -o main.i 查看main.i文件,可以发现确实将宏转换为了字符串:
... # 5 "main.c" int main(void) { printf("STRINGIFY(hello)=%s\n", "hello"); return 0; } 编译成可执行文件,运行测试:
$ gcc main.c -o main $ ./main STRINGIFY(hello)=hello ##操作符 ##操作符将两个标识符连接在一起,在编译时进行标识符连接。
下面根据一个简单的示例分析一下。
#include <stdio.h> #define CONCAT(x, y) x##y int main(void) { int ab = 1; printf("CONCAT(a,b)=%d\n", CONCAT(a,b)); return 0; } 执行如下预处理命令:
gcc -E main.
Conference:ACM Conference on Computer and Communications Security (CCS)
CCF level:CCF A
Categories:network and information security
Year:2023
Num:25
1
Title: Under the Dark: A Systematical Study of Stealthy Mining Pools (Ab)use in the Wild
黑暗之下:对野外隐秘矿池滥用的系统研究
Authors: Key words:
Cryptocurrency Mining; Cryptojacking; Malware; Botnet
加密货币挖矿;加密劫持;恶意软件;Botnet
Abstract: Cryptocurrency mining is a crucial operation in blockchains, and miners often join mining pools to increase their chances of earning rewards. However, the energy-intensive nature of PoW cryptocurrency mining has led to its ban in New York State of the United States, China, and India.
在Oracle数据库中,表名、表字段和表注释通常存储在数据字典视图中。以下是如何查询这些信息的SQL语句:
查看所有表名:
SELECT table_name FROM all_tables WHERE owner = 'YOUR_SCHEMA_NAME'; -- 如果只查询特定schema下的表,请替换'YOUR_SCHEMA_NAME' 如果你只关心当前用户下的表,可以使用user_tables代替all_tables。
查看表的字段和字段注释:
SELECT column_name, data_type, data_length, data_precision, data_scale, comments FROM all_col_comments WHERE owner = 'YOUR_SCHEMA_NAME' AND table_name = 'YOUR_TABLE_NAME'; -- 注意:Oracle没有直接存储字段注释的视图,但你可以使用DBMS_METADATA.GET_DDL来获取DDL,并从中解析注释。 -- 例如: SELECT DBMS_METADATA.GET_DDL('TABLE','YOUR_TABLE_NAME','YOUR_SCHEMA_NAME') FROM DUAL; 但请注意,DBMS_METADATA.GET_DDL返回的是整个表的DDL,你需要从中解析出字段注释。
查看表的注释:
SELECT comments FROM all_tab_comments WHERE owner = 'YOUR_SCHEMA_NAME' AND table_name = 'YOUR_TABLE_NAME'; 再次强调,你需要将'YOUR_SCHEMA_NAME'和'YOUR_TABLE_NAME'替换为你的实际schema名和表名。
如果你经常需要查询这些信息,可能会考虑编写一个PL/SQL程序或存储过程来自动化这个过程,并为你提供一个更友好的界面来查看这些信息。
一:DOM节点 1 什么是DOM节点 DOM树里每一个内容都称为节点
2 DOM节点分类 元素节点
属性节点:a标签的href、img标签的src等
文本节点:标签中的文字
上图为整个DOM树,每个标签、以及标签属性、文本内容构成了DOM树
二:节点查找(元素节点) 节点查找依据的是节点之间关系进行查找,查找后返回的都是对象,这与通过document.querySelector()查找返回类型是一致的
1 节点关系 父节点 语法格式:子元素.parentNode只能查找最近一级的父级元素,如果没有返回null 子节点 两种查找方式 父元素.childNodes(不重要) 获取的是所有元素节点、文本节点、注释节点父元素.children(重点) 仅获得所有元素节点返回的是伪数组 兄弟节点 两种属性 nextElementSiblingpreviousElementSibling 三:增加节点 节点添加分为创建节点、追加节点两步
1 创建节点 语法格式:cosnt 变量名= document.creatElement('元素标签')
2 追加节点 在父元素末尾追加节点 语法格式:父元素.appendChild(存储创造节点的变量名)在父元素最前方追加节点 语法格式:父元素.insertBefore(添加哪一个元素,放到哪个元素前面) 2 案例:渲染数据 案例中核心代码块 创建li标签,将li标签中内容利用模板字符串修改,最后在追加到ul中
// 1 遍历数组,创建节点、插入节点 const ul = document.querySelector('.box-bd ul') for (let index = 0; index < data.length; index++) { const li = document.createElement('li') li.innerHTML = ` <a href="#"> <img src="${data[index].src}" alt="
目录
1.部署环境
2.docker部署
3.docker-compose部署
4.redis 6.0部署
4.1拉起公网镜像
4.2 创建保存数据和配置文件的目录
4.3本地镜像打标签
4.4redis.yml配置
4.5验证
4.6问题记录
1.部署环境 系统:CentOS
容器:docker和docker-compose
2.docker部署 yum update yum install -y yum-utils yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo yum install docker-ce docker-ce-cli containerd.io systemctl start docker systemctl enable docker 3.docker-compose部署 离线安装包下载:docker-compose-linux-x86_64
cp docker-compose-Linux-x86_64 /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose 4.redis 6.0部署 4.1拉起公网镜像 https://hub-stage.docker.com/_/redis/tags(需要翻墙)
docker pull redis:6.0 docker images 4.2 创建保存数据和配置文件的目录 mkdir -p /data/redis6.0/conf mkdir -p /data/redis6.0/data https://download.csdn.net/download/li2327234939/89403390上传配置文件到/data/redis6.0/conf目录下,配置文件下载路径https://download.csdn.net/download/li2327234939/89403390
或者到对应的官网下载:Index of /releases/
修改文件,修改配置问,只需修改如下三处即可:
前端实现微信扫码登录网站(PC端二维码嵌套页面) 微信扫码登录是一种便捷的用户认证方式,尤其在PC端应用中非常流行。本文将介绍如何在前端实现微信扫码登录,并在PC端页面中嵌入二维码。
一、前置准备 微信开放平台账号:你需要注册一个微信开放平台账号并创建一个网站应用。获取AppID和AppSecret:在微信开放平台的应用详情页面获取你的AppID和AppSecret。配置回调URL:在微信开放平台的应用详情页面配置授权回调域名。 二、流程概述 用户在PC端点击“微信扫码登录”按钮。前端请求微信授权二维码接口并展示二维码。用户使用微信扫描二维码并确认登录。微信返回授权码(code)到回调URL。服务器使用授权码请求微信的Access Token接口获取用户信息。 三、前端实现步骤 1. 引入必要的库 可以使用纯JavaScript实现二维码的展示,但为了方便,我们可以使用qrcode.js库来生成二维码。
在HTML文件中引入qrcode.js:
<script src="https://cdn.jsdelivr.net/npm/qrcode/build/qrcode.min.js"></script> 2. 创建扫码登录按钮和二维码容器
在你的HTML中,创建一个用于触发微信扫码登录的按钮和一个用于展示二维码的容器:
<button id="wechat-login-btn">微信扫码登录</button> <div id="qrcode-container" style="display:none;"> <div id="qrcode"></div> </div> 3. 实现扫码登录逻辑 在JavaScript中,添加点击事件监听器来生成二维码并展示:
document.getElementById('wechat-login-btn').addEventListener('click', function() { // 请求微信二维码接口,假设你的后端接口为 /api/wechat/qrcode fetch('/api/wechat/qrcode') .then(response => response.json()) .then(data => { const qrcodeUrl = data.qrcode_url; // 从后端获取二维码URL // 使用 qrcode.js 生成二维码 QRCode.toCanvas(document.getElementById('qrcode'), qrcodeUrl, function (error) { if (error) console.error(error); console.log('success!'); }); // 显示二维码容器 document.getElementById('qrcode-container').style.display = 'block'; }) .catch(error => console.
前言 深度学习技术在当今技术市场上面尚有余力和开发空间的,主流落地领域主要有:视觉,听觉,AIGC这三大板块。
目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相关联的,其实语音模块在近来市场上面活跃空间很大。
从智能手机的语音助手到智能家居中的语音控制系统,再到银行和电信行业的语音身份验证,语音技术的应用日益广泛。那么对应现在ACG技术是可以利用原音频去进行训练学习,从而得到相对应的声音特征,从而进行模仿,甚至可以利用人工智能生成的语音可以以假乱真,给社会带来了严重的安全隐患。
当前,语音深度鉴伪识别技术已经取得了一定的进展。研究人员利用机器学习和深度学习方法,通过分析语音信号的特征,开发出了一系列鉴伪算法。
然而,随着生成大模型和其他语音合成技术的不断进步,伪造语音的逼真度也在不断提高,使得语音鉴伪任务变得愈加复杂和具有挑战性。本项目系列文章将从最基础的语音数据存储和详细分析开始,由于本系列专栏是有详细解说过深度学习和机器学习内容的,音频数据处理和现主流技术语音分类模型和编码模型将会是本项目系列文章的主体内容,具体本项目系列要讲述的内容可参考下图:
语音模型的内容不是那么好掌握的,包含大量的数学理论知识以及大量的计算公式原理需要推理。且如果不进行实际操作很难够理解我们写的代码究极在神经网络计算框架中代表什么作用。不过我会尽可能将知识简化,转换为我们比较熟悉的内容。
我将尽力让大家了解并熟悉神经网络框架,保证能够理解通畅以及推演顺利的条件之下,尽量不使用过多的数学公式和专业理论知识。以一篇文章快速了解并实现该算法,以效率最高的方式熟练这些知识。希望有需求的小伙伴不要错过笔者精心打造的专栏。
上篇文章详细解答了部份音频噪音种类和效果,以及频谱减法(Spectral Subtraction)和自适应滤波(Adaptive Filtering),接下来我们需要继续了解小波变换去噪(Wavelet Transform Denoising)和维纳滤波(Wiener Filter)进行去噪算法结尾。
小波变换去噪(Wavelet Transform Denoising) 小波变换是一种能够同时在时域和频域中对信号进行分析的技术。它利用小波函数对信号进行多尺度分解,能够有效地捕捉信号的局部特征和突变点。在去噪应用中,小波变换被广泛应用于处理各种类型的信号,如语音信号、图像、医学信号等。
详细步骤 1. 小波分解 对信号进行小波分解,可以得到不同尺度上的逼近系数和细节系数。公式如下:
其中, ϕ j 0 k ϕ_{j_{0}k} ϕj0k是尺度函数, ψ j , k \psi_{j,k} ψj,k 是小波函数, c j v , k c_{j_v,k} cjv,k 和 d j , k d_{j,k} dj,k 分别是尺度系数和细节系数。
2. 阈值处理 对细节系数进行阈值处理,去除噪声。常见的阈值处理方法有:
硬阈值(Hard Thresholding):将小于阈值的系数置为零。 软阈值(Soft Thresholding):将小于阈值的系数置为零,大于阈值的系数按一定规则缩小。 硬阈值是一种简单的置零的方法,而软阈值对于大于阈值的小波系数作了"收缩",即都减去阈值,从而使输入-输出曲线变成连续的。在阈值选选取上,人们普遍使用软阈值。改进的阈值是硬阈值和软阈值之间的一个折中,即当小波系数小于阈值时,不是简单地置为零,而是平滑地减小为零,当大于阈值时,小波系数幅度都减去阈值。这样,既保证了大的小波系数,又保证了加阈值后系数的平滑过渡。
阈值的选取 在小波变换去噪过程中,阈值选择至关重要,直接影响去噪效果。常用的阈值选择方法包括通用阈值(Universal Threshold)和自适应阈值。下面详细介绍这两种方法的计算逻辑。
1. 通用阈值(Universal Threshold) 通用阈值是由Donoho和Johnstone提出的一种简单有效的阈值选择方法。通用阈值的计算公式如下:
λ = σ 2 l o g ( n ) λ=σ\sqrt {2log(n)} λ=σ2log(n)
下一个更大的数
定义一个Solution类,用于实现next_great方法 class Solution:
def next_great(self, nums1, nums2):
# 初始化一个空字典answer,用于存储答案
answer = {}
# 初始化一个空列表stack,用于存储待比较的数字
stack = []
# 遍历nums2中的数字
for x in nums2:
# 当stack非空且stack[-1]<x时,说明stack中的数字小于x,将其加入答案字典并删除stack
while stack and stack[-1] < x:
answer[stack[-1]] = x
del stack[-1]
stack.append(x)
# 遍历stack中的数字,将其加入答案字典并设置为-1
for x in stack:
answer[x] = -1
# 返回nums1中数字的答案
return [answer[x] for x in nums1]
定义一个主函数,用于测试Solution类的next_great方法 if name == ‘main’:
# 定义一个示例数组nums1和nums2
nums1 = [4, 1, 2]
nums2 = [1, 3, 4, 2]
1. pathlib库介绍 1.1 pathlib和pathlib.Path pathlib是Python标准库中的一个模块,它提供了一组面向对象的文件系统路径操作。在Python早期版本中,文件和目录路径通常使用字符串来处理,或者使用os.path模块中的函数来执行操作,如路径拼接、获取文件属性等。pathlib模块在Python 3.4及更高版本中引入,提供了一种更现代、更直观的方式来处理文件系统路径。
pathlib.Path是pathlib模块中的核心类,它表示一个文件系统路径。Path对象可以表示文件或目录的路径,并且提供了许多方法来执行常见的路径操作,如路径拼接、检查路径是否存在、遍历目录、读取和写入文件等。
1.2 Path的特点 面向对象:Path对象允许我们使用对象和方法来处理路径,而不是传统的字符串操作。这使得代码更加清晰和可读。跨平台:Path对象会根据我们的操作系统自动处理路径分隔符(如Windows上的\和Unix/Linux/MacOS上的/),这使得我们的代码可以在不同的系统上运行,而无需做任何修改。便捷的方法:Path提供了许多便捷的方法来执行常见的文件系统操作,如open()、read_text()、write_text()、mkdir()、iterdir()等,这些方法简化了文件和目录的操作。属性访问:Path对象提供了许多属性,如name(文件名)、suffix(文件扩展名)、stem(无扩展名的文件名)、parent(父目录)等,这些属性可以很容易地访问路径的不同部分。模式匹配:Path对象支持使用glob模式匹配来查找符合特定模式的文件或目录。操作符重载:Path对象支持使用/操作符来进行路径拼接,这比使用字符串拼接更加直观。 总之,使用pathlib.Path可以让我们以更统一、更现代的方式处理文件系统路径,从而提高代码的质量和可维护性。
1.3 官方定义 The pathlib module – object-oriented filesystem paths(面向对象的文件系统路径) 简单来说,pathlib就是一个面向对象的文件操作类,我们一般会直接使用它的Path类。
1.4 pathlib组成部分关系 Path:是一个方便的别名,它自动选择PosixPath或WindowsPath,具体取决于我们的操作系统。 在Unix-like系统上,Path等同于PosixPath;在Windows系统上,Path等同于WindowsPath。 PurePath:这是一个抽象基类,提供了与操作系统无关的路径操作。它不能用于访问文件系统,但可以用于操作路径字符串。 PurePath不处理路径的具体细节,如路径分隔符或文件系统的存在性。 PurePosixPath:PurePath的一个子类,用于表示类Unix操作系统的路径。 它使用/作为路径分隔符,并且遵循POSIX路径规则。 PureWindowsPath:PurePath的一个子类,用于表示Windows操作系统的路径。 它使用\作为路径分隔符,并且可以处理Windows特有的路径形式,如驱动器号和UNC路径。 PosixPath:Path的一个子类,用于表示实际存在于类Unix操作系统中的路径。 它继承自PurePosixPath,并且提供了与文件系统交互的方法,如检查路径是否存在、遍历目录等。 WindowsPath:Path的一个子类,用于表示实际存在于Windows操作系统中的路径。 它继承自PureWindowsPath,并且提供了与文件系统交互的方法,如检查路径是否存在、遍历目录等。 关系总结:
PurePath是所有路径类的抽象基类,提供了与操作系统无关的路径操作。PurePosixPath和PureWindowsPath继承自PurePath,分别提供了特定于POSIX和Windows的路径操作。PosixPath和WindowsPath继承自PurePosixPath和PureWindowsPath,分别提供了与实际文件系统交互的方法。Path是一个方便的别名,根据操作系统自动指向PosixPath或WindowsPath。 这种设计允许开发者编写可移植的代码,同时也能够处理特定操作系统的路径细节。通过使用Path,我们可以编写不依赖于操作系统的代码,而PurePath及其子类则提供了处理特定操作系统路径的能力。
1.5 补充 1.5.1 POSIX路径 POSIX(Portable Operating System Interface)路径是指遵循POSIX标准的文件系统路径。POSIX是一个IEEE标准,旨在为Unix-like操作系统提供一系列API规范,以确保软件可以在不同的操作系统上运行。
POSIX路径具有以下特点:
路径分隔符:POSIX路径使用/作为目录分隔符。例如,/home/user/documents是一个POSIX路径。相对路径和绝对路径:POSIX路径可以是相对路径,也可以是绝对路径。相对路径是相对于当前工作目录的路径,而绝对路径是从文件系统的根开始的完整路径。当前目录和父目录:点.表示当前目录,而双点..表示父目录。例如,../file.txt表示当前目录的父目录中的file.txt文件。文件名和扩展名:文件名通常由两部分组成:基础名和扩展名。基础名是文件的名称,而扩展名通常是跟在最后一个点.后面的部分,表示文件的类型。例如,在文件名document.txt中,document是基础名,txt是扩展名。路径解析:POSIX路径解析遵循特定的规则,例如,连续的路径分隔符被视为单个分隔符,.表示当前目录,而..用于返回到上一级目录。
POSIX路径规范被广泛应用于类Unix操作系统,如Linux、BSD、MacOS X等。这些系统的文件系统API通常遵循POSIX标准,以确保软件的兼容性和可移植性。 1.5.2 驱动器号和UNC(Universal Naming Convention)路径 它们俩都是Windows操作系统中的两个概念,用于指定文件或目录的位置。
驱动器号: 在Windows系统中,每个物理或逻辑磁盘分区都被分配一个驱动器号,通常是一个字母后跟一个冒号。例如,C:通常是指系统启动磁盘,D:可能是指第二个磁盘分区,依此类推。驱动器号后面可以跟一个路径,如C:\Windows\System32,表示C:驱动器上的Windows\System32目录。驱动器号是Windows特有的概念,不适用于Unix-like操作系统。 UNC路径: UNC路径是一种用于指定网络资源位置的通用命名约定。UNC路径的格式通常是\\servername\sharename\path\filename,其中servername是网络服务器的主机名或IP地址,sharename是共享资源的名称,path是共享资源内的文件路径,filename是要访问的文件或目录的名称。UNC路径可以用于访问网络上的共享文件夹或打印机等资源,不依赖于特定的驱动器号。UNC路径在Windows网络环境中广泛使用,但也得到了其他支持SMB(Server Message Block)协议的系统的支持,如一些Unix-like系统。 ❗ 注意:驱动器号是Windows专有的,但UNC不是(Windows和Linux都有)。
2. pathlib库下Path类的基本使用 2.1 Path类的属性和方法概览 ⚠️ 我这里使用的Python版本为:
前言 需求: 因项目需要License认证,认证页面有服务器信息。 服务器信息可一键复制发送给技术人员,方便生成license。使用navigator.clipboard 全局对象就是来处理剪贴板的,对于clipboard 的API,JS剪切板操作一文写的很清楚。
问题: 项目发布后发现,只有我开发环境可以实现一键复制。原因:只有 HTTPS 协议的页面才能使用Clipboard API。不过,开发环境(localhost)允许使用非加密协议
解决方案: 使用clipboard.js插件
下面是两种方式实现一键复制,需要的 小伙伴各取所需
项目效果如下: 一、JS实现一键复制 限制:js Clipboard API 对安全性有要求,项目需使用https
html代码
<fieldset id="systemField"> <legend>服务器信息</legend> <div style="padding:10px"> <div class="copyDiv"> <button id="copyBtn">{{replicatedShow ? "已复制":"一键复制"}}</button> </div> <div id="systemInfoBtn"> <div class="text item"> <span>MAC地址: </span> <span class="spanLabel">{{systemForm.macAddressList}}</span> </div> <div class="text item"> <span>CPU序列号: </span> <span class="spanLabel">{{systemForm.cpuSerial}}</span> </div> <div class="text item"> <span>主板序列号: </span> <span class="spanLabel">{{systemForm.mainBoardSerial}}</span> </div> </div> </div> </fieldset> js代码
mounted: function () { const clipboard = navigator.
最近植物大战僵尸杂交版可是非常的火爆,各大主播都在玩,可是该游戏作者只发布了win版本,我只有一台 Macbook 一直都很想玩,经过一番折腾终于在Mac上成功安装运行了该游戏,并整理好了,大家想要在 Mac 上安装的可以根据我的教程来,非常简单
首先,我们先把事先转译打包好的 DMG 安装包下载下来,该安装包全都把资源整理在了一起,可以直接安装
DMG安装包:https://www.hereitis.cn/articleDetails/2551
下载好以后,我们打开安装包,如下图直接拖拽过去就可以了
到这,就算是安装成功了,我们前往控制台打开该游戏,但可能存在打不开的问题,可能会提示已损坏
问题一(游戏已损坏打不开) 如提示已损坏,不安全等打不开问题,我们回到上面的DMG安装包,然后运行下方的软件损坏修复引导程序(如同样打不开提示未知开发者不安全等请看问题二)
这里输入密码,回车就可以了
问题二(未设置允许运行任何来源软件) 如过你的软件修复引导同样打不开,很有可能是你还未设置允许你的电脑安装第三方软件,你可以前往设置》隐私与安全性》安全性》单次允许本次运行,或者直接设置为允许任何来源软件运行
电脑设置允许运行任何来源软件教程:https://www.hereitis.cn/articleDetails/847
问题三(窗口模式不显示画面) 当我们在游戏内设置为窗口模式后,就只有一个横条,我们拖拽该横条多甩甩,就能恢复窗口画面了
问题四(游戏加载黑屏) 我们第一次进入该游戏时,加载会比较慢,而且画面是黑的,所有会有卡住的错觉,其实不要乱动等一分钟左右就可以了,下次再进的时候就快了
手机空号过滤或手机号码有效性验证通常涉及使用专门的API接口来查询手机号码的状态。这些API接口通常由第三方服务提供商提供,它们会与电信运营商合作或利用自己的数据库来验证手机号码是否真实存在、是否已被分配、是否处于空号状态等。
以下是一些步骤和考虑因素,用于实现手机空号过滤或手机号码有效性验证:
选择API提供商:
查找信誉良好的API提供商,它们通常与多个电信运营商有合作关系,可以提供广泛的覆盖范围和准确的数据。
比较不同提供商的价格、准确性、查询速度和覆盖范围。
注册和获取API密钥:
在选定的API提供商处注册账户。
获取API密钥或访问令牌,以便在您的应用程序中使用。
集成API:
根据API提供商的文档,将API集成到您的应用程序中。
这通常涉及发送HTTP请求到API端点,并在请求中包含手机号码和API密钥。
处理响应:
API将返回一个响应,其中包含有关手机号码状态的信息。
解析响应并确定手机号码是否有效、是否空号等。
错误处理和日志记录:
实现适当的错误处理机制,以处理API调用失败或返回无效响应的情况。
记录日志以帮助诊断问题和监控API使用情况。
遵守隐私和合规性要求:
确保您遵守所有相关的隐私和合规性要求,特别是关于数据收集、存储和传输的规定。
确保您从用户那里获得了适当的权限和同意,以验证他们的手机号码。
测试和优化:
在将API集成到生产环境之前,进行充分的测试以确保其正常工作并满足您的需求。
监控API的性能和准确性,并根据需要进行优化。
考虑缓存:
对于频繁查询的手机号码,考虑实现缓存机制以减少对API的调用次数并提高性能。
请注意,由于手机号码的隐私性和敏感性,不同的国家和地区可能有不同的法律和规定来限制手机号码的验证和使用。因此,在实施手机空号过滤或手机号码有效性验证之前,请确保您了解并遵守所有相关的法律和规定。
最后,由于API提供商和具体实现细节可能因时间和技术发展而变化,请务必参考您所选API提供商的最新文档和指南来获取最准确的信息。
空号过滤:https://www.wapi.cn/emptymobile.html
查询结果:
项目场景: 数据库环境 :mysql8;
工程使用:MyBatisPlus
表情况:
问题描述 某一个插入语句使用了 MyBatisPlus 的 save 方法,因为end_time1 end_time2都并没有值,所以在MyBatisPlus默认情况下,并不会在插入语句中提及,
最终提取其SQL: INSERT INTO aaaa (serial_no, business_date, market_no, report_code)
VALUES (31, 20230704, 1, ‘688610’)
结果报错 Field 'end_time1' doesn't have a default value。
一般情况下,这种报错是表设置成非空字段,我们又没设置默认值导致的。但是这里我们明明表中设置了可空。而且该场景为偶现,我们单独把SQL提取出来执行又是可以的,排查数小时无果。
原因分析: 偶现,目前无法查出其原因,可能需要去Mysql源码来看原因了
解决方案: 既然说的是没有默认值,那我们就在插入的时候指定传null 进去即可,由于MyBatisPlus的特性,所以最终在DBclass层,为end_time1和end_time2都设置为null 也插入和更新
该参数的运行原理可见往期博文《MybatisPlus 构造器wrapper的使用与原理》 中的“易错点-null处理”小节
最终生成的SQL如下:
INSERT INTO aaaa ( serial_no, business_date,
market_no, report_code, end_time1, end_time2 ) VALUES ( 63, 20230704,
1, ‘688610’, , )
修复后没有再次报错。
上架GooglePlay权限问题 问题描述 REQUEST_INSTALL_PACKAGES 权限问题 解决方式 方式1 找到所有使用该权限的库修改删除该权限引用
方式2 打开项目 ~/andoird/app/src/main/AndroidMainfest.xml 添加文本 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" tools:node="remove" />
前言:本篇文章继续分享一种新的算法——二分查找。
一.二分查找 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9输出: 4 解释: 9 出现在 nums中并且下标为 4 示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2输出: -1 解释: 2 不存在 nums 中因此返回 -1 按照一般的方法去解决上述题目,我们的第一想法肯定是将数组从头到尾遍历一遍,每个值都跟target进行一次比较,从而判断其是否存在于数组中。
此方法虽然简单,但是在最差的情况下,需要进行n次循环,即时间复杂度为O(N),如果说在数据量很大的前提下,这样做的速度反而是非常慢的。
但是有了数组已经有序(升序)的前提,所以为了降低时间复杂度,引出二分查找的概念:
取一组数据的中间值与target进行比较,如果相等,就直接返回;
如果中间值比target小,那么数组中的目标值就一定在中间值的右边;
如果中间值比target大,那么数组中的目标值就一定在中间值的左边;
通过中间值的方法,不断将数组拆分成两半,便可以使其中一半不满足条件的数据直接舍弃,无需在进行判断,如此以来的时间复杂度变为O(logN)。
下面来看具体代码:
int search(vector<int>& nums, int target) { int left = 0,right = nums.size() - 1; while(left <= right) { int midnum = left + (right - left) / 2; if(nums[midnum] == target) { return midnum; } else if(nums[midnum] > target) right = midnum - 1; else left = midnum + 1; } return -1; } 二分查找,需要定义两个指针left和right,分别管理要处理的数据的两端,起始时为整个数组的两端。 随后我们需要得出中间值,求中间值有一个细节,如果我们使用(right + left) / 2的方式去求算中间值,那么当left和right均接近于INT_MAX时,就会发生数据越界,所以我们采用上述代码的方式更加稳妥。
概念 1.实数 2.指数函数 f(x) = (a>0且a≠1)【a: 底数(常量),x: 指数(变量)】
特征:指数函数在x轴没有交点,是光滑的曲线
3.幂函数 f(x) = 【x:底数(自变量), a:指数(常量-实数)】
4.对数函数 (a>0,且a≠1)【x:自变量,a:常量】
a>1
0<a<1
图象
对数函数 f(x) = (a>0,且a≠1) 与 指数函数 f(x) = (a>0,且a≠1) 互为反函数
在日常的数据库操作中,我们经常需要判断某个字段中是否包含特定的字符串。在 MySQL
中,有多种方式可以实现这一需求。本文将介绍几种常见的方式,并详细说明它们的使用场景和优缺点。
1. 使用 LIKE 进行模糊查询 LIKE 是最常见的字符串匹配方法,通过使用百分号 % 作为通配符来实现模糊查询。以下是一个示例:
SELECT * FROM user WHERE user_name LIKE '%李%'; 该查询将返回所有 user_name 中包含“李”字的记录。
2. 使用 LOCATE 判断是否包含某字符串 LOCATE 函数返回子字符串在字符串中的位置,如果返回值大于 0,则表示包含该子字符串。示例如下:
SELECT * FROM user WHERE LOCATE('李', user_name) > 0; 3. 使用 POSITION 判断是否包含某字符串 POSITION 和 LOCATE 类似,也用于查找子字符串的位置。语法如下:
SELECT * FROM user WHERE POSITION('李' IN user_name) > 0; 4. 使用 INSTR 判断是否包含某字符串 INSTR 函数也是返回子字符串在字符串中的位置,语法如下:
SELECT * FROM user WHERE INSTR(user_name, '李') > 0; 使用 FIND_IN_SET 判断字段值是否在条件字符串中
📝个人主页🌹:Eternity._
⏩收录专栏⏪:C++ “ 登神长阶 ”
🤡往期回顾🤡:初步了解vector
🌹🌹期待您的关注 🌹🌹
❀STL之vector 📒1. 迭代器失效🌈插入时失效🌞删除时失效 📕2. 解决迭代器失效🍂在插入时失效🍁在删除时失效 📜3. vector的拷贝问题🎩浅拷贝🎈深拷贝 📖4. 总结补充💧补充:insert和erase的模拟实现(优化前)🔥总结 前言:在C++的STL(Standard Template Library)库中,vector容器无疑是最常用且功能强大的数据结构之一。它提供了动态数组的功能,允许我们在运行时动态地增加或减少元素。然而,随着我们对vector的深入使用,一些潜在的问题也逐渐浮现,其中最为常见和棘手的就是迭代器失效以及拷贝问题 (关于初始insert和erase的模拟实现在本篇末尾)
注意:我们使用的函数是上一篇模拟实现的函数
📒1. 迭代器失效 迭代器失效是指在使用迭代器遍历或操作vector容器时,由于某些操作导致迭代器失效,无法再正确引用容器中的元素。 这种情况往往发生在vector容器进行扩容、插入或删除元素等操作时。迭代器失效可能导致程序出现未定义行为,甚至崩溃。
因此:深入理解vector迭代器失效的原因和场景,对于编写健壮、可靠的C++代码至关重要。
🌈插入时失效 代码示例:(插入)
void test_vector() { vector<int> v1; // 创建一个vector插入4个元素 v1.push_back(1); v1.push_back(2); v1.push_back(3); v1.push_back(4); vector<int>::iterator it = find(v1.begin(), v1.end(), 1); v1.insert(it, 2); // 然后我们再来插入两个元素 v1.insert(it, 3); for (auto e : v1) { cout << e << " "; } cout << endl; } 哎呀,怎么程序出错了?
目录
1 GaussDB 关键架构目标
2 GaussDB分布式架构
2.1 GaussDB 分布式关键技术架构
3 数据计算路由层(Coordinator)关键技术方案
3.1 分布式优化器
3.2 分布式执行框架
GaussDB是华为自主创新研发的关系型数据库,基于华为在数据库领域20多年的战略投入,通过多维度的技术创新,在行业实践中构筑了高可用、高安全、高性能、高弹性、高智能的技术优势,在数据库替换场景中,具备易部署、易迁移的特性。作为国内当前唯一能够做到软硬协同、全栈自主的数据库,GaussDB已经在金融、政务、能源、交通等关键信息基础设施行业积累了丰富的实践经验,是企业数字化转型、核心数据上云、分布式改造的信赖之选。
从本期开始,Gauss松鼠会将陆续推出GaussDB技术解读系列文章,带您了解GaussDB的架构及关键技术原理。本篇将从GaussDB 关键架构目标、GaussDB分布式架构、数据计算路由层(Coordinator)关键技术方案等三方面对GaussDB架构进行介绍。
1 GaussDB 关键架构目标 GaussDB在架构设计上,采用组件化原则,分为GaussDB Kernel内核和GaussDB Kernel OM两部分。在产品形态上,提供面向云数据库服务GaussDB(for openGauss)的分布式安装包和集中式安装包,提供面向本地化安装的小型化安装包。
根据华为云提供的调查报告,当前全球数据库市场增长超预期,云是数据库增长最重要驱动力。得益于云数据库的迅猛发展,AWS市场份额超越IBM,成为数据库市场空间第三位,聚焦公有云、混合云构筑具备竞争力的可商用分布式数据库版本,数据库已成为公有云Top收入来源,同时通过数据库服务能够更大地提升公有云服务粘性。GaussDB Kernel面向云服务提供GaussDB产品,主要客户包含金融(银行、证券、保险)行业、政府(政务云、财政等)和大企业客户。结合产品可信要求定义及可信实施策略分析的内容,以及业界数据库厂商前沿动态,GaussDB Kernel在云服务场景中的架构目标按照一下几个维度来展开:
高性能:建立基于x86平台与鲲鹏平台的绝对性能领先,鲲鹏平台相对x86平台保证50%性能优势,达到单机170万tpmC,分布式全局强一致32节点1500万tpmC,承载用户关键业务负载;具备性能韧性能力,5倍压力下性能不抖动、十倍压力下系统不崩溃,同时具备抗过载逃生能力;具备大并发、低时延能力,单节点支持1万并发、单集群支持10万级并发访问请求,ms至秒级事务处理时延,支撑政企客户核心业务负载。
云原生:通过GTM-Lite技术轻量化处理全局读一致性点与写一致性点,集群扩展性达到256节点,未来通过全球时钟技术演进,在跨Region全局一致性下去除单点瓶颈;面向业务陡增等业务场景,构建基于哈希聚簇的存储结构和弹性扩容方案,实现秒级存储节点扩缩容和业务无感的计算节点弹性伸缩;构建分布式备机只读技术,只读性能提升100%以上。
高可用:AZ内主备高可用,1主多备,RPO=0、RTO<10s;同城跨AZ高可用,RPO=0、RTO<60s;跨Region容灾,RPO<10s、RTO<5min;提供备份恢复、PITR、闪回、ALT等企业级高可用特性;构建基于Paxos协议的多副本高可用和并行逻辑复制技术,实现RPO=0的同城双集群高可用容灾和基于流式复制的多地多中心容灾,保证机房级、区域级、城市级故障下的数据库高可用。
高安全:继承可信实施策略中安全可信需求,从安全,韧性,隐私等维度构筑安全可信能力,结合业界安全技术前沿发展,设计全密态数据库和防篡改数据库,保证用户敏感数据免于泄露和篡改;构建数据库安全自治管控方法,识别和拦截攻击者的异常行为;构建从接入、访问控制、加密到审计全方位纵深防御的安全防护体系。
高智能:面向云化场景故障运维诉求,基于AI技术,提供端到端自治运维管理能力,全面提升数据库产品服务可靠性和可用性;构筑自学习数据库内核,尤其是智能优化器,解决数据库内优化执行过程中计划不准、无法自适应等难题;结合业界前沿技术,构建库内AI引擎,基于SQL-like简易语法,提供数据库内置的机器学习训练和推理能力,为用户提供普惠AI;提供向量数据库能力,支撑盘古大模型、NAIE-NetGPT和GTS领域知识库等场景,提高大模型的预测效率。
GaussDB Kernel提供的本地化版本的架构目标包括:
高性能:支撑业务1千并发能力,性能达1000+ TPS;
高可用:提供多种部署形态的能力:一主一备、一主多备等;
高安全:支持数据库备份加密、网络连接安全管理及传输加密;支持三权分立,即数据库管理员、安全管理员、审计管理员权限职责分离;支持访问控制;
高智能:提供丰富高效的DFx运维监测手段,后续朝向基于AI的自治运维调优方向发展,降低BCM相关产品或解决方案的运维成本,提升易用性;
小型化:数据库安装包大小<25MB,且数据库刚启动后的底噪内存<250MB。
2 GaussDB分布式架构 2.1 GaussDB 分布式关键技术架构 Coordinator: 负责接收SQL请求,路由分发请求到对应的数据节点。同时维护系统元数据(路由分片信息,表定义)。
图1 Coordinator逻辑模型
Datanode: 数据节点存储分片数据。副本复制采用Quorum/Paxos协议。
图2 DN逻辑模型
SECURITY: 安全子系统,主要包含了Kerberos认证,登录认证,安全审计,角色管理与访问控制,安全通信,透明数据加密,防篡改账本,全密态数据,数据脱敏等功能。
图3 安全逻辑模型
GTM: 全局事务管理器, 负责产生CSN号,提供全局统一快照。
图4 GTM逻辑模型
CM: 集群管理系统, 主要包括 CM Agent, CM Server和分布式配置中心。
在这个信息爆炸的数字化时代,我们的网络隐私和安全正面临着前所未有的挑战。虚拟专用网络(VPN)作为一种有效的解决方案,通过加密通信和隧道技术,为用户在公共网络上提供安全的连接。本文将带您深入了解 VPN 的工作机制,并展示如何使用 Python 和 strongSwan 库构建一个高级 VPN 连接,以实现更高级别的安全性和灵活性。
VPN 工作机制深度解析 加密通信协议:数据的保护神 VPN 的首要任务是确保数据的机密性。它通过使用 OpenVPN、IPsec、L 2 TP 等不同的加密协议来实现这一目标。这些协议通过加密数据包,使得数据在传输过程中即使被截获也无法被解读,从而保护了数据的隐私。
隧道技术:数据的安全通道 VPN 利用隧道技术创建一条加密的通道,将用户的数据包封装在内,通过公共网络安全传输。即使数据包在传输过程中被截获,由于加密,攻击者也无法读取其中的内容。
身份验证与授权:严格的访问控制 在建立 VPN 连接时,用户必须通过身份验证,这通常涉及用户名和密码,或者采用更高安全性的身份验证方式。这一步骤确保了只有授权用户才能访问 VPN 网络。
虚拟 IP 地址分配:隐藏用户真实身份 VPN 服务器为客户端分配虚拟 IP 地址,使得用户在网络上的位置似乎与 VPN 服务器所在地相同。这不仅提供了隐私保护,还隐藏了用户的真实 IP 地址。
构建高级 VPN 连接:Python 与 strongSwan 的结合 步骤 1:安装必要的库 在开始构建 VPN 之前,我们需要准备一些工具。首先,安装 strongSwan 库,这是一个功能强大的 IPsec VPN 解决方案。在命令行中运行以下命令:
pip install strongswan 步骤 2:编写 Python 代码 接下来,我们将编写一个 Python 脚本,用于启动和停止 VPN 连接。创建一个名为 advanced_vpn.py 的文件,并添加以下代码:
import subprocess def start_vpn(): # 配置VPN参数 vpn_config = { "