2023年从入门到精通java开发全栈知识体系架构学习总结知识脑图(学习使用于项目实战)前端、后台、服务器、Linux、性能优化、集群搭建、微服务、大数据、项目实战等内容

一、最硬核的知识点描述(内容更新于2023年3月21日) 本人从事Java开发已多年,平时有记录问题解决方案和总结知识点的习惯,整理了一些有关Java的知识体系。也算是记录自己在从事编程工作的成长足迹,通过博客可以促进博主与阅读者的共同进步,结交更多志同道合的朋友。特此分享给大家,本人见识有限,写的博客难免有错误或者疏忽的地方,还望各位大佬指点,在此表示感激不尽。 本文章主要是汇总java开发人员从入门到精通的以及工作中用到的实践内容。内容主要包括前端、后台、服务器、linux系统、流行的框架技术和数据库等。以下将全栈知识体系架构脑图全部免费分享给大家,内容持续更新中。 让我们一起每天学习一点,让自己与众不同,能过本内容你可以学习到涵盖了前端、后台、服务器、Linux、性能优化、集群搭建、微服务、大数据、项目实战等内容,关注我,持续学习 知识脑图学习大纲请到以下地址学习: 1、processon版:Java开发全栈知识体系架构学习 (服务器、微服务、数据库、| ProcessOn免费在线作图,在线流程图,在线思维导图 2、百度脑图版:与百度连接 二、Java全栈知识体系架构脑图 总休结构图如图,详细请继续往下看: 技术总结持续更新中-----------每天学习一点,让自己与众不同,本内容涵盖了前端、后台、服务器、Linux、性能优化、集群搭建、微服务、大数据、项目实战等内容,关注我,持续学习 三、前端知识脑图 四、后台技术学习脑图 五、数据库学习脑图 技术总结持续更新中-----------每天学习一点,让自己与众不同 六、Linux系统篇学习脑图 技术总结持续更新中----------- 七、服务器篇学习脑图 技术总结持续更新中----------- 八、项目开发篇脑图 九、性能优化篇 十、大数据篇 十一、详细知识结构脑图 十、版本更新历史(使用最新更新的在最上面) 更新时间:2023年3月29日17:08:53 更新内容:增加了文本阅读功能,详见Java开发全栈知识体系架构学习 (服务器、微服务、数据库、| ProcessOn免费在线作图,在线流程图,在线思维导图 更新时间:2023年1月18日16:17:55 更新内容:增加了docker的学习和实践内容 更新时间:2023年1月15日17:01:18 更新内容:增加docker的学习内容和部份常用前端知识 更新时间:2023年1月8日12:48:51 更新内容:增加大数据学习的知识学习目录、Vue框架的初始与路由使用、linux学习目录顺序整理 更新时间:2023年1月6日13:18:37 更新内容:增加前端前端需要注意了解的SEO知识、HTTP的几种方法请求用途、前端网站性能优化的知识 *******欢迎各位大佬批评指正错误的点,以及建议,谢谢*******

【笔记】Python3|爬虫请求 CSRF-Token 时如何获取Token、Token过期、处理 CSRF-Token 需要注意的问题及示例

CSRF-Token 机制是 Web 应用程序中常用的安全机制,它可以防止跨站请求伪造攻击,但会给爬虫造成一定的困扰。本文将介绍在使用 Python3 爬虫时,处理 CSRF-Token 机制需要注意的问题及示例。 文章目录 1 CSRF-Token 机制的原理2 爬虫处理 CSRF-Token 机制的问题3 CSRF-Token 可能存在的位置3.1 CSRF-Token 位于 Web 表单时3.1.1 使用 Beautiful Soup 库3.1.2 使用正则表达式 3.2 CSRF-Token 位于 响应体 时3.3 CSRF-Token 位于 响应头 时3.4 注意事项 4 将 CSRF-Token 嵌入到请求中4.1 CSRF-Token 嵌入请求头4.2 CSRF-Token 嵌入请求参数 5 示例6 总结 1 CSRF-Token 机制的原理 在 Web 开发中,每次发送请求时,服务器都会生成一个 CSRF-Token。当用户访问 Web 页面时,该 CSRF-Token 将被嵌入到 Web 表单、请求 URL 或 请求头 中。当用户提交表单或者发送请求时,该 CSRF-Token 将会被服务器验证,以防止跨站请求伪造攻击。 2 爬虫处理 CSRF-Token 机制的问题 由于爬虫不同于浏览器,它无法直接接收服务器生成的 CSRF-Token。因此,在使用爬虫时,我们需要解决如下问题:

使用Node.js连接和发布/订阅MQTT消息

Node.js是一种基于事件驱动的异步I/O服务器端JavaScript运行环境,因为其非阻塞I/O和事件驱动模型,使得它非常适合处理大量并发请求的场景。MQTT是一种轻量级的消息传递协议,它是基于发布/订阅模式的,适用于传输小量数据,且具有低带宽、低电量消耗和可靠性高等特点。这篇文章将介绍如何使用Node.js和MQTT客户端库来连接和发布/订阅MQTT消息。 一、安装MQTT客户端库 在Node.js中使用MQTT客户端库,需要先安装它。在命令行中输入以下命令即可安装MQTT客户端库: npm install mqtt 二、引入MQTT客户端库 在使用MQTT客户端库之前,需要先引入它。在Node.js脚本中,可以使用以下代码来引入MQTT客户端库: var mqtt = require('mqtt') 三、连接MQTT代理 在Node.js中使用MQTT客户端库连接MQTT代理需要使用mqtt.connect()方法。该方法的第一个参数是MQTT代理的地址,可以是IP地址或者域名,第二个参数是连接选项。 var client = mqtt.connect('mqtt://localhost:1883', { clientId: 'nodejs-mqtt-client' }) 其中,'mqtt://localhost:1883'是MQTT代理的地址,端口号为1883,'nodejs-mqtt-client'是客户端ID。 四、发布MQTT消息 在Node.js中,使用MQTT客户端库发布MQTT消息需要使用client.publish()方法。该方法的第一个参数是消息主题,第二个参数是消息内容,第三个参数是选项。 client.publish('topic', 'hello mqtt', { qos: 1 }) 其中,'topic'是消息主题,{qos: 1}是选项,表示消息订阅的QoS级别为1。 六、接收MQTT消息 在Node.js中,使用MQTT客户端库接收MQTT消息需要使用client.on('message', callback)方法。该方法的第一个参数是'message',表示监听MQTT消息,第二个参数是回调函数,用来处理收到的MQTT消息。 client.on('message', function (topic, message) { console.log('Received message:', topic, message.toString()) }) 其中,'topic'是消息主题,message是消息内容,toString()方法将消息内容转化为字符串类型。当客户端接收到MQTT消息时,就会触发该回调函数。 七、断开MQTT连接 在Node.js中,使用MQTT客户端库断开MQTT连接需要使用client.end()方法。 八、完整示例 下面是一个完整的Node.js和MQTT客户端库的示例: var mqtt = require('mqtt') var client = mqtt.connect('mqtt://localhost:1883', { clientId: 'nodejs-mqtt-client' }) client.on('connect', function () { console.log('Connected to MQTT broker') client.

STM32f103ZET6引脚通道(ADC和TIM)

STM32F103ZET6是一款基于ARM Cortex-M3内核的微控制器,具有三个12位ADC和五个16位TIM。这些功能之间在一定程度上存在差异。 对于ADC,STM32F103ZET6具有三个独立的ADC,每个ADC可以进行单次或连续转换,并且可以使用DMA传输数据。这些ADC可以同时测量不同的模拟输入信号,因此可以轻松地实现多通道采样。此外,每个ADC都带有一个可编程增益放大器,允许对低信号进行放大。 对于TIM,STM32F103ZET6具有五个16位定时器,它们可以用于各种精确定时应用程序。其中,两个是基本定时器(TIM2和TIM3),它们包含计数器和预分频器,可以产生PWM输出信号。其余三个是高级定时器(TIM1、TIM4和TIM5),它们具有更多的特性,例如输入捕获、输出比较、PWM生成等。 因此,虽然所有ADC和TIM都具有相似的基本功能,但它们之间也存在差异,这使得STM32F103ZET6适用于广泛的应用程序需求。 ADC通道引脚配置汇总 TIM通道引脚配置汇总 更多引脚配置请参考《STM32F103ZET6(中文)》资料P20--P27, 链接:https://pan.baidu.com/s/1CxmBSnI3xhFaiYgMxHwt2A?pwd=ky3c 提取码:ky3c

Unity实现残影效果

1、效果展示 2、场景搭建 3、代码 1、PlayerMovement.cs:挂载在角色身上 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMovement : MonoBehaviour { [Header("人物移动速度")] public float moveSpeed = 5; private Rigidbody2D rb; private Vector2 moveDir; private Animator anim; [Header("冲锋时长")] public float dashTime = 0.5f;//冲锋时长 private float dashTimeLeft;//冲锋剩余时间 [Header("冲锋时的速度")] public float dashSpeed = 10;//冲锋时的速度 [Header("冲锋冷却时间")] public float dashCoolDown = 1;//冲锋冷却时间 private float lastDash = -10; private bool isDashing;//是否冲锋 // Start is called before the first frame update void Start() { rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); } // Update is called once per frame void Update() { InputManagement(); if (Input.

vue-router 在没有用户交互情况下,执行push ,无法返回上一个页面?

一.问题描述 1.在index页面中(默认项目主页),获取了用户的信息,根据query参数,判断是否需要跳转到其他页面。 2.代码如下,3s秒,跳到了foo’页面,但点击浏览器返回键,无法返回index页面,直接跳到上上个页面? mounted(){ setTimeout(()=>{ this.$router.push('/foo') },3000) }, 二、出现的bug如何解决,求助

Python学习笔记-19(闭包函数,装饰器,匿名函数等案例)

2023.4.28 努力学习python,想为以后可以有一份额外收入,如果有大神可以指点一下,我将不胜感激 如果有大神想以后拥有一个合作伙伴进行交流,我会尽力赶上您的脚步! 1. 牛刀小试,简单小算法 '''题目:给你一个 m x n 的整数网格 accounts ,其中 accounts[i][j] 是第i位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。 客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。 例如 输入:accounts = [[1,2,3],[3,2,1]] 输出:6 解释: 第 1 位客户的资产总量 = 1 + 2 + 3 = 6 第 2 位客户的资产总量 = 3 + 2 + 1 = 6 两位客户都是最富有的,资产总量都是 6 ,所以返回 6 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/richest-customer-wealth 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。''' #函数写法 class Solution(object): def maximumWealth(self, accounts): list1 = [] #该空列表要放在外面,否则会循环 for i in range(len(accounts)): #4-7行计算各元素和 sum = 0 #首先根据总长度循环 for n in range(len(accounts[i])): #再根据元素长度循环,并拿出其中值相加 sum += accounts[i][n] list1.

AutoJs制作简易自动化脚本(持续更新)

一、环境搭建 代码编程建议使用vscode编写 下载安装autojs(建议还是下载4.1.1版本):​​​​​​Auto.js Pro (autojs.org) 2023-2-18免费版已经无法使用,建议使用 autox.js:Releases · kkevsekk1/AutoX · GitHub 调试建议下载雷电模拟器 :雷电安卓模拟器 (ldmnq.com) 安装好auto.js之后记得开启以下操作: 1、先在vscode中下载auto.js插件,并且在查看--控制面板 中输入auto.js回车,就会有相应的命令, 2、开启auto.js的无障碍服务、悬浮窗、连接电脑 3、查看电脑ip: 二、auto.js官方文档 Auto.js Pro文档 (autojs.org) 注意!!!! 因为抖音短视频的机制是,当进入页面的时候会有上下视频先进性加载缓存,如下图,所以当我们直接按照控件属性去寻找控件的时候,会一次性找到好多个,一般往往都会取第一个,所以我们一般都要加上visibleToUser()这个属性表示在可视范围内的。 三、开发遇到问题记录 1、当使用截图找相似图的时候,最好不要采用scrcpy的投屏形式进行截屏,直接采用手机截图(因为这样分辨率一样,更好找) 因为有些手机没法永久设置同意截图的权限,导致每次运行都要在截图的时候进行同意权限,那么在刚开始运行脚本的时候就进行设置权限,而这个权限只需要同意一次就可,请求截图只要请求一次,否则会堵塞。 //封装一个截图函数 function imageClick(smallImgpath, saveImgPath, threshold, screen) { for (var i=0; i<=5; i++) { if (screen) { if (sig) { if (!requestScreenCapture()) { // 请求截图 // console.log("请求截图失败"); exit(); } sig = false } var img = captureScreen(); //截图 images.saveImage(img, "/sdcard/Download/" + saveImgPath); } var bg = images.

Windows常用硬件信息查看(命令行)

查看磁盘信息: CPU 型号和主频等信息 wmic cpu get name CPU 的 Core 的个数: wmic cpu get numberofcores 逻辑 CPU 的个数: wmic cpu get numberoflogicalprocessors 服务器主板上 cpu 的 socket(插槽)个数: wmic cpu list brief 服务器生产商(比如 inspur): wmic bios get manufacturer 服务器主机的序列号(贴在服务器主机机身上): wmic bios get serialnumber 服务器型号: wmic csproduct 服务器能安装的最大内存大小(KB 为单位): wmic memphysical get maxcapacity 服务器当前已经安装内存的制造商信息,容量信息(B 为单位): wmic memorychip get manufacturer,capacity 服务器当前已经安装网卡的速度信息(b 为单位): wmic nic get adaptertype,name,speed 服务器操作系统版本,位数信息: wmic os get name,osarchitecture,version 示例:

python语法-def()详细介绍(特别全)

1. 什么是函数 在 Python 中,函数是一种可重用的代码块,用于执行特定的任务或操作。函数可以接受输入参数,并返回输出结果,从而实现模块化和封装性编程的目的。Python 中定义函数的语法如下: def function_name(parameters): """ Function documentation string. """ # Function body goes here. return [expression] 其中,def 是定义函数的关键字,function_name 是函数的名称,parameters 是函数的参数列表,用圆括号包裹,多个参数之间用逗号分隔,如果没有参数,则留空即可。函数名称和参数列表组成了函数的签名(signature),用于唯一识别和调用该函数。 函数的主体部分由冒号和缩进的代码块组成,通常包含一些语句和表达式来完成具体的计算或操作。函数的文档字符串(documentation string)是一个可选的字符串,用于描述函数的作用、参数、返回值等信息,可以通过内置函数 help() 来查看。 函数执行完毕后,可以使用 return 语句来返回一个值(expression),也可以不返回任何值,此时默认返回 None。 下面是一个简单的示例,演示如何定义和调用一个函数: def add_numbers(a, b): """ Add two numbers and return the result. """ return a + b x = 3 y = 4 z = add_numbers(x, y) print(z) # Output: 7 上面的示例中,我们定义了一个函数 add_numbers,它接受两个参数 a 和 b,并返回它们的和。然后,我们将 x 和 y 的值分别设置为 3 和 4,并调用 add_numbers 函数来计算它们的和,最后将结果赋给变量 z 并输出。

Matlab读取excel文件中的数据

Matlab读取Excel文件指南 在Matlab中,读取Microsoft Excel文件非常简单。在本文中,我们将介绍如何使用Matlab读取Excel文件,并展示一些实用的技巧和窍门。 导入Excel文件 使用Matlab读取Excel文件非常简单。下面是一个示例: data = xlsread('Data.xlsx'); 在上面的示例中,我们使用xlsread函数导入了一个名为Data.xlsx的Excel文件。这个函数返回一个数据矩阵。 选择要读取的Excel文件的工作表 当Excel文件包含多个工作表时,你需要指定要读取的工作表。例如: [data, header] = xlsread('Data.xlsx', 'Sheet1'); 在上面的示例中,我们使用xlsread函数读取了Data.xlsx文件中的第一个工作表(Sheet1)的内容,并将结果存储到了名为data和header的变量中。 指定读取Excel文件的数据范围 你可以使用xlsread函数的第三个参数来指定要读取的Excel文件中的数据范围。 data = xlsread('Data.xlsx', 'Sheet1', 'B2:E6'); 在上面的示例中,我们使用xlsread函数仅读取了B2到E6的单元格范围内的数据。 读取Excel文件中的字符串 有时,Excel文件中包含字符串数据。使用Matlab读取Excel文件时,你可以使用xlsread函数的另一个输出参数(txt)来读取这些字符串。 [data, txt, raw] = xlsread('Data.xlsx', 'Sheet1'); 在上面的示例中,我们使用xlsread函数从Data.xlsx文件中的Sheet1读取了数据,并使用txt参数返回了字符串数据。 处理Excel文件中的数字和日期 当Excel文件中包含数字或日期时,你可以使用xlsread函数读取它们,并使用相应的Matlab函数进行处理。 例如,可以使用datenum函数将Excel文件中的日期转换成Matlab日期格式: [~, ~, raw] = xlsread('Data.xlsx', 'Sheet1'); dates = raw(2:end, 1); % 跳过标题行 dates_num = datenum(dates, 'mm/dd/yyyy'); 在上面的示例中,我们首先使用xlsread函数读取Data.xlsx文件中的原始数据,并从中提取日期数据。然后,我们使用datenum函数将这些日期转换为Matlab日期格式(以序号表示)。 同样,可以使用mat2cell函数将从Excel文件中读取的列向量转换为单元格数组。 [~, ~, raw] = xlsread('Data.xlsx', 'Sheet1'); data = raw(2:end, [2, 3]); data_cell = mat2cell(data, ones(size(data, 1), 1), ones(size(data, 2), 1)); 在上面的示例中,我们使用mat2cell函数将2和3列的数据从Excel文件中的raw变量转换为一个名为data_cell的单元格数组。

【Linux】System V 共享内存、消息队列、信号量

🍎作者:阿润菜菜 📖专栏:Linux系统编程 文章目录 system V共享内存介绍理解共享内存IPC实现共享内存IPC认识接口代码实现 深入理解什么是同步与互斥共享内存的内核数据结构IPC资源的组织方式(多态)共享内存的优点和缺点(管道和shm分别数据拷贝次数) 认识信号量System V 消息队列 system V共享内存介绍 System V 共享内存是一种进程间通信的机制,它允许多个进程共享一块物理内存区域(称为“段”)。System V 共享内存的优点是效率高,因为进程之间不需要复制数据;缺点是需要进程之间进行同步,以避免数据的不一致性。共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到 内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据 示意图: 理解共享内存IPC 进程凭什么独立?每个进程拥有自己独立的进程地址空间mm_struct,自己独立的映射的物理内存空间。进程独立性的实现主要依赖于操作系统和硬件的支持。操作系统通过为每个进程分配独立的虚拟地址空间,使得每个进程都有自己的代码和数据空间,这样不会被其他进程干扰。硬件通过内存管理单元(MMU)来实现虚拟地址到物理地址的映射,以及分页或分段的方式来划分内存空间。操作系统还通过进程调度算法来控制每个进程的执行顺序和时间片,以及通过进程同步和通信机制来协调多个进程之间的关系。实现进程间通信的第一个前提就是如何让不同的进程看到同一份资源,匿名管道我们是通过子进程继承父进程打开的资源,命名管道是通过两个进程都打开具有唯一性标识的命名管道文件,而共享内存其实是通过OS创建一块shm(共享内存块),然后通过MMU将shm的地址分别映射到两个进程的各自地址空间当中,那么两个进程就可以通过这份虚拟起始地址来进行进程间通信。 在应用层也就是用户层,我们只能操作虚拟地址,但内核中会有MMU进行虚拟地址的映射,所以进程在IPC时,只需要操纵虚拟地址即可,从虚拟地址中读取或向虚拟地址中进行写入,这样就完成了共享内存式的IPC。所以通过让不同的进程,看到同一份物理内存块的方式,就叫做共享内存!为什么说共享内存是最快的IPC形式? 共享内存是一种进程间通信(IPC)的方式,它允许多个进程访问同一块逻辑内存,从而实现数据的快速交换。共享内存是最快的IPC形式,因为它避免了数据在进程间的复制,而是直接在内存中读写。要使用共享内存,需要用到一些函数,如shmget, shmat, shmdt, shmctl等。这些函数可以创建、映射、分离、控制共享内存段。共享内存的优点是高效和灵活,缺点是没有提供同步机制,需要借助其他手段来实现进程间的同步访问,而且共享内存没有任何保护机制 那管道呢?系统接口有封装。 实现共享内存IPC 认识接口 命令查看 共享内存是否已经存在 ipcs -m 查看共享内存 ipcrm -m 用于删除共享内存 — 注意使用shmid进行删除 类比于文件描述符 System V 共享内存的API包括以下几个系统调用: shmget(2):创建一个新的段或获取一个已存在的段的标识符(ID)。这个ID是用来在其他API中引用段的。shmat(2):将一个已存在的段映射到调用进程的虚拟地址空间中。这样,进程就可以通过指针来访问共享内存中的数据。shmdt(2):将一个段从调用进程的虚拟地址空间中解除映射。这样,进程就不能再访问共享内存中的数据。shmctl(2):对一个段进行控制操作,例如修改它的权限、获取它的状态信息、删除它等。 1.shmget()函数是用来创建或打开一块共享内存的,它的原型是:int shmget (key_t key, size_t size, int shmflg); 第一个参数key是一个非零整数,它为共享内存段提供一个外部名,可以用IPC_PRIVATE或ftok()函数生成。shmget()函数成功时返回一个与key相关的共享内存标识符(非负整数),用于后续的共享内存函数。调用失败返回-1。 第二个参数size是以字节为单位指定需要共享的内存容量。所有的内存分配操作都是以页为单位的,所以如果申请的内存大小不是页的整数倍,会被向上取整到最近的页大小。 第三个参数shmflg是一组标志位,它可以指定权限标志、创建标志和排他标志。权限标志与文件的读写权限一样,如0644表示允许创建者读写,其他用户只读。创建标志IPC_CREAT表示如果共享内存不存在,则创建一个新的共享内存,否则打开已有的共享内存。排他标志IPC_EXCL表示只有在共享内存不存在时,才创建新的共享内存,否则返回错误。 共享内存的大小是以4kb为单位的,这是巧合吗?是这样的(对应磁盘文件系统):这里第二个参数是共享内存的大小,一般建议将开辟的共享内存大小设置为4KB的整数倍,内存划分内存块的基本单位是Page,大小刚好是4KB,所以建议将大小设置为4KB的整数倍,如果你设置成4097什么的,有点浪费内存,因为实际内核会开辟8KB大小的空间。 2.shmat()函数用来将共享内存段连接到进程的地址空间,它的原型是:void * shmat (int shmid, const void *shmaddr, int shmflg); 第一个参数shmid是由shmget()函数返回的共享内存标识符。第二个参数shmaddr指定共享内存连接到当前进程中的地址位置,通常为NULL,表示让系统来选择共享内存的地址。第三个参数shmflg是一组标志位,可以指定SHM_RDONLY表示共享内存只读,或者默认为0表示可读可写。调用成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1。 3.shmdt()函数用来将共享内存从当前进程中分离,它的原型是:int shmdt (const void *shmaddr);

Matlab画图彩色变黑白

摘要:自己写论文的时候,Matlab画出来的是彩色的,期刊要求论文插图必须是黑白色,想了老半天怎么用PS把彩色变成黑白,后来灵机一动,所有线条用黑色不就好啦,果然最后解决问题,特此记录一下。 文章目录 一、使用步骤1.图变黑白2.图变黑白+实心的 二、总结 一、使用步骤 1.图变黑白 代码如下(示例):k代表黑色 plot(X,Y1,' k - p',X,Y2,' k- x',X,Y3,'k-^') 效果如下: 2.图变黑白+实心的 代码如下(示例):再在结尾处添加'MarkerFaceColor','k' plot(X,Y1,' k - p',X,Y2,' k- x',X,Y3,'k-^', 'MarkerFaceColor','k'); 二、总结 1.Matlab画黑白图,直接让每个线条都是黑色,即,添加k即可 2.图形想要空心变成实心的,就plot命令结尾处添加'MarkerFaceColor','k'

vue用使用异步+reduce实现循环调用接口(上一个接口调用完毕再调用下一个接口)

需求介绍: vue循环请求同一个接口,等接口返回数据之后在进行下次循环(在项目中,有时候会需要批量操作,有些更特殊的还需要按顺序调用接口。) 注意点:(批量下发10个任务,按任务序号顺序下发,同时需要等上一个任务下发完成再进行下一个任务的下发(不然可能会有后面的接口执行更快提前下发的情况)) 代码如下: // 批量下发 multipleIssue() { const arr = [123, 456, ...id] var that = this // 改变this指向 function callPromise(item) { return new Promise((resolve, reject) => { testInterface({ id: item }).then((res) => { if (res.status) { that.$message({ // 方法内部用that替代this message: '下发成功', type: 'success' }) resolve(item) } else { that.$message.error(res.msg) } }) }) } const result = arr.reduce((accumulatorPromise, next) => { return accumulatorPromise.then(() => { // 上一个接口执行完毕再执行下一个 return callPromise(next) }) }, Promise.

JavaScript学习(九) —— 函数式编程

百科定义: 函数式编程(Functional Programming)是种编程范式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。 写在前头:本人之前并没有过多了解过函数式编程,也很少发散思维和总结。直到最近开始写技术文章,写到函数式编程这个主题时,阅览了大量大神写的文章后才恍然,发现实战项目中很多模块用到了函数式编程。写这篇博文的过程也是自己系统学习这种编程范式的过程,用自己所学的知识尽力把函数式编程涉及到的知识点都说明白。 目录 一、纯函数二、函数柯里化(Currying)三、函数组合四、一个实际例子五、一些通用函数库 一、纯函数 要弄清楚函数式编程的具体实现和实际使用方法,需要先弄清楚纯函数的概念。我们一直说的函数式编程中的函数指的是数学中的函数,类似我们高中学过的关于自变量x的函数f(x)、g(x)还有复合函数f(gx)等概念。这样的数学函数可算是纯函数的一种。 纯函数的特性: 对于相同的输入,永远会得到相同的输出没有任何可观察的副作用不依赖外部环境的状态。 JS中某些对数组的一些方法(函数)就有纯和非纯的分别: 纯函数: var arr = [1,2,3,4]; console.log(arr.slice(0,2)); // [1, 2] console.log(arr); // [1, 2, 3, 4] slice是纯函数,它没有改变原来的数组arr。 非纯函数: var arr = [1,2,3,4]; console.log(arr.splice(0,2)); // [1, 2] console.log(arr); // [3, 4] splice改变了原来的数组arr,是非纯的函数。 以上面两个例子对比: 我们的目的是想通过调用一个函数后,获得一个截取原数组arr的结果,但并不想改变原数组arr。非纯函数splice随便就把外部变量或状态(原数组arr)修改,会导致很多预期之外的结果,这样的副作用不是我们所期望的。在函数式编程范式中,我们当然希望使用纯函数slice,它不会修改原数组,没有副作用。 看一个函数会依赖外部环境的状态的示例: 例1: var price = 69.99; function discount(){ return price * .8; } console.log(discount()); // 55.992 console.log(price); // 69.99 例1的discount方法引用了外部状态price,如果修改了外部状态price,会轻松影响discount方法返回的值,对于大型应用程序会增强系统复杂性和维护的难度。 解决这个问题的方法是把价格当作参数传入函数: 例2: var price = 69.

软件测试技术(四)白盒测试

白盒测试 白盒测试(White Box Testing)又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。白盒测试只测试软件产品的内部结构和处理过程,而不测试软件产品的功能,用于纠正软件系统在描述、表示和规格上的错误,是进一步测试的前提。 白盒测试遵循的四大原则: 保证一个模块中所有路径至少被测试一次;所有逻辑值都要测试真(true)和假(false)两种情况检查程序的内部数据结构是否有效;检查上、下边界及可操作范围内运行所有循环 静态白盒测试 白盒测试分静态和动态两种,静态测试是指不运行程序,通过人工对程序和文档进行分析与检查。下面是静态白盒测试检查的故障模式。 内存泄漏的故障(Memory Leak Fault, MLF)数组越界故障的故障(Out of Bounds Array Access Fault OBAF)使用未初始化变量故障(Uninitialized Variable Fault,UVF)空指针使用故障(NULL Pointer Dereference Fault NPDF)非法计算类故障(Illegal Computing Fault ILCF)死循环结构(Dead Loop Fault DLF)资源泄漏(RLF)并发故障 (Concurrency Fault)安全漏洞故障疑问代码故障 简单来说,静态白盒测试就是看代码找bug 动态白盒测试 白盒测试分静态和动态两种,动态测试是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能。 动态白盒测试流程: 选取定义域有效值,或定义域外无效值;(等价类划分思想)已选取值决定预期的结果;用选取值执行程序;执行结果与对已选取值决定预期的结果对比,不吻合程序有错 逻辑覆盖测试 为了满足白盒测试的四大原则,需要使用逻辑覆盖测试法来设计测试用例。逻辑覆盖测试是以程序内部的逻辑结构为基础设计测试用例的方法,首先需要就行代码的结构分析,绘制流程图。 代码如图所示: 对应结构图如下: 注意:圆圈中的数字代表代码的行数 之后进行逻辑覆盖,由于覆盖测试的目标不同,逻辑覆盖又可分为:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖。 覆盖方法介绍语句覆盖选择足够多的测试用例,使得程序中的每个可执行语句至少执行一次。判定覆盖通过执行足够的测试用例,使得程序中的每个判定至少都获得一次“真”值和“假”值, 也就是使程序中的每个取“真”分支和取“假”分支至少均经历一次,也称为“分支覆盖”。条件覆盖设计足够多的测试用例,使得程序中每个判定包含的每个条件的可能取值(真/假)都至少满足一次。判定/条件覆盖设计足够多的测试用例,使得程序中每个判定包含的每个条件的所有情况(真/假)至少出现一次,并且每个判定本身的判定结果(真/假)也至少出现一次。满足判定/条件覆盖的测试用例一定同时满足判定覆盖和条件覆盖条件组合覆盖通过执行足够的测试用例,使得程序中每个判定的所有可能的条件取值组合都至少出现一次。满足组合覆盖的测试用例一定满足判定覆盖、条件覆盖和判定/条件覆盖路径覆盖设计足够多的测试用例,要求覆盖程序中所有可能的路径 从表中的介绍可知,从上到下,该方法覆盖的路径越多。其他方法覆盖的路径不全面,那为什么不直接使用路径覆盖?这是由于如果程序中出现了多个判断和多个循环,可能的路径数目将会急剧增长,以至实现路径覆盖不可能。 为了解决上面的问题,出现了基本路径覆盖,它在程序控制流图的基础上,通过分析程序控制流图的环路复杂性,导出基本可执行路径(独立路径)的集合,然后据此设计测试用例。 各个覆盖方法的优缺点: 在实际测试中,即使对于路径数很有限的程序已经做到路径覆盖,仍然不能保证被测试程序的正确性,还需要采用其他测试方法进行补充。 数据流测试 数据流测试分析常常集中于定义/引用异常的缺陷,用于如下三方面测试。 变量被定义,但是从来没有使用(引用)所使用的变量没有被定义变量在使用之前被定义两次 早期的数据流测试主要用于检测程序编写时出现的一些警告信息,如“所定义的变量未被使用等”问题,这些问题光靠简单的语法分析器或者是语义分析器是无法检测出来的。 程序插桩 在程序的特定部位插入记录动态特性的语句,最终是为了把程序执行过程中发生的一些重要的历史事件记录下来。例如,记录在程序执行过程中某些变量值的变化情况,变化的范围等。这些插入的语句常常被称为“探测器”或者“探测点”。 总结 白盒测试方法基于被测程序的源代码开发测试用例。常见的白盒测试方法有逻辑覆盖、数据流测试、路径分析以及程序插装等。逻辑覆盖以程序内部的逻辑结构为基础设计测试用例,要求对被测程序的结构作到一定程度的覆盖,如语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖及路径覆盖。路径覆盖是最强的逻辑覆盖准则,实际上我们只能有选择地测试程序中某些有代表的性路径。

dropout层的添加,L2正则化

dropout 一般添加在线性层,要给某一线性层添加dropout,dropout函数一般写在此线性层的前面。 注意:最后一个线性层前面一般不加dropout,一般线性层和激活函数搭配 import torch from torch import nn self.linears = nn.Sequential( nn.Linear(1, neural num), nn.ReLU(inplace=True), nn.Dropout(p=0.5), nn.Linear(neural_num, neural_num), nn.ReLU(inplace=True), #此三行为一组,Dropout写在对应线性层的前面 nn.Dropout(p=0.5), #有人说一般不加,但也可以加 nn.Linear(neural num, 1) #最后一个线性层一般不加Dropout ) L2正则化: net_normal = Net(neural_num=n_hidden) net_weight_decay = Net(neural_num=n_hidden) optimizer = torch.optim.SGD(net_normal.parameters(), lr=lr_init, momentum=0.9) optimizer = torch.optim.SGD(net_weight_decay.parameters(), lr=lr_init, momentum=0.9, weight_decay=1e-2) 仅仅只是优化器中多加此参数代表使用了L2正则化。weight_decay=1e-2 同济自豪兄好像把dropout写在了此线性层的后面 原始的: 加上激活函数后的: 另一种加dropout:

concat合并的一个问题及解决办法pandas DataFrame

使用pandas DataFrame concat合并时碰到一个问题,整理一下发出来,希望有用 第一步:读取测试表格 import pandas as pd df_1 = pd.DataFrame(pd.read_excel("测试表格.xlsx", engine='openpyxl')) print(df_1) 表格信息 第二步:以测试表格为基础创建另一张表 df_2 = df_1 df_2['B列'] = df_2['B列'].map(str) + "_后缀" print(df_2) 得到新表格如下 想使用concat得到如下信息 第三步:使用concat合并df_1和df_2 df_3 = pd.concat([df_1, df_2]) print(df_3) 结果如下 前5行明显错误,本该不应该有后缀的信息,被自动添加。 解决办法 在第二步复制表格1时,先重置索引 df_2 = df_1.reindex(columns=['A列', 'B列']) df_2['B列'] = df_2['B列'].map(str) + "_后缀" 再使用concat合并即可得到目标表格 问题解决,完整代码如下 # -*- coding:utf-8 -*- import pandas as pd df_1 = pd.DataFrame(pd.read_excel("测试表格.xlsx", engine='openpyxl')) # print(df_1) df_2 = df_1.reindex(columns=['A列', 'B列']) df_2['B列'] = df_2['B列'].map(str) + "

「OceanBase 4.1 体验」|大厂开始接入的国产分布式数据库,不来了解了解?

OceanBase 4.1 体验 前言OCP Express在线升级功能租户级物理备库TP(事务处理)和AP(分析处理)优化TP 性能优化AP 性能优化 结尾 前言 上次我们讲了本人自己亲自上手OceanBase 4.1的初体验,国产的分布式数据库也太太太太太便捷了吧,具体参考链接: 「OceanBase 4.1 体验」|国产分布式数据库不好用?别再打脸了,上次只是初步体验,经过了多天的持续体验,OceanBase 4.1简直就是宝藏分布式数据库,那可是 for i in range(9999999999999999999999999999999999999999999999999999999999999999999999): print("太"); 好用了! OCP Express在线升级功能 OCP表示 “Online Cluster Platform”,它可以为OceanBase用户提供更加高效、稳定的在线升级方式。是一种旨在实现在线升级的集群平台。 单击式在线升级 OCP Express可以让用户在不停机的情况下快速完成在线升级,只需要单击按钮即可完成整个升级过程。例如,在使用OceanBase 4.0版本时,用户可以轻松地升级到OceanBase 4.1版本,而无需任何额外操作。 故障自愈 在升级过程中,如果发生故障,OCP Express会自动检测并进行相应的处理,以确保系统的稳定和可靠性。例如,如果某个节点在升级过程中出现了故障,OCP Express会自动将其踢出集群,并进行修复,直到节点重新运行后再次将其加入集群。 并行化升级 OCP Express可以同时对多个节点进行升级,大大缩短了升级时间。例如,在一个由100个节点组成的集群中,OCP Express可以同时升级10个或20个节点,从而显著缩短了升级时间。 回滚支持 如果在升级过程中发生错误,OCP Express可以快速回滚到之前的状态,以避免数据丢失和系统不稳定。例如,在升级过程中,如果出现了无法解决的问题,OCP Express会自动将集群回滚到升级之前的状态。 租户级物理备库 OceanBase 4.1的新特性:租户级物理备库是一种数据库备份和恢复方案,它可以对整个集群进行备份,包括所有的数据和元数据。租户级物理备库与传统的逻辑备份不同,它基于底层文件系统或块设备进行备份,因此备份速度更快、可靠性更高。在租户级物理备库方案中,备份文件通常会存储到独立的存储介质中,以保证备份文件的安全性和可靠性。用户可以设置定期备份策略,例如每天备份一次,以确保备份文件始终是最新的。 支持增量备份 OceanBase 4.1版本可以通过增量备份方式实现备份操作,仅备份变更部分数据,可大幅减少备份所需时间和存储空间。 支持并行备份 在备份大型数据库的情况下,OceanBase 4.1版本可以支持并行备份,将备份任务分成若干个独立的作业并行执行,加快备份过程。同时,多个备份进程可以同时访问相同的数据页,提高备份速度。 支持增量恢复 除了增量备份外,OceanBase 4.1版本还支持增量恢复,可以快速恢复更新的数据,加快恢复过程。 备份文件可去除敏感信息 OceanBase 4.1版本备份文件可去除敏感信息(如密码等),保证备份数据的安全性。 支持灾备备库的动态注册 当出现故障时,OceanBase 4.1版本支持将备库注册到主库以实现灾备自动切换,提高系统的可用性。 支持增量异地备库 在多地域、多数据中心部署的场景下,OceanBase 4.1版本支持增量异地备库,可实现数据在异地备库之间的实时同步,保证数据的高可用性。 支持全量备份灾备 OceanBase 4.1版本的全量备份灾备功能可实现全量备份文件的跨地域复制,从而在灾难恢复时快速恢复原有数据。 支持备份集成到管理中心 OceanBase 4.

Python学习笔记-18(函数小案例,小练习题等)

2023.4.26 努力学习python,想为以后可以有一份额外收入,如果有大神可以指点一下,我将不胜感激 如果有大神想以后拥有一个合作伙伴进行交流,我会尽力赶上您的脚步! 一个小题我是在其他网站上做的,我感觉适合初学者,拿来做一下小案例记录一下 1.逻辑判断 小试牛刀! #题目要求: #1.给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。 #举例: ''' 输入:num = 8 输出:4 解释: 步骤 1) 8 是偶数,除以 2 得到 4 。 步骤 2) 4 是偶数,除以 2 得到 2 。 步骤 3) 2 是偶数,除以 2 得到 1 。 步骤 4) 1 是奇数,减 1 得到 0 。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/number-of-steps-to-reduce-a-number-to-zero 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 ''' #使用函数题解 def numberOfSteps(num): i = 0 while True: if num % 2 == 0 and num > 0: #判断偶数奇数,然后做出相应的动作,并添加一次次数 num = int(num / 2) i += 1 if num % 2 !