1、查看各个节点状况 Ready(就绪):节点正常运行且准备好接受工作负载。这是节点的正常工作状态。NotReady(未就绪):节点无法接受工作负载,可能是由于网络问题、资源不足或其他故障导致的。OutOfDisk(磁盘空间不足):节点磁盘空间不足,无法继续运行工作负载。MemoryPressure(内存压力):节点内存资源不足,无法继续运行工作负载。DiskPressure(磁盘压力):节点磁盘资源不足,无法继续运行工作负载。PIDPressure(进程ID压力):节点的进程ID资源不足,无法继续运行工作负载。NetworkUnavailable(网络不可用):节点的网络连接出现问题,无法继续运行工作负载。 kubectl get nodes 2、查看端口映射 将 <namespace> 替换为你要查看的命名空间名称。这样,你将只获取特定命名空间的服务和端口映射信息。
kubectl get services -n <namespace> 3、查看K8s版本 kubectl version 4、进入容器内部 # test-pod 是pod_name container1是container_name kubectl exec -it test-pod --container container1 -- /bin/bash
软件测试网站压力测试报告
一、测试目的
本次压力测试旨在模拟实际网站系统承受用户并发访问的情况,检测系统的性能、可靠性和稳定性。通过对网站进行多用户并发访问,验证系统在高负载情况下的处理能力和稳定性,为后续优化提供参考依据。
二、测试环境
硬件环境:服务器配置为四核CPU、8GB内存、100Mbps带宽。
软件环境:操作系统为Windows Server 2016,数据库为MySQL 8.0。
压力测试工具:使用LoadRunner客户端模拟100、200、500个虚拟用户并发访问。
三、测试过程
准备测试数据:根据实际用户数据,准备了10000条测试数据。
设计测试场景:根据实际用户行为,设计了登录、注册、浏览商品、下单等测试场景。
执行测试:使用LoadRunner模拟不同数量的虚拟用户,按照设计的测试场景进行并发访问。
监控系统响应时间:在测试过程中,实时监控系统各个页面的响应时间,观察系统在不同负载下的性能表现。
记录测试结果:记录每个测试场景下的系统响应时间、吞吐量、错误率等指标。
四、测试结果
以下是各个测试场景下的系统性能指标统计:
测试场景并发用户数平均响应时间(ms)吞吐量(reqs/s)错误率(%)登录10020015000.5%注册20035030001.0%浏览商品50060060002.5%下单50080080003.5% 根据上述测试结果,我们可以得出以下结论:
系统在低负载情况下(100个并发用户)表现良好,各项指标均在正常范围内。
随着负载增加,系统的响应时间逐渐增加,但在200个并发用户以下,系统的响应时间仍在可接受的范围内。
当并发用户数达到500时,系统的响应时间明显增加,但仍在可接受的范围内。此时系统的吞吐量较高,能够处理大量的用户请求。
在整个测试过程中,系统的错误率较低,表现出较好的稳定性。
五、总结与建议
根据本次压力测试报告的结果,我们可以得出以下结论:
系统在低负载情况下表现良好,可以满足实际用户的需求。
当负载增加时,系统的响应时间会有所增加,但在可接受的范围内。
系统在较高负载情况下仍能保持较好的稳定性和吞吐量。
针对以上结论,我们提出以下建议:
对系统进行进一步优化,提高响应速度和稳定性,以应对更高的负载情况。
在系统设计时,应考虑到未来的业务发展和用户增长情况,确保系统具备足够的扩展能力。
在系统运行过程中,应定期进行性能监控和优化,确保系统始终处于最佳状态。
本报告为第三方软件测试机构出具的软件测试报告,旨在为软件开发团队提供客观、公正、专业的测试结果和建议。我们将继续为软件开发行业提供高质量的软件测试服务,帮助客户提高软件质量和可靠性。
文章来源:https://www.kexintest.com/sys-nd/306.html
标签:压力测试、软件测试机构
SWAT水文模型建立及应用 SWAT模型建立常见疑问 1 DEM数据的利用1.1 高分辨率DEM数据的获取1.2 数据处理1)DEM数据的下载与拼接处理2)数据的投影转换步骤1: 设置图层投影坐标步骤2: 更改DEM数据投影 2 子流域的划分2.1 准备工作:启动ArcSWAT分区模块2.2 定义SWAT工程步骤1:DEM的加载步骤2:MASK定义(可选)步骤3: 数字化河网添加(可选)步骤4:河网生成步骤5: Outlet、Inlet定义(可选)步骤6: 流域总出口指定及子流域划分步骤7:子流域参数的计算 参考 SWAT水文模型原理及数据库简介可参见另一博客文章-【水文模型】SWAT水文模型原理及数据库简介。
SWAT建模过程中出现的各种错误及解决方案见另一博客-【SWAT水文模型】ArcSWAT各种报错总结。
本博客主要介绍SWAT水文模型建立及应用。以下SWAT水文模型建立过程均以洮河流域为例,区域地理位置/水系图如下:
SWAT模型建立 SWAT可以用来模拟单个流域或有水力联系的流域系统。每一个流域先被划分为子流域,然后根据土地利用和土壤类型来划分水文响应单元(HRUs)。
模型建立流程如下所示:子流域数据准备→子流域划分→土壤、土地数据准备→气象数据的准备→水文相应单元的划分→率定
步骤1:划分流域边界 使用数据:DEM、河流GIS图层
步骤2:HRU子流域划分 使用数据:土地利用库、土壤库、气象库
步骤3:率定(SWAT CUP) 使用数据:水文站(径流数据)
常见疑问 1.研究区域并非完整流域,如何处理?
我的做法是直接将包含该区域的三级流域拿来分析。
1 DEM数据的利用 DEM (Digital Elevation Model) 是描述区域地貌形态空间分布的GIS数据。DEM用一组有序数值阵列形式表示地面高程,是一定范围内规则格网点的平面坐标(X,Y)及其高程(Z)的数据集。在利用SWAT模型建模的过程中,将利用DEM数据进行流域 水系生成 以及 子流域划分 等工作。
1.1 高分辨率DEM数据的获取 目前使用较多的高分辨率DEM数据包括 SRTM(Shuttle Radar Topography Mission) 90米分辨率数据以及ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer) GDEM(Global DEM)30米分辨率数据两类。这两类数据都可通过中国科学院国际科学数据服务平台进行下载。
此外,亦有ALOS_PALSAR_12.5m分辨率DEM数据。
1.2 数据处理 1)DEM数据的下载与拼接处理 本次处理以ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer) GDEM(Global DEM)30米分辨率数据为例,根据经纬度1°×1°分片,拼接裁剪得到研究区域DEM数据,具体拼接裁剪过程见另一博客-【ArcGIS】拼接/裁剪得到研究区域DEM高程图。
最简版本 只限制了结束时间不能在开始时间前 后续有使用到在详细完善功能
<el-row :gutter="20"> <el-col :span="5"> <el-form-item label="预计进企时间" prop="gmtInto" :rules="rules.gmtInto"> <el-date-picker size="small" :picker-options="pickerOptionsStart" v-model="formData.gmtInto" type="datetime" value-format="yyyy-MM-dd HH:mm" placeholder="选择日期时间"> </el-date-picker> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="预计离企时间" prop="gmtLeave" :rules="rules.gmtLeave"> <el-date-picker size="small" :picker-options="pickerOptionsEnd" v-model="formData.gmtLeave" type="datetime" value-format="yyyy-MM-dd HH:mm" placeholder="选择日期时间"> </el-date-picker> </el-form-item> </el-col> </el-row> data() { return { formData:{}, pickerOptionsStart: { disabledDate: (time) => { if (this.formData.gmtLeave) { return ( time.getTime() > new Date(this.formData.gmtLeave).getTime() ); } } }, pickerOptionsEnd: { disabledDate: (time) => { if (this.
目录
OpenCV
pcl
pangolin
SuiteSparse
OpenCV 编辑环境变量
D:\Automation\VS2017\OpenCV_DIR\build\x64\vc14\bin 包含目录/库目录
包含目录
D:\Automation\VS2017\OpenCV_DIR\build\include\opencv D:\Automation\VS2017\OpenCV_DIR\build\include D:\Automation\VS2017\OpenCV_DIR\build\include\opencv2 库目录
D:\Automation\VS2017\OpenCV_DIR\build\x64\vc14\lib 附加依赖项debug
opencv_calib3d2413d.lib opencv_contrib2413d.lib opencv_core2413d.lib opencv_features2d2413d.lib opencv_flann2413d.lib opencv_gpu2413d.lib opencv_highgui2413d.lib opencv_imgproc2413d.lib opencv_legacy2413d.lib opencv_ml2413d.lib opencv_nonfree2413d.lib opencv_objdetect2413d.lib opencv_ocl2413d.lib opencv_photo2413d.lib opencv_stitching2413d.lib opencv_superres2413d.lib opencv_ts2413d.lib opencv_video2413d.lib opencv_videostab2413d.lib 附加依赖项release
opencv_objdetect2413.lib opencv_ts2413.lib opencv_video2413.lib opencv_nonfree2413.lib opencv_ocl2413.lib opencv_photo2413.lib opencv_stitching2413.lib opencv_superres2413.lib opencv_videostab2413.lib opencv_calib3d2413.lib opencv_contrib2413.lib opencv_core2413.lib opencv_features2d2413.lib opencv_flann2413.lib opencv_gpu2413.lib opencv_highgui2413.lib opencv_imgproc2413.lib opencv_legacy2413.lib opencv_ml2413.lib pcl (1)一定要选择 Add PCL to the system PATH for all user
(2)在安装pcl过程中会弾出来openNI2的安装对话框,将其在 D:\Automation\VS2017\PCL_DIR\PCL 1.8.1\3rdParty\OpenNI2
电脑文件夹备份
cmd窗口输入shell:startup
将备份.bat文件放到,自启动文件夹下
bat文件内容写以下就可以了
Xcopy "D:\文件\" "F:\文件备份\" /E/H/C/I/y
Json数据处理 此处使用的JSON处理方式都为阿里下的fastjson2依赖(com.alibaba.fastjson2:fastjson2:2.0.15)下的处理方式。其他的也可以可能会有细微差距
String字符串格式的Json数据转换为JSON数据 //转为JSONObject格式数据 JSONObject jsonObject = JSON.parseObject(json); //转为JSONArray格式数据 JSONArray objects = JSON.parseArray(json); Json数据分为JSON对象即数据为对象用大括号{}包裹数据,即使用JSONObject接收数据。
另一个种常用为JSON数组类型数据用中括号[]包裹数据,即使用JSONArray接收数据。
提取JSONObject数据中想要的数据 如果直接提取对象数据中的某个值时:可以直接使用Object object = jsonObject.get(“subjectName”);
此处get()方法,即提取出值,提取出的为Object类型值,之后在转换为对应需要的值;如果提取对象中还包裹层对象数据,而我需要取的是该对象包裹的对象中的一个数据呢:如下类型JSON数据 { "aId": "90100", "id": 246680609219420160, "product": { "appCode": "8A57DB69BAB162A", "appSecret": "En1RCd80", "authorizationEnd": 168000, "authorizationStart": 169000, "id": "26240" } } 如果我需要取product对象中的appSecret的值那该如何处理呢,不急,JSONObject对象中有一个getJSONObject()方法可以使用。
首先我们去获取product数据**JSONObject jsonObject2 =
jsonObject.getJSONObject(“product”);这样我们就获取到了product的JSON对象,然后获取appSecret的值就在调用get()方法即可。如下:
JSONObject jsonObject2 = jsonObject.getJSONObject("product"); //此处为String类型,即get方法后为object对象直接调用toString方法转为String类型 String appSecret = jsonObject2.get("appSecret").toString; //如果确定且知道值时什么类型也可以直接获取对应类型 如下:
如果是取值对象中还包括数组集合形式的JSON数据,我们可以使用getJSONArray()方法去获取如对应的数组集合数据。 { "aId": "590100", "id": 24660160, "product": { "appCode": "1960D7DB69BAB162A", "appSecret": "En1R7ACd80", "authorizationEnd": 161000, "
蚂蚁集团产品经理实习环境靠着西湖,空气非常清新
在蚂蚁集团产品经理实习已经两周啦,给大家share这里的情况。公司环境:背靠西湖风景区,天然氧吧,但是蚊子也很多,这一点特别不友好;园区特别好看,空气非常清新,
题解 | #字符串排序#
import java.util.Scanner;import java.util.TreeMap;import java.util.TreeSet;impor
题解 | #删除字符串中出现次数最少的字符#
while True: try: inputstring = input() if len(inputstring) >
题解 | #最小长方形#
import syswhile True: a = [float('inf'), float('inf'), float('-inf'), float('
题解 | #牛群Z字型排列#
题目考察的知识点:二叉树层序遍历题目解答方法的文字分析:将二叉树层序遍历,然后将需要翻转的数组进行翻转即可。本题解析所用的编程语言:c++/** * struc
题解 | #求int型正整数在内存中存储时1的个数#
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息public class Main 题解 | #填充数组#
class Solution {public: #define A 1000000007 int FillArray(vector<int&g
题解 | #正则表达式匹配#
class Solution: def match(self, str, pattern) -> bool: # write code
一、Mybatis与Springboot整合 1.创建模块springboot03 2.pom.xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> </dependency> 3.aplication.yml logging: level: com: hjl: springboot03: debug mybatis: mapper-locations: classpath:mappers/**/*.xml type-aliases-package: com.hjl.springboot03.entity server: port: 8080 spring: application: name: springboot03 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/vue?useUnicode=true&characterEncoding=UTF-8 username: root password: root logging: level: com.hjl.springboot03: debug 4.代码生成插件 4.1resources/jdbc.properties jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/vue?useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=root 4.2resources/generatorConfig.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" > <generatorConfiguration> <!-- 引入配置文件 --> <properties resource="jdbc.properties"/> <!--指定数据库jdbc驱动jar包的位置--> <!-- <classPathEntry location="
文章目录 1. 什么是操作系统?2. 操作系统主要有哪些功能?3. 什么是内核?4. 什么是用户态和内核态?5. 什么是进程和线程?6. 进程间通信方式7. 什么是死锁?8. 产生死锁的四个必要条件是什么?9. 解决死锁的基本方法 1. 什么是操作系统? 操作系统是一种运行在内核态的软件。
它位于硬件和应用程序之间,主要用于管理计算机硬件和软件资源。比如:运行在电脑上的应用程序通过操作系统来调用内存以及磁盘等硬件。
2. 操作系统主要有哪些功能? CPU 管理:主要是进程管理。内存管理:主要利用了虚拟内存的方式。外存管理:主要是磁盘管理。I/O 管理:对输入/输出设备的管理。 3. 什么是内核? 内核是操作系统的核心,具有很高的权限,可以控制 CPU、内存、磁盘等硬件。
4. 什么是用户态和内核态? 用户态:我们运行的进程基本都是运行在用户态,权限比较低。当应用程序需要执行某些需要特殊权限的操作,就需要向操作系统发起系统调用请求,进入内核态。
内核态:运行在内核态的进程可以访问计算机的所有资源,权限比较高。
5. 什么是进程和线程? 进程是程序的执行过程。
一个进程是由多个线程组成的。
6. 进程间通信方式 管道:管道可以理解成缓存,从管道的一端写数据,另一端读数据。信号 : 信号就是一种通知,通知指定进程处理信号。比如 kill -9 1050 就表示给 PID 为 1050 的进程发送 终止 信号。信号量:信号量表示资源的数量,是进程同步的一种方式,通过 PV 操作来实现。 P 操作,会将信号量减 1,如果信号量 < 0,说明资源被占用,进程要阻塞等待;如果信号量 >= 0,说明资源可用,进程可正常继续执行。V 操作,会将信号量加 1,如果信号量 <= 0,说明有进程在阻塞队列里,会唤醒当前进程;如果信号量 > 0,说明阻塞队列里没有被阻塞的进程; 消息队列:消息队列和管道差不多,能承载更多的数据。Socket:用于客户端和服务器之间通过网络进行通信。 7. 什么是死锁? 假设有两个进程 A 和 B,以及两个资源 X 和 Y,它们的分配情况如下:
PyTorch 深度学习实践 第5讲 课后习题 由于本节习题很少看到比较完整的代码, 因此上传一个给大家参考.
B站 刘二大人
这里要注意一下, 在对不同优化器进行比较的过程中, 需要保持初始参数值一致, 这样才有可比性
# 练习5-1 尝试不同优化器训练线性模型,并保存图像 """ Adagrad Adam Adamax" ASGD LBFGS RMSprop Rprop SGD """ import torch import matplotlib.pyplot as plt x_data = torch.Tensor([[1.0], [2.0], [3.0]]) y_data = torch.Tensor([[2.0], [4.0], [6.0]]) class LinearModel(torch.nn.Module): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.linear = torch.nn.Linear(1, 1) self.linear.weight.requires_grad = True self.linear.bias.requires_grad = True def forward(self, x): x = self.linear(x) return x def init_weights(m): m.
文章目录 前言一、spring-boot-devtools添加热部署框架支持settings 开启项目自动编译开启运行中热部署使用Debug启动 二、IDEA 自带 HowSwap 功能设置 Spring Boot 启动类等待项目启动完成点击热加载按钮存在的问题 三、JRebel 插件【推荐】安装插件使用插件 前言 在日常开发中,我们需要经常修改 Java 代码,手动重启项目,查看修改后的效果。如果项目还比较小,重启速度比较快,等待的时间是较短的。但是随着项目逐渐变大,重启的速度变慢,等待时间越来越长,我们的效率就很低下。Spring Framework 提供了热部署(Hot Reload)功能,允许在开发过程中无需重启应用程序就能实时地修改代码并看到更改效果。这对于提高开发效率非常有帮助。以下是常见的几种热部署方式:
一、spring-boot-devtools spring-boot-devtools (opens new window)是 Spring Boot 提供的开发者工具,它会监控当前应用所在的 classpath 下的文件发生变化,进行自动重启。
添加热部署框架支持 在pom.xml中添加如下框架引用
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> settings 开启项目自动编译 开启运行中热部署 使用Debug启动 二、IDEA 自带 HowSwap 功能 该功能是 IDEA Ultimate 旗舰版的专属功能,不支持 IDEA Community 社区版。
设置 Spring Boot 启动类 等待项目启动完成 点击热加载按钮 每次修改 Java 代码后,点击左下角的「热加载」按钮,即可实现代码热加载
存在的问题 IDEA 自带 HowSwap 功能,支持比较有限,很多修改都不支持。
只能增加方法或字段但不可以减少方法或字段只能增加可见性不能减少只能维持已有方法的签名而不能修改等等。 三、JRebel 插件【推荐】 JRebel 插件是目前最好用的热加载插件,它支持 IDEA Ultimate 旗舰版、Community 社区版
前言 Hive是由Facebook开源,基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。本节内容我们主要介绍一下hive的安装与部署的相关内容。
正文 上传hive安装包到hadoop101服务器/opt/software目录 解压apache-hive-3.1.3-bin.tar.gz到/opt/module/目录下 - 命令:tar -zxvf /opt/software/apache-hive-3.1.3-bin.tar.gz -C /opt/module/
修改apache-hive-3.1.3-bin名字为hive-3.1.3,便于使用 命令:mv apache-hive-3.1.3-bin hive-3.1.3
配置hive的环境变量,便于使用hive - 使用vi编辑器修改/etc/profile.d/my_env.sh下的自定义环境变量,添加hive的环境变量
- 使配置的环境变量生效, source /etc/profile.d/my_env.sh,使hive命令生效
先启动hadoop集群,再启动hive - hadoop集群启动
- 初始化元数据库(默认是derby数据库):bin/schematool -dbType derby -initSchema
- 启动hive客户端,查看hive是否已经可以使用
结语 到这里,关于hive的安装部署就结束了,我们下期见。。。。。。
需求 最近想做一个小工具,大概要实现这样的效果:后端生成条形码后,不保存到服务器,直接返回给前端展示。
大概思路是,通过 python-barcode库 生成条码的字节流,生成字节流后直接编码成base64格式返回给前端,前端通过img标签展示base64格式的图片。
代码示例 后端代码
以flask为例,其他web框架实现的方法类似。
这里使用Code128格式的条码,可以去python-barcode官网看看,该工具还支持生成其他格式的条码。
@app.route('/barcode', methods=['POST']) def bar_code(): param_code = request.get_json()['barCode'] buffer = BytesIO() Code128(param_code, writer=SVGWriter()).write(buffer) res = base64.b64encode(buffer.getvalue()).decode('utf-8') return { "code": 200, "message": "success", "data": res } 前端代码
以vue为例
<template> <img :src="imgUrl" /> </template> <script setup> import { onMounted, ref, inject } from 'vue' const axios = inject("$axios") const imgUrl = ref(null) const load_barcode = async () => { // 请求后台 const param = { "
文章目录 背景介绍历史优化方案maven 代理优化 sync 时间背景优化方案 模块 aar 化背景优化方案收益 增量 java/kotlin 编译背景 编译耗时恶化近期优化方案app 壳模块 kapt 优化背景优化方案收益 kapt 隔离优化背景收益 transform 优化背景收益 dexBuilder 优化背景dexBuilder 增量效果量化优化方案desugarGraph 异常DesugaringGraph 逻辑概述收益 build-cache 优化踩坑apt 顺序不一致导致的缓存失效问题解决方案收益 编译耗时防恶化管控总结更多分享 背景介绍 Android 项目一般使用 gradle 作为构建打包工具,而其执行速度慢也一直为人所诟病,对于今日头条 Android 项目这种千万行级别的大型工程来说,加粗样式全量编译一次的时间可能高达六七分钟,在某些需要快速验证功能的场景,改动一行代码的增量编译甚至也需要等两三分钟,这般龟速严重影响了开发体验与效率,因此针对 gradle 编译构建耗时进行优化显得尤为重要。
在今日头条 Android 项目上,编译构建速度的优化和恶化一直在交替执行,
18 年时由于模块化拆分等影响,clean build 一次的耗时达到了顶峰 7 分 30s 左右,
相关同学通过模块 aar 化,maven 代理加速,以及增量 java 编译等优化手段,将 clean build 耗时优化到 4 分钟,增量编译优化到 20~30s 。
但是后面随着 kotlin 的大规模使用,自定义 transform 以及 apt 库泛滥,又将增量编译速度拖慢到 2 分 30s ,且有进一步恶化的趋势。
在之前的《手把手教你用 NebulaGraph AI 全家桶跑图算法》中,除了介绍了 ngai 这个小工具之外,还提到了一件事有了 Jupyter Notebook 插件: https://github.com/wey-gu/ipython-ngql,可以更便捷地操作 NebulaGraph。
本文就手把手教你咋在 Jupyter Notebook 中,愉快地玩图数据库。
只要你仔细读完本文,一条 %ngql MATCH p=(n:player)->() RETURN p 命令就可以直接查询出数据,再接上 %ng_draw 就可以画出返回结果。
下面,进入今天的主菜——Jupyter Notebook 扩展:ipython-ngql。
其实,ipython-ngql 这个扩展断断续续地开发了两年,我一直没有开发完成。恰好之前有空,并完成了一直以来的心愿,把 ipython-ngql 重构并正式发布了。它除了完全适配 NebulaGrpah 3.x 所有查询之外,还支持了 Notebook 内的返回结果可视化。
在介绍 ipython-ngql 是什么之前,我先做个简单的 Jupyter Notebook 介绍,虽然大多数的 Python 开发都知道。
什么是 Jupyter Notebook Jupyter Notebook / Jupyter Labs 项目最初起源自 IPython 这个项目,后者是一个命令行上的交互式 Python 解释环境。因为有很好的补全、高亮和丰富的扩展能力,IPython 很快就成为了 Python 的第一 IDLE 替代项目,并且后来衍生出来了可以在浏览器里做更多事情的笔记本模式。
Jupyter 的笔记本模式改变了数据科学和相关科研、工业领域里人们协作、开发、分享面向数据的工作方式。有了它,我们可以在一个笔记本中可复现、可分享地进行代码执行、科学计算、数据可视化等等操作,是数据科学家、科研工作者的非常喜欢的工具,而且它还早就引入了 Python 之外的很多其他语言作为执行内核支持。
因为在 Jupyter Notebook 中进行 NebulaGraph 的查询、计算、可视化一直是很多社区同学的心愿,在前阵子 NebulaGrpah AI Suite 的开发过程中,我并实现了 Jupyter 中方便进行 NetworkX / PySpark 的计算。既然有图计算了,索性我就把相关的查询、可视化功能一起做掉,并作为 Jupyter 的扩展一起发布出来给大家使用啦。
总代码:其中包含了自制的头文件和cpp文件tool用来实现特定的功能
/* * 天天酷跑开发日志 * 1.创建项目 * 2.导入素材 * 3.游戏界面 * 实际的开发流程 * 选择图形库或基于其他引擎 * 本项目基于EASY X * 1)创建游戏窗口 * 2)设计游戏背景 * a.3重背景不同的速度同时移动 * b.循环滚动背景的实现 * 3)实现游戏背景 * a.加载背景资源 * b.渲染 * 4.实现玩家奔跑 * 5.实现玩家跳跃 * 6.实现随机小乌龟 * 7.创建障碍物结构体数据类型 * 8.使用障碍物结构体后的重新初始化 * 9.封装后多个障碍物的显示 * 10.实现下蹲 * 11.实现悬挂障碍物 * * */ #include<iostream> #include<graphics.h> #include<conio.h> #include"tools.h" #include<vector> using namespace std; #define SCREEN_LONG 1012 #define SCREEN_WIDTH 396 #define OBSTACLE_COUNT 10 #define WIN_SCORE 10 IMAGE images[3]; int bgX[3]; int bgSpeed[3] = { 1,3,19 }; IMAGE heroImg[12]; int heroIndex; int heroX; int heroY; bool herojump; //表示玩家正在跳跃 bool heroDown; //玩家下蹲 int jumpMaxHeight; int heroJumpOff; int updata; //表示是否需要马上刷新画面 int heroBlood; int score; typedef enum { TORTOISE, LION, HOOK1, HOOK2, HOOK3, HOOK4, OBSTACLE_TYPE_COUNT }obstacle_type; //int data[3][5] vector<vector<IMAGE>> obstacleImgs; //特殊的二维数组 typedef struct obstacle { int type; //障碍物类型 int imgIndex; //当前显示的图片的序号 int x, y; //障碍物的坐标 int speed; int power; //杀伤力 bool exist; //障碍物是否存在 bool hited; //表示是否已经发生碰撞 bool passed; //表示是否已经被通过 }obstacle_t; obstacle_t obstacles[OBSTACLE_COUNT]; IMAGE imgDOWN[2]; IMAGE imgSZ[10]; void init() { initgraph(SCREEN_LONG, SCREEN_WIDTH); char name[64]; for (int i = 0; i < 3; i++) { sprintf_s(name, "
像暗黑3设计中,每回打完秘境以后,只有几件装备有用,每次花个几秒钟就可以完成清包,但是也被玩家吐槽装备深度不行,做不到像暗黑2一样每一种颜色的装备都是有潜在有用价值的
但是暗黑2的装备躺在地上就可以知道它本身有没有价值
但是在暗黑4设计中,每一件黄以上的装备都有存在价值,导致清包时间过长,每回看完一背包装备就很难受,严重影响了游戏爽度
不吐槽不为快,建议增加词条过滤功能
现在 Java 面试都只是背答案吗? 不背就通过不了面试,但是现在面试都问原理、问场景!Java 面试题就像我们高考时的文言文,包括古诗词,不背是不可能答出来的!当然了,除了背,还得理解,否则意义不大,对面试过后的工作帮助也不大!
我在五年之前参加过多场面试,应聘的岗位均为 Java 工程师,在不断地面试过程中,分类总结了面试中的一些知识点,主要包括以下几部分
Java 基础知识点
Java 常见集合
JVM 内容管理
高并发编程
spring 全家桶系列
数据库相关
网络协议相关
算法相关
项目相关
......
很多时候,面试官问的问题会和自己准备的“题库”中的问题不太一样,即使做了复盘,下次面试还是不知道该从何处下手。
为此我专门整理了一份《2023最新的 Java 面试宝典》享给大家,内容涵盖:Java 基础知识点、JVM、高并发编程、spring、算法、微服务、分布式、数据库、大厂面经、技术脑图等等...接近 2000 多页 质量非常高!不仅有大厂面试真题还有各大技术栈讲解,不管最近要不要去面试,建议大家都保存一份!
内容如下
第一份面试笔记【1000 道专题 Java 面试题手册】 JavaOOP 面试题
Java 集合/泛型面试题
Java 异常面试题
Java 中的 IO 与 NIO 面试题
Java 反射
Java 系列化/注解
Java 多线程
JVM
MySQL
redis
Memcached
MongoDB
Spring
Spring Boot
Spring Cloud
RabbitMQ
Dubbo
MyBatis
ZooKeeper
数据结构与算法
Elasticsearch
macOS
1. rm -rf node_modules && rm -rf $HOME/.pnpm-store 删掉原来的modules 和pnpm-store
2. sudo pnpm i OK了
开篇 网上有很多篇粒子系统源码解析,但是只是简单的接口罗列,没有从最原理出发去讲清楚粒子系统的来龙去脉,我将从粒子系统的本质去讲清楚它的设计理念,当理解了它的理念以后,很多粒子遇到的问题就会迎刃解决了,这篇文章主讲粒子的实现和一些框架级的优化方式,其实有很多优化细节就不赘述
粒子系统的设计思想 在早期游戏发展的时候,有一些粒子效果是实现一些鼠标特效的,比如《刀剑封魔录》中滑动鼠标后,鼠标本身就会作为一个粒子发射器,在鼠标拖动后,会产生很多粒子并随着时间消亡,这就是最早的粒子系统模型
在早期的桌面系统中实现的粒子全是用cpu在屏幕上渲染的,如果需要世界中的3D粒子,则会将世界坐标转换为屏幕坐标,在屏幕指定位置渲染个粒子,而且这个粒子是每一帧去更新的
我给一个imgui类型渲染系统的粒子伪代码方便大家去理解,每一帧都去更新所有粒子的信息,当然现代游戏引擎粒子实现也类似于此
//定义粒子结构 struct particle { float x; float y; image img; } //定义粒子集合 vector<particle> particles //设置粒子位置 void setparticlepositon(particle &p) { p.x++; p.y++; } tick::update() //每一帧更行所有需要渲染的信息 { for(auto i : particles) { setparticlepositon(i);//循环更新粒子位置 draw(i);//循环更新粒子绘制 } } 更复杂的话就是定义每个粒子的周期,并定义粒子发射器,另外可以在setparticlepositon中设置更复杂的更新条件
class ParticleEmitter{ protected: void Tick() { Spawn(); //生成阶段:创建新粒子 UpdateAndRecycle(); //更新阶段:更新每个粒子的状态数据并回收已死亡的粒子 Render(); //渲染阶段:使用粒子渲染器将粒子效果渲染出来 } private: vector<Particle> Particles; }; 万变不离其宗,都是源于这个思想
既然有大量相同的粒子,那么结合现代游戏引擎的特性,可以用到实例化(Instancing),将相同的mesh和材质用一套,大大减少了数据量,另外也可以用GPU粒子优化
使用几何着色器优化 Nvidia在2006年的GeForce 8系列中出了DirectX 10.0,并推出了几何着色器
简单说,就是几何着色器可以把单个顶点扩充成多个顶点,如果粒子的mesh都一样的话,只需要从顶点着色器中传入的单个顶点和扩展规则,就可以生成想渲染的粒子mesh,而并不需要每回传入大量的顶点了
使用之前:
可见每个粒子需要传入五个位置然后生成五角星 使用之后:
想渲染一个五角星只要传入一个顶点,就可以用几何着色器扩充为五角星,大大减少了draw所占的带宽
文章目录 原因分析解决方法1. 在自己的过滤器中再次设置白名单 原因分析 例如:
@Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/css/**"); web.ignoring().antMatchers("/js/**"); web.ignoring().antMatchers("/fonts/**"); } 虽然在WebSecurity.ignoring().antMatchers()中配置了自己要放行的地址,但是我定义了自定义的过滤器。然而自定义过滤器交给了spring IOC管理,所以你在spring Security的config无论怎么配都会走到自己的过滤器。
@Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() // .requestMatchers()//用于规定哪些路径我需要拦截,精确指定请求匹配规则,如特定URL路径、请求方法、请求参数等。 // .antMatchers("/api/**") // 仅匹配 /api/** 路径的请求 // .and() .authorizeRequests()//基于请求匹配规则来定义访问控制策略。该方法允许您为特定的请求路径或请求模式指定访问要求,如需要特定角色或权限才能访问。 .antMatchers(HttpMethod.DELETE, "/tasks/**").hasRole("ADMIN") // 测试用资源,需要验证了的用户才能访问 .antMatchers("/tasks/**").authenticated() // 其他都放行了 .anyRequest().permitAll() .and() .addFilter(new JWTAuthenticationFilter(authenticationManager())) .addFilter(new JWTAuthorizationFilter(authenticationManager())) // 不需要session .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .exceptionHandling().authenticationEntryPoint(new JWTAuthenticationEntryPoint()) .accessDeniedHandler(new JWTAccessDeniedHandler()); //添加无权限时的处理 } 解决方法 1. 在自己的过滤器中再次设置白名单 请注意如若只在自己的过滤器中设置白名单还不行,因为请求还会走SpringSecurity的过滤器链,必须两边都配置。
如果只想配置一边,可以在自己过滤器放行请求时,直接给本次请求设置一个默认的认证身份
SecurityContextHolder.getContext() .
文章目录 概述安装使用componentsVuexEventsRoutingPerformanceSettings 来源 概述 Vue Devtools 是 Vue 官方发布的调试浏览器插件,可以安装在 Chrome 和 Firefox 等浏览器上,直接内嵌在开发者工具中,使用体验流畅。Vue Devtools 由 Vue.js 核心团队成员 Guillaume Chau 和 Evan You 开发。
安装 (1)在github上下载devtools源码,地址:https://github.com/vuejs/vue-devtools
(2)下载后进入vue-devtools工程,执行npm install,然后npm run build。
(3)进入该文件下的node_modules 文件,找到 vue-devtools 文件,将vender 文件下的 manifest.json ,修改persistent 为 true。
(4)打开浏览器右上角的设置–>更多工具–>扩展程序,打开开发者模式
(5)然后将刚刚编译后的shells下的chrome文件夹拖拽到浏览器中。
使用 只有当Vue.config.devtools === true时才可使用devtools。
components components面板内可以看到我们定义的一系列组件,选中相应的组件后,右侧面板可以看到组件内的data、props、computed、attrs属性。
同时,data属性是可以编辑的,编辑后页面也会实时改变
选中Select后可以实时的选中页面中的组件,快速定位到调试面板对应的组件
鼠标右键 –> Inspect Vue component,也可以快速定位组件。 可以根据组件名字去筛选组件
还可以筛选数据
点击Inspect Dom可以直接定位到Elements面板内的DOM元素
每个组件实例都有一个变量,当前选中的组件是 v m 0 ,其余组件从上到下升序赋值 ( vm0,其余组件从上到下升序赋值( vm0,其余组件从上到下升序赋值(vm1、 v m 2 、 vm2、 vm2、vm3…),控制台直接打印$vm0可以直接看到这个实例。
environment顾名思义就是环境,对于项目来说,无非就是:
开发环境:development生产环境:production 某些逻辑,配置等在两个不同的环境中要呈现出不同的状态,所以environment是一个必要的事情。
Vue3中配置environment: 主要分为两个步骤:
创建文件配置文件 第一步 - 创建文件:
在项目根目录下创建environemnt文件夹在environment文件夹下创建.env.development 和 .env.production 文件将项目创建时就存在的.env.d.ts 类型文件也拖到environment文件夹里 此时的文件结构是这样的:
|--environment |----.env.development |----.env.production |----.env.d.ts 第二步 - 配置文件:
在tsconfig.app.json中添加类型路径,确保类型可以正确读取。 { "include": ["environment/env.d.ts", ...], } 在vite.config.ts中添加envDir配置 export default defineConfig({ ... envDir: 'environment' }) 第二步中配置的路径都是我们自己指定的,由此可知第一步中的文件组合自己可以自由组合,只要在第二步中配置完善即可。
Vue3中使用environment: 默认环境配置中的字段名称需要以VITE_开头,所以如果我们有个test字段需要配置,那么应该是这样的:
.env.development
VITE_TEST = false .env.production
VITE_TEST = true .env.d.ts
/// <reference types="vite/client" /> interface ImportMetaEnv { // 这里配置字段的类型 readonly VITE_TEST : boolean; } interface ImportMeta { readonly env: ImportMetaEnv } 在组件中使用时:
解决npm install 报错 “npm err code 1“
在VSCode执行“npm install”下载相关依赖时,出现"npm err code 1"的问题:
原因分析:
可能是node版本过高,这里采取使用nvm降低node的版本的方法。
解决方案:
1. 查看nodejs的版本
node -v
1
2. 使用nvm管理nodejs的版本
“nvm:nodejs version management”,nvm的安装这里就不过多赘述了。
nvm v
1
3. 相关命令
① 查看当前已安装的nodejs所有版本:nvm ls
② 查看当前所有能够安装的nodejs版本:nvm list available
③ 安装指定版本的nodejs:nvm install 12.17.0
④ 使用指定版本的nodejs:nvm use12.17.0
此处可能会出现如下的错误:
这时候我们使用管理员运行终端,即可正常切换nodejs版本!
⑤ 卸载指定版本的nodejs:nvm uninstall 12.17.0
总结:
到此为止,如果是因为nodejs版本太高而导致问题,那么就应该顺利的解决问题了。当然,如果还无法解决问题,请另辟蹊径。此方法,博主亲测有效!!!
目录
动态规划
JS构建二维数组注意
题目
连续子数组的最大和
原题链接
解析
核心思想
答案
丑数
原题链接
解析
核心思想
答案
n个骰子的点数
原题链接
解析
核心思想
答案
动态规划 通常用于优化递归或求最大、最小值等问题。一般把结果存在一个数组中.
首先确定初始值res[0]=f(0),然后找到上下层res[i]和res[i+1]的关系,通过for循环递归解出arr[n]的值,找上下层关系的时候可以去列举res[0],res[1],res[2]...列举初始的前几位,找到对应的关系。
需要注意
上下层的关系不一定是相差1,例如背包问题,相差arr[j](目标数组中的值);最大、最小值等问题可能需要涉及存储一些临时值用来跟res[i]判断大小后取。 JS构建二维数组注意 JavaScript构建2维数组的时候需要谨慎使用fill和map函数。正确的构建5*5全为0的数组使用
new Array(5).fill(0).map(v=>new Array(5).fill(0))。
错误的构建方式
1.使用new Array(5).map(v=>new Array(5).fill(0))相当于new Array(5),因为map不会对值为empty的数值返回内容。
2.new Array(5).fill(new Array(5).fill(0)),此时的arr[0]和arr[1~4]都是指向相同的引用,也就是说改变数组中一个值,其余4个值都会变为相同的,即fill填充的如果不是基础值,填充的会是相同的引用。
题目 连续子数组的最大和 输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。
输入:[1,-2,3,10,-4,7,2,-5]
返回值:18
经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18
输入:[2]
返回值:2
输入:[-10]
返回值:-10
原题链接 连续子数组的最大和_牛客题霸_牛客网
解析 这里需要注意要有一个变量存储,之前一个最大连续的子数组一直加上到i位元素的和。例如输入[1,-2,3,10,-4,7,2,-5]时,当计算到-4时,计算是否加上7时,该变量应该存储3+10+-4,这时用3+10+-4+7和3+10和7这3位对比选取最大。
核心思想 首先找到初始值res[0]=arr[0],然后找到上下层级的关系。这里需要分析以下例如下面3个数组,[-1,100],[-10,100,40,80,-20,200]、[-1,-10],我们什么时候需要把下一个算进去,什么时候需要重新开始计算。
结论:res[i+1]=Math.max(res[i],tmp+arr[i+1],arr[i+1],) tmp为记录之前的一个最大连续子数组一直加上到目前i位元素的和。
答案 function FindGreatestSumOfSubArray(array) { let temp = array[0] let res = new Array(array.length).fill(0) res[0] = array[0] for (let i = 1; i < array.
目录
一、zookeeper
1.Zookeeper 定义
2.Zookeeper 工作机制
3.Zookeeper 特点
4.Zookeeper 数据结构
5.Zookeeper 应用场景
(1)统一命名服务
(2)统一配置管理
(3)统一集群管理
(4)服务器动态上下线
6.Zookeeper 选举机制
(1)第一次启动选举机制
(2)非第一次启动选举机制
7.部署zookeeper群集
二、消息队列概述
1.为什么需要消息队列(MQ)
2.使用消息队列的好处
(1)解耦
(2)可恢复性
(3)缓冲
(4)灵活性和峰值处理能力
(5)异步通信
3.消息队列的两种模式
(1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
(2)发布/订阅模式(一对多,又叫观察者模式,消费者消费数据之后不会清除消息)
三、kafka概述
1.Kafka 定义
2.Kafka 简介
3.Kafka 的特性
(1)高吞吐量、低延迟
(2)可扩展性
(3)持久性、可靠性
(4)容错性
(5)高并发
4.Kafka 系统架构
(1)Broker
(2)Topic
(3)Partition
(4)Replica
(5)Leader
(6)Follower (7)Producer (8)Consumer
(9)Consumer Group(CG)
(10)offset 偏移量
(11)Zookeeper
5.kafka的部署
6.kafka命令的使用
(1)创建topic
(2) 列出所有topic
(3)查看topic信息
(4) 发布消息
(5)消费消息 (6)修改指定topic分区数
【最近公共祖先】 LCA 一、简单介绍 (Lowest Common Ancestors)二、代码实现离线算法(离线)①.插入函数②.并查集查找函数③.trajan 算法Code算法小总结 倍增法(在线)I.插入函数II.dfs 函数III. LCA查找函数Code 2算法小总结 总结用途:题库 后记 一、简单介绍 (Lowest Common Ancestors) 在一棵二叉搜索树中,任意两个结点的最近公共祖先,是指以这两个结点为后代的深度最大的那个结点。需要通过比较两个结点的值,来判断它们在二叉搜索树中的位置关系。如果两个结点的值都小于当前结点的值,那么它们一定在当前结点的左子树中;如果两个结点的值都大于当前结点的值,那么它们一定在当前结点的右子树中;如果一个结点的值小于当前结点的值,另一个结点的值大于当前结点的值,那么当前结点就是它们的最近公共祖先。如果两个结点中有一个等于当前结点,那么当前结点也是它们的最近公共祖先。
对于有根树 T T T 的两个结点 u 、 v u 、v u、v ,最近公共祖先 LCA (T,u,v) 表示一个结点 x x x,满足 x x x 是 u u u 和 v v v 的祖先且 x x x 的深度尽可能大。在这里,一个节点也可以是它自己的祖先。
蒟蒻第一次画树,希望谅解
转载自 百度 最近公共祖先
二、代码实现 离线算法(离线) ①.插入函数 用邻接表存读入的一棵树,代码实现较好理解,解决代码:
struct Edge { int v,n; }edge[N<<1]; //创建邻接表 int head[N],idx; //邻接表存储树 void connec(int x,int y) { edge[++idx].
简要 微信小程序中有时需要进行全局状态管理,这个时候就需要用到Mobx.下面我们来看一下在小程序中是如何使用Mobx的
安装 pnpm i mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1 或 npm i mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1 或 yarn add mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1 配置 根目录下新建store文件夹,新建store.js文件
import { observable, action } from 'mobx-miniprogram' export const store = observable({ //数据字段 numA: 1, numB: 2, //计算属性 get sum() { return this.numA + this.numB }, //actions方法 updateNumA: action(function (step) { this.numA += step }), updateNumB: action(function (step) { this.numB += step; }) }) 页面中如何使用 // pages/notice/notice.js import { createStoreBindings } from 'mobx-miniprogram-bindings' import { store } from '.
图形渲染管线和着色器Rendering Pipeline And Shader 前言:什么是管线?
管线我们可以理解为流水线,流水线大家都懂,就是工厂里面生产东西的一整套流程。例如饮料厂要生产饮料,需要洗瓶子,倒饮料,加盖,包装等等,这一整套过程就是流水线。
那我们要把一个三维场景渲染成二维图像,同样需要一个先干嘛再干嘛最后干嘛的一个过程,这个过程就成为管线。
图形渲染管线(Graphics Rendering Pipeline) 我们知道了要把一个三维场景渲染成一个二维的图像大致分为以下几个步骤:
1.MVP变换和齐次裁剪,透视除法,视口变换,把三维场景变得屏幕空间大小一样(但此时还是一个3D的)2.光栅化,把物体离散成一个个像素,在屏幕上显示出来。3.深度缓存,根据每个像素做深度缓存。4.着色,根据着色频率的不同,不同的着色会在不同的时间点进行。 对于这一套流程,我们就可以称之为实时渲染管线,大致整理一下可以得到下面的流程图:
Vertex Stream 我们的MVP变换,视口变换实则是对物体表面也就是Mesh中的每个三角形的顶点进行变换,这部操作我们可以称之为Vertex Processing,操作的内容都是顶点,即vertex stream。
同时我们之前所说的高洛德着色就是在这里进行操作的,因为高洛德着色处理的就是顶点。
Triangle Stream 顶点变换好之后,我们自然就可以听过这些顶点组成三角形,指定三个顶点即可连成一个三角形,即可得到所有三角形面,即Triangle Stream,这步操作称之为Triangle Processing;
Fragment Stream 然后我们就要把这些三角形进行光栅化,离散成一个个像素。在OpenGL当中引入了Fragment的概念,我们可以理解为一个采样点所覆盖的区域即为一个Fragment,若我们对一个像素进行一次采样,那么Fragment就是一个像素,但是如果我们做MSAA操作,例如在一个像素选取四个点进行采样,那么这个像素就有四个Fragment。
每个Fragment 都会记录颜色,深度,透明度等信息,所以说MSAA的显存和带宽开销会加倍,但是渲染计算时还是只运行一次fragment shader,这就是MSAA与SSAA的区别,详情可见之前的文章。
本文我们就简单的吧一个Fragment 当做是一个像素。因此在光栅化操作(Rasterization)中,我们得到的即是Fragment的集合(Fragment Stream)
然后我们的深度缓存,以及冯氏着色都是针对每个Fragment进行处理的,这些相关操作我们称之为Fragment Processing。在这里通过重心坐标我们就可以知道每个Fragment对应的颜色,从而得到每个像素对应的颜色。
(PS:在片元处理阶段,除了使用Blinn-Phong之外,我们还可以去做texture mapping,利用texture的信息来代替blinn-phong模型漫反射系数来当做颜色)
这样,我们的一个管线就走完了,即可得到我们最终的结果,也就是一副二维的图像。
当然了,上面的介绍仅仅是一个大致的说明,实际上的渲染管线要复杂的更多,并且在不同的图形API里,整个过程也是有所不同的,甚至在相同的图形API里,随着版本的迭代,渲染管线也在不断的更新。
Shader 上面所说的管线,都是在我们GPU里制定好的,但是在现代的GPU里,允许Vertex Processing和Fragment Processing这两部分是可编程的。也就是说我们可以通过自己写代码来控制它们是怎么着色的,而这部分代码就是Shader。
Shader本身是一个能在GPU上执行的模块,作用在Vertex Processing的我们称之为Vertex Shader,作用在Fragment Processing的我们称之为Fragment Shader。
从基本意义上来说,Shader只是一种把输入转化为输出的程序,也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。
Vertex Shader的输入即是顶点的属性,而它的输出往往会作为Fragment Shader的输入,Fragment Shader输出则是一个颜色值,代表每个像素的最终颜色。
我们可以使用我们常说的那些图形API(例如OpenGL和DirectX)来编写Shader,目前主要有3种语言:
1.基于OpenGL的OpenGL Shading Language,简称GLSL。
2.基于DirectX的High Level Shading Language,简称HLSL。
3.NVIDIA公司的C for Graphic,简称Cg语言。
OpenGL和DirectX属于敌对的关系,我们可以把GLSL转换为HLSL。而Cg语言(C for Graphic)是为GPU编程设计的高级着色语言,可以被OpenGL和Direct3D广泛支持的图形处理器编程语言。因此Cg语言和GLSL、HLSL并不是同一层次的语言,而是它们的上层,即Cg程序是运行在OpenGL和DirectX标准顶点和像素着色的基础上的。Cg由NVIDIA公司和微软公司相互协作在标准硬件光照语言的语法和语义上达成了一致开发,所以HLSL和Cg其实是同一种语言。虽然它目前还在被使用,但是已停止了更新(https://developer.nvidia.com/cg-toolkit)。
接下来我们来简单的介绍下OpenGL和DirectX它们的渲染管线以及shader。
OpenGL OpenGL(Open Graphics Library)是一个定义了跨编程语言、跨平台的编程接口规格的专业图形程序接口。它用于二维/三维图像,是一个功能强大,调用方便的底层图形库,是行业领域中最为广泛接纳的2D/3D图形API。OpenGL是一个与硬件无关的软件接口,可以在不同的平台如Windows、Linux、MacOS之间进行移植。因此,支持OpenGL的软件具有很好的移植性,可以获得非常广泛的应用。
1.简述
若向量记号为X,方程组就可以写成F(X)=0的形式。
我们知道,对于一元函数的牛顿迭代法求根公式
类似的,对于多元函数求根公式
其中X是向量,是非线性方程组对应的雅可比矩阵。
具体求解的时候,我们可以先通过绘图命令绘制图形,看交点。然后将交点附近的值带入迭代
矩阵。最后求出小于误差的收链解。
2.代码
主程序:
function newton%牛顿迭代法解非线性方程组
syms a x;
beta=0.15;
F=[1-beta+sqrt((1-beta)^2+4*a)-2*x;
beta+a+2*x-(beta+x)^3];
eps=10e-6;%精度
num=1;%记步数
tol=1;%给定误差初始值
x0=[1;1];%参数赋初始值
v=[a,x];
while tol>eps
Fx=subs(F,v,transpose(x0));
dF=jacobian(F,v);
c=subs(dF,v,transpose(x0));
x=x0-inv(c)*Fx;
tol=norm(x-x0);
x0=x;
num=num+1;
if (num>10^8)
disp('迭代次数大于最大值,可能不收敛')
return
end
end
%Output
fprintf('解出 a = %g.\n',x0(1))
fprintf('解出 x = %g.\n',x0(2))
fprintf('迭代次数 n = %g次.\n',num)
子程序:
function [y,n]=newton_fun(F,x0)
if nargin==2
eps=1.0e-6;
end
num = 0;
tol = 1;
v=findsym(F);
while tol>eps
Fx = subs(F,v,transpose(x0));
本文重点梳理从因果树到因果森林、再到广义随机森林,正交随机森林,其中不乏涉及相关论文的精读推导.
1. 因果树 定义:处理效应的均方误差 公式: 核心点:"诚实"估计,honest approach定义:①原来的树方法,使用训练样本训练出模型以后,我们用训练样本上各个子集的样本均值做为估计值,然后使用该估计值在测试集(test set)上计算MSE来判断模型的好坏;②修改后的计算方法,将训练样本切割成两部分,一部分仍是训练样本(train set),另一部分是估计样本(estimate set),即在训练样本上训练模型,模型训练好以后放到估计样本上计算估计值,最后使用该估计值在测试集上计算MSE来判断模型的好坏。文章亮点: 改为诚实方法: 修改了MSE的表达式, 标准的Rubin因果框架假设样本个体间不存在相关性(SUTVA),保住了此假设.修改了均方误差的计算方法。 变成了 式中的p代表的是处理组在子集中所占的比例, 1−p是对照组所占的比例了. 加快收敛速度.原因二是无法观测到反事实结果,减掉 τ² 能够让我们回避无法直接观测到τ这个问题. 如右图所示. 诚实预估下的分裂准则: 优点:
诚实树和子采样保证了估计的结果具有渐近正态性与一致性
相对于uplift树的优势在于采用了诚实的方法. 有效避免过拟合. 2. 因果森林 提出一种非参的方法,相比传统的非参可以破除“维度诅咒”的问题。其次,是在决策树、随机森林的基础上提出的因果森林,可以有效的提高样本的泛化能力“诚实树”的保证,处理效应的结果估计是无偏的.除了无偏,作者最后证明因果森林得到的处理效应是渐近正态的。 3. 广义随机森林 泛化性.假设 θ(x) 是我们感兴趣的参数, v(x) 是我们不感兴趣的参数(nuisance parameter); O为观测结果;那么广义随机森林解决的是以下局部矩方程求得我们感兴趣的 θ(x) ,使得
跟因果森林一样:GRF的分裂标准是treatment效应估计的MSE最小,且采用诚实的方法.结果预测:广义随机森林先对样本X与各棵子树计算相似度 ,再加权求得估计值. 树分裂准则:最小化感兴趣的参数的误差等价于最大化两个子节点的异质性. 4. 梯度提升树算法
4. 正交随机森林 但GRF需要假定unconfoundedness,对Y和T进行局部中心化后,对中心化后的结果进行估计(本质上其实是DML+GRF),可以在存在confounding的情况下识别treatment异质性,去除偏差。 5. 机器学习能为因果做些什么? 总结一句话,就是帮助解决因果推断中的“异质性”问题.
在了解所有的异质性处理效应之后,我们可以根据收益/成本最大化的目的,针对不同的群体实施treatment。通过数据驱动的方式识别异质性因果的差异,而不需要预先分析计划。传统的计量经济学在分析异质性的时候,往往需要多次尝试,以了解异质性处理效应的结果。尤其是在连续变量切分的时候,我们往往无从下手。比如年龄段的cohort分析如何切分?房屋的大小,多大是大,多小是小?其中阈值难以知道。而机器学习,采用数据驱动的方式,省去了预先计划分析异质性。 6. QA 1.什么是维数诅咒?
增加维度而不增加训练样本的数量导致分类器性能的降低。不断增加维度,训练数据量需要以指数级增长,以保持相同的训练样本覆盖范围并避免过度拟合。
2.广义随机森林中的得分函数跟工具变量有何关系?
7. 因果的文章总结: 《Recursive Partitioning for Heterogeneous Causal Effects∗》Athey and Imbens (2016)
《Estimation and Inference of Heterogeneous Treatment Effects using Random Forests∗》 Wager and Athey (2018)
一、基本用法 编码语言分类:
1、解释型:PHP、JavaScript、Python、VBScript……:几乎都是弱类型语言,执行速度较慢,通常用于各类快速开发场景,并非专业程序员专属。
2、编译型:C、C++、C#、Java、Go、Rust……..:几乎者是强类型评语,一旦完成编译,执行速度很快,通常用于专业程序设计场景。
1、代码块 PHP是运行于Web服务器中,主要用于网页的处理。
<?php // 必须要使用<?php ?> 进行代码的包裹 ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <?php // 可以在PHP的源文件中,直接写HTML代码 ?> </body> </html> 2、注释 <?php // 必须要使用<?php >进行代码的包裹,只能注释一行 /* 可以用于注释一行或者一个段落 */ ?> 3、内容输出 <?php // 必须要使用<?php >进行代码的包裹,只能注释一行 /* 可以用于注释一行或者一个段落 */ /** * 在PHP中,可以通过两个函数往页面中输出注释: * (1)echo:支持用逗号分隔多个字符进行拼接输出 * (2)print:不支持用逗号分隔多个字符进行拼接输出 * 注意:在PHP中,换行符\n无法被浏览器解析,<br>才能被浏览器解析 */ echo "这是一个牛逼的网页. <br/>"; print "这又是一个更牛逼的网页.<br>"; echo "1111111111", "
在Linux中安装lrzsz(yum命令使用) 操作步骤:
1、搜索lrzsz安装包,命令为yum list lrzsz
2、使用yum命令在线安装,命令为yum install lrzsz.x86_64
注意事项:
Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。
使用命令:
命令作用rz文件上传到Linux服务器
本文由社区用户 Albert 贡献,首发于 NebulaGraph 论坛,旨在提供多一种的部署方式使用 NebulaGraph。
在本文,我将会详细地记录下我用 K8s 部署分布式图数据库 NebulaGraph 的过程。下面是本次实践的内容规划:
一到十章节为 K8s 集群搭建过程;十一到十五章节为参考 NebulaGraph 官方文档安装部署 NebulaGraph的过程; 本文所有实践是在本地虚拟机 3 台 CentOS 实例上完成
一、集群环境准备 本文所有集群都遵循以下的部署,仅供参考。
首先,集群规划 方面:
#把 xxx 替换为对应的主机名 192.168.222.141 node1 192.168.222.142 node2 192.168.222.143 node3 配置静态 IP
# vi /etc/sysconfig/network-scripts/ifcfg-enss3 IPADDR="192.168.222.XXX" # XXX 是自己规划的 IP PREFIX="24" # 掩码 4 个 255 GATEWAY="192.168.222.XXX" # 网关需要自己指定 DNS1="114.114.114.114" # DNS 也可以设置为其他,能用即可 配置主机名
hostnamectl set-hostname xxx 192.168.222.141 node1 192.168.222.142 node2 192.168.222.143 node3 配置 ip_forward 及过滤机制
介绍QQ音乐团队在增量编译组件研发上的探索与实践。
原文地址:https://juejin.cn/post/6891957803813584909
文章目录 1. 序言2. 问题分析3. 优化思路4. 增量编译的诞生5. 核心原理5.1 代码编译(1)获取改动文件并进行编译(2)进行代码依赖分析 5.2 资源编译(1)资源增量(2)资源ID固定 5.3 动态加载(1)代码注入(2)资源注入 6. 结语 1. 序言 工程编译,是Android应用开发工作中的重要一环。而随着工程代码量膨胀,编译耗时也越来越长,拖慢了开发效率。
这个问题在中大型团队中并不少见。以QQ音乐为例,Android工程代码量达到120万行以上,每修改一行代码,都要等待4分钟以上才能在手机上看到改动效果。
为了应对这个问题,我们自研推出了一款增量编译组件。经过一年时间的不断优化,组件已经可以支撑团队内的日常开发工作,有效提升了本地开发场景下的编译效率。
本文将会介绍QQ音乐团队在增量编译组件研发上的探索与实践历程。
2. 问题分析 本地开发过程中,我们会不断重复 修改代码-编译工程-安装APK-运行验证 这一过程。
因此,可以从编译与安装两个纬度来分析编译慢的原因。
首先是编译阶段。 其主要流程是,先收集工程中的所有资源文件进行编译,得到资源包以及资源索引类。随后资源索引类会跟随工程的所有代码文件,一起被编译为字节码文件,字节码文件还需要被进一步编译为Dex文件,这样才能被Android虚拟机所识别。
待资源包和Dex文件都准备好后,会被打包压缩到一起,执行签名、对齐等流程,最终完成编译,得到一个APK安装包。
在这个过程中,不论是资源编译还是代码编译,耗时都是与待编译的文件数量成正比的。我们在开发过程中,一般只会改动极少数的代码文件,然后触发编译。理想的情况是,编译工具应当只编译这些被改动的文件。但是由于代码的依赖关系,这在原生工具下很难实现。
Android Gradle Plugin自3.0版本开始,开始废弃compile关键字,并引入implementation关键字来声明依赖,是希望可以从module的粒度,去加快大型项目的编译速度。不过对于一些并未拆分多module的单一工程项目来说,使用效果并不理想。
再来看安装阶段。 安装包首先需要通过ADB工具传输到手机上,然后系统对其进行签名校验。校验成功后,还需要进行一系列文件解压、拷贝的操作。例如拷贝Dex文件、so文件等。
此外,如果是在系统版本为5.0、6.0的手机上,由于系统采用了AOT机制,安装过程中会进行预编译,将Dex中的字节码变成机器码,以提高应用运行时的效率,这就导致了安装耗时进一步被拉长。
可以看到,安装包体积、手机系统版本,都会影响到安装阶段的耗时。
3. 优化思路 根据上述分析,主要有三类解决方案。
构建工具 欲善其事,必先利其器,首先可以尝试对工程的构建工具链进行优化。
常见的方式是升级Android Gradle Plugin、Gradle等工具的版本、调整构建参数等。不过实践后发现,他们带来的优化效果并不理想。
当然,除了Gradle构建工具外,也可以考虑使用Facebook的Buck作为构建工具。根据官方介绍, 它利用多模块、多任务并行编译的思想,可以大幅度缩短编译耗时。
不过对于大型项目来说,要迁移构建工具,成本是极高的。目前使用的众多插件、周边开发工具链,都是基于Gradle体系的,迁移的话就会失去这些功能的支持;此外,如果工程还涉及到其他团队、项目的协作,构建方案也是无法随意更换的。
工程代码优化 另外一种思路是,对工程代码进行优化,尽可能减少参与编译的代码数量。
这里可以做的事情很多,比如梳理业务删除冗余代码、进行多工程拆分、实施组件化(模块化)改造等;但是,由于代码耦合深、开发节奏紧等客观因素的存在,代码优化的难度通常比较大,各个方案的实施周期会比较长。所以并不能在短期内,快速解决编译缓慢的问题。
增量编译工具 那么,能不能提供一个编译工具:在本地开发期间,每次仅编译被改动过的少量代码,而且最好可以跳过APK的安装过程,仅推送与加载新改动的代码。这样就可以从编译与安装两个纬度,去大幅缩减编译耗时。
这其实就是增量编译工具的核心思想。对于工具的接入方来说,不需要大刀阔斧地升级工具链或者进行工程改造,即可在较低的成本下,快速提高本地开发效率。
截止目前,业界主要有两款方案可以参考。
Instrant Run Instant Run是Google推出的第一代增量编译方案。不过在大型项目中,它带来的提速效果并不明显,甚至在某些场景下会让构建时间变得更长。
首先,在Gradle 4.6以前,如果项目中使用了注解处理器,那么每次代码修改都要进行全量编译。此外,若是修改的类中,包含有公有静态常量,那么也同样会导致本次修改需要进行全量编译。
Instant Run在使用过程中,有时也会遇到一些兼容性问题,但由于它是集成在Android Studio内部的,对于我们来说是一个黑盒,无法自行定位解决问题,只能被动地反馈问题与等待新版本发布。所以综合来看,这个方案并不合适引入。
在最新的Android Studio中,Instant Run已经被废弃,取而代之的,是Apply Changes方案,它是基于JVMTI技术来实现的。不过仅支持 Android 8.
vue + elementUI 实现下拉树形结构选择部门,支持多选,支持检索 <template> <div> <el-select v-model="multiple?choosedValue:choosedValue[0]" element-loading-background="rgba(0,0,0,0.8)" :disabled="disableFlag" @visible-change="visibleChange" filterable clearable collapse-tags :filter-method="filterMethod" @clear="clear" @remove-tag="removeTag" :multiple="multiple" ref="selectRef" v-loading="loading" style="width: 100%"> <el-option :label="option.name" :value="option.id" v-for="option in options" :key="option.id" class="optionClass"/> <template v-slot:empty> <div/> </template> <el-tree :props="treeProps" :load="loadNode" :data="treeData" :show-checkbox="multiple" @check="handleCheck" :expand-on-click-node="false" @node-click="chooseNode" :filter-node-method="filterNodeMethod" class="treeClass" ref="treeRef" :node-key="'id'" :default-checked-keys="choosedValue"/> </el-select> </div> </template> <script> import {getDwxxOfTree} from "@/api/commentTable/api"; export default { name: "chooseUnitTree", props: { disableFlag: { Type: Boolean, required: false, default: false }, value: { Type: Object, required: true }, multiple: { Type: Boolean, required: false, default: false } }, data() { return { treeProps: { label: 'name', value: 'id', children: 'children' }, deptMap: {}, treeData: [], options: [], loading: false, choosedValue: [], choosedOptions: [], } }, computed: {}, watch: { // choosedValue: { // handler(n, o) { // if (this.
1.什么是Maven Maven是一个Java项目管理和构建工具。它提供了一种简单的方式来定义项目的结构、依赖关系和构建过程,并自动下载所需的库文件。Maven使用XML格式的配置文件,通过执行一系列的生命周期阶段来完成项目的构建和部署。它还支持在项目中管理插件和构建脚本,使得开发人员能够更加方便地进行项目的管理和构建。
2.如何下载安装Maven 一.官网下载 Maven – Download Apache Maven
下载好后解压到你喜欢的目录下,建议新建一个Maven目录存放,我测试用的版本稍低一些
但是方法都是一样的
3.配置Maven环境 演示系统 Windows11
一.找到设置>系统>系统信息>高级系统设置>环境变量 二.然后配置Maven的环境 在系统变量下面点击新建 变量名:MAVEN_HOME 变量值:找到电脑上的Maven安装的根目录
三.找到Path点击编辑>新建 %MAVEN_HOME%\bin
然后点击确定...
四.测试Maven是否配置成功 1.启动cmd命令用管理员身份运行cmd
2.在窗口命令输入:mvn -v
出现上述界面,则表示成功安装Maven
4.修改Maven仓库下载镜像及修改仓库位置 Maven下载慢的原因是服务器在国外,要翻墙才能下载,大约速度在0.9K/s的下载速度,所以我们安装好Maven时,要及时的修改Maven下载的镜像地址,最好改为国内的下载镜像,例如阿里云中央仓库,华为云中央仓库。
五.Maven如何修改为本地仓库 在开发Maven项目中我们会下载很多jar包,而且Maven的默认位置在C盘,如果C盘空间不充足并不及时修改的话会很容易的将C盘撑爆,且C盘容易损毁、
所以我们可以在存放Maven的同路径下新建目录作为仓库来进行存放jar包
然后我们要找到Maven的conf文件下的settings.xml文件进去修改本地仓库路径,建议使用Notepad++软件进行修改,好处就是容易找到,比电脑自带的文本文档更容易找到标签
找到<localRepository>标签修改为我们刚才新建的本地仓库路径
六.如何修改Maven下载的镜像地址 在settings.xml文件下找到<mirrors>标签下的<mirror>标签,把他修改为阿里云的远程仓库
阿里云仓库-> 仓库服务 (aliyun.com)
<mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror> 然后Ctrl+s保存退出 我们就修改好了
5.在idea中部署Maven项目 一.第一步我们先设置好idea的全局设置,下次在建Mane项目就不需要重新设置了 二.找到构建、执行、部署>构建工具>Maven 要把后面的重写打上勾才能修改
三.找到构建、执行、部署>构建工具>Gradle 然后我们就设置好了全局,接下来去建Maven项目
四.开始建Maven项目 然后下一步
五.默认会选择Java EE 8 然后直接点击完成即可 六.部署完成 然后我们的idea Maven就创建好了,Tomcat服务器也配置好了,第一次搭建Maven项目会自动下一些jar包 网络不好的情况下会慢一些。
七.Maven生命周期的命令原理使用 Maven是一个Java项目管理工具,它的生命周期命令用于构建、测试和部署项目。Maven的生命周期命令包括clean、validate、compile、test、package、integration-test、verify、install和deploy。
- clean命令用于清理项目,删除生成的目录和文件。
- validate命令用于验证项目是否正确且所有必需的信息都可用。
Api 注意:需要指定服务器响应的数据类型 —> responseType: 'blob'
// 导出/下载 import request from './request' export default { exportData(params) { return request.post('/export', params, { responseType: 'blob' }); }, } 注意:request.js文件里需要判断响应数据中 config.responseType 的类型
import axios from 'axios' import Vue from 'vue' import store from '@/store/index' // 取消请求(用于当没有 token 时,取消当前的请求,直到获取 token) const CancelToken = axios.CancelToken const source = CancelToken.source() // 过滤掉空字符串 function filterEmptyKey(params) { Object.keys(params).forEach(key => { if ( params[key] === null || params[key] === '' || params[key] === 'null' || params[key] === undefined ) { delete params[key] } }) } // 环境的切换 let baseURL = null if (process.
.meta 文件的作用简单来说是建立 Unity 与资源之间的“桥梁”。 在游戏中引用一个游戏资源,Unity 并不是直接按照文件的路径或者名称,而是使用一个独一无二的 GUID 来指向工程里该资源文件。 这个 GUID 就是存储在 Unity 工程为每一个资源和文件生成的 meta 文 件里。除了 GUID , meta 文件还存储了有关资源导入的信息。例如,贴图资源在导入时可以当作标准贴图、法线贴图、GUI 贴图、 cookie 或者光线贴图。这些导入设置都会被存储在 meta 文件里。 GUID 优点:移动、重命名或者修改资源的内容,这个资源仍然可以通过 GUID 来被引用(只要 GUID 不变,资源就能够被引用。 GUID 缺点:必须明确的意识到 Meta 文件是被关联到特定的资源 上的,如果删除了一个 meta 文件, Unity 会认为原始的资源文件已经 被删除,然后为这个“ 新的 ” 资源文件生成一个新的 GUID 。这就是游戏场景中的资源引用中断的最常见原因。 当把新的资源导入 Unity 时,Unity 会自动做下面这件事: 1. 分配唯一 ID 2. 创建 .meta 文件 3. 处理资源 1. 分配唯一 ID : Unity 会维护一个自己资源列表,在将资源导入 Unity 的时候, Unity会先检测这个资源列表,然后为导入的资源分配一个唯一的 ID ,在Unity 中会使用此 ID 来引用资源。 2.
t-SNE(t-Distributed Stochastic Neighbor Embedding)是一种非线性降维算法,用于将高维数据映射到低维空间。它可以在可视化和数据分析任务中帮助发现数据中的模式和结构。以下是t-SNE算法的基本步骤:
计算相似度:首先,根据输入的高维数据,计算数据点之间的相似度或距离。常用的相似度度量方法包括欧氏距离、余弦相似度等。
创建条件概率:基于计算得到的相似度,计算每个数据点与其他数据点之间的条件概率。条件概率表示了数据点之间的相似性,即在低维空间中,两个数据点是如何彼此靠近的可能性。
随机初始化:为每个数据点在低维空间中随机初始化一个坐标。
梯度下降优化:通过梯度下降方法,不断调整数据点在低维空间中的坐标,使得数据点之间的条件概率与高维空间中的相似度尽可能匹配。
优化目标函数:t-SNE算法通过最小化Kullback-Leibler(KL)散度来优化目标函数。KL散度是用来衡量两个概率分布之间的差异,通过不断调整低维空间中的数据点坐标,使得KL散度最小化,从而得到最优的低维表示。
可视化和分析:最后,将优化后的低维表示用于可视化和分析。通过将高维数据映射到二维或三维空间,可以直观地展示数据点之间的关系、聚类结构和异常点。
t-SNE方法在数据可视化、聚类分析、异常检测等领域得到广泛应用。它可以帮助发现数据中的隐藏模式和结构,帮助研究人员和数据科学家更好地理解和解释数据。然而,需要注意的是,t-SNE是一种计算密集型算法,对于大规模数据集需要进行优化或考虑使用其他降维方法。
Java建造者模式:创建复杂对象的灵活构建者 在软件开发中,我们经常遇到需要创建一个复杂对象的情况。如果使用传统的构造函数进行对象创建,可能会导致构造函数参数过多,难以管理和维护。建造者模式(Builder Pattern)通过引入建造者对象来逐步构建复杂对象,使得对象的构建过程更加灵活、可控,同时还能提供更好的代码可读性和维护性。
一、原理 建造者模式的核心思想是将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。具体来说,建造者模式通过将对象的构建过程委派给不同的建造者类,每个建造者类都负责创建对象的一部分,并最终将这些部分组装成完整的对象。
它由四个主要的角色组成:产品类(Product)、抽象建造者类(Builder)、具体建造者类(ConcreteBuilder)和指导者类(Director)
产品类(Product):表示最终构建的对象。该类具有一些属性,可以通过设置相应的setter方法进行赋值,并且定义了一个展示产品的方法。抽象建造者类(Builder):定义了产品构建的抽象方法。包括构建不同部分的方法和获取最终产品的方法,由具体建造者类来实现。具体建造者类(ConcreteBuilder):继承自抽象建造者类,实现了具体的构建过程。包括构建不同部分和获取最终产品的方法。指导者类(Director):负责使用具体的建造者类来构建产品。通过调用具体建造者的方法来完成产品的构造,并最终返回一个完整的产品对象。 产品类
public class Product { private String partA; private String partB; private String partC; public void setPartA(String partA) { this.partA = partA; } public void setPartB(String partB) { this.partB = partB; } public void setPartC(String partC) { this.partC = partC; } public void show() { System.out.println("Product: " + partA + ", " + partB + ", " + partC); } } 抽象建造者类
在软件开发中,经常遇到需要对某个对象进行控制或者监控的场景。而直接修改对象的代码可能使代码变得复杂且难以维护。这时,使用代理模式(Proxy Pattern)可以很好地解决这个问题。
代理模式是一种结构型设计模式,通过引入一个代理对象来替代原始对象,实现对原有对象的控制或扩展。Java中的代理模式常用于实现日志记录、权限控制、事务控制等功能。
原理及实现思路 代理模式的核心思想是通过引入代理对象作为中间层,将客户端的请求转发给真正的对象,从而实现对真实对象的控制。
代理模式包含三个主要角色:
抽象主题(Subject):定义了代理对象和真实对象的共同接口。
真实主题(RealSubject):实现了抽象主题接口,是真正的业务逻辑处理对象。
代理主题(ProxySubject):实现了抽象主题接口,内部持有一个真实主题对象的引用,通过代理对象间接调用真实对象。
实现代理模式的步骤如下:
创建抽象主题接口,定义需要代理的方法。
创建真实主题类,实现抽象主题接口,完成真正的业务逻辑。
创建代理主题类,实现抽象主题接口,持有一个真实主题对象的引用,在代理方法中调用真实主题的方法。
静态代理 静态代理是最简单的一种代理技术,由程序员手动编写代理类来代替真实对象。静态代理在编译期生成代理类,在运行时代理类不会发生变化。
静态代理的优点是简单易懂、易于实现,但缺点也显而易见,每个代理类只能代理一个具体类,当代理类的数量较多时,会导致代码冗余,并且每个代理类只能代理一个固定的类。
示例代码如下:
// 抽象主题接口 interface Subject { void doSomething(); } // 真实主题类 class RealSubject implements Subject { @Override public void doSomething() { System.out.println("RealSubject do something."); } } // 代理主题类 class ProxySubject implements Subject { private Subject realSubject; public ProxySubject(Subject realSubject) { this.realSubject = realSubject; } @Override public void doSomething() { // 对真实主题方法的增强 System.out.println("Before do something.
文章目录 一图总结怎么口述初始化阶段模板编译阶段更新阶段组件销毁 子父组件生命周期顺序注意内存泄漏异步请求放在created还是mounted中 一图总结 这张图是我在官网图的基础上修改的,珍藏了一年多,可以放出来了。
怎么口述 可能会有小伙伴觉得看图不太好闭卷口述出来,这里我就按照自己的理解打个样出来(这里不需要详细描述vdom的更新原理)。
vue的生命周期分为四个大的阶段,分别是组件初始化阶段,模板编译阶段,组件更新阶段和组件销毁阶段。
初始化阶段 首先将vue实例化,data、methods等尚未初始化,此时提供了beforeCreate这个钩子函数供使用。
接着vue初始化完成,data、methods等可以使用了,此时提供了created这个钩子函数供使用。
beforeCreate() { // 这个钩子中的使用目前我还不知道能举什么例子 }, created() { // 这里因为data、methods等可以使用了,所以可以用来提前处理一些变量,调用一些函数 } 模板编译阶段 接着进入模板编译阶段,将模板的字符串进行编译,生成vdom放入内存中,此时提供了beforeMount这个钩子函数供使用。
紧接着把内存中的vdom渲染成真实的dom,挂载到真实的页面上,组件创建完成。此时提供了mounted这个钩子函数供使用。
beforeMount() { // 这个钩子中的使用目前我还不知道能举什么例子 }, mounted() { // 这里组件已经实例化完成,可以做很多事情了 this.$refs['子组件'].getData() // 获取组件实例 this.$nextTick(()=>{ this.$refs['子组件'].getData() // 如果获取不到子组件就用nextTick }) this.getData() // 发送异步请求 this.$on('fn', this.fn) // 订阅事件总线 window.addEventListener('resize', this.fn) // 监听方法 let timer = setInterval(()=>{}, 1000) // 开启定时器 // ...等等 } 更新阶段 在组件运行中,data发生改变,视图未更新前提供了beforeUpdate这个钩子函数供使用。
data改变后,重新进行对应的模板编译,把新的vdom渲染更新到真实的dom上,挂载后提供了updateed这个钩子函数供使用。
组件销毁 组件即将进入销毁的时候,此时提供了beforeDestroy这个钩子函数供使用。
组件完全销毁后,此时提供了destroyed这个钩子函数供使用。
beforeDestroy() { // 进行一些注销操作 this.
目录
1、WDMA特征:
2、 LengthVar特征:
WDMA(Weighted Dynamic Memory Access)和LengthVar(Variable Length)是特征提取的两个常用算法。
1、WDMA特征: WDMA是一种用于计算机体系结构的特征提取算法。它基于内存访问模型,通过统计程序执行期间的内存访问模式,计算出一系列与内存访问相关的特征,如内存读取次数、内存写入次数、内存访问延迟等。这些特征可以用于分析和评估程序的内存访问效率,帮助优化程序的性能和资源利用。
以下是WDMA算法的基本步骤:
数据采集:通过运行程序并监控内存访问操作,收集程序执行期间的内存访问信息。这可以使用硬件性能计数器、跟踪工具或模拟器来实现。特征提取:基于采集到的内存访问信息,计算一系列与内存访问相关的特征。常见的特征包括内存读取次数、内存写入次数、内存访问延迟、内存访问冲突等。特征加权:根据特征的重要性,对提取到的特征进行加权。这可以根据具体应用场景和需求来确定,例如,可以根据内存访问次数的多少对特征进行加权。特征分析和优化:根据提取到的特征,分析程序的内存访问模式和性能瓶颈,找出优化的潜在方向。可以通过改进算法、优化数据结构、调整内存访问策略等手段来提高程序的内存访问效率和性能。 2、 LengthVar特征: LengthVar是一种用于文本分析的特征提取算法。它基于文本中词语的长度变异性,通过计算词语的平均长度、标准差等统计指标,来描述文本的特征。LengthVar特征可以用于文本分类、情感分析等任务,帮助识别文本中的重要信息和特征。
以下是LengthVar算法的基本步骤:
分词:将文本进行分词,将文本拆分为一系列的词语或单词。长度计算:对每个词语或单词计算其长度(通常以字符个数为单位)。统计指标计算:统计词语长度的一些常见统计指标,如平均长度、标准差、最长词语长度、最短词语长度等。特征提取:基于计算出的统计指标,提取一系列与词语长度变异性相关的特征。这些特征可以用于文本分类、情感分析等任务,帮助识别文本中的重要信息和特征。特征分析和应用:根据提取到的特征,进行文本分析和处理。可以通过特征的比较、聚类、分类等方法,进行文本相关的任务,如情感分析、关键词提取、文本分类等。 这两种特征提取算法在不同领域和任务中有广泛的应用。WDMA特征适用于计算机体系结构和程序优化领域,LengthVar特征适用于文本分析和自然语言处理领域。通过提取这些特征,可以帮助分析和理解数据,从而支持后续的目标项目分析和决策。
文章目录 前言一、CMD命令安装1.官网下载MySQL安装包2.配置环境变量3.配置初始化的my.ini文件的文件4.初始化MySQL5.安装MySQL服务 + 启动MySQL 服务6.连接MySQL + 修改密码 结束了,安装完成 前言 本篇文章用来记录本人安装MySQL数据库时用到两种方法 比较推荐第一种 一、CMD命令安装 1.官网下载MySQL安装包 先去官网下载安装包:https://dev.mysql.com/downloads/mysql/ 解压: 2.配置环境变量 首先,打开电脑系统环境变量
然后,添加mysql安装的bin文件目录的路径,如下图所示:
3.配置初始化的my.ini文件的文件 解压后的目录并没有的my.ini文件,没关系可以自行创建在安装根目录下添加的my.ini(新建文本文件,将文件类型改为的.ini),写入基本配置: [mysqld] # 设置3306端口 port=3306 # 设置mysql的安装目录 basedir=D:\DevInstall\mysql-8.0.27-winx64 # 设置mysql数据库的数据的存放目录 datadir=D:\DevInstall\mysql-8.0.27-winx64\MySqlData # 允许最大连接数 max_connections=200 # 允许连接失败的次数。 max_connect_errors=10 # 服务端使用的字符集默认为utf8mb4 character-set-server=utf8mb4 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB # 默认使用“mysql_native_password”插件认证 #mysql_native_password default_authentication_plugin=mysql_native_password [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8mb4 [client] # 设置mysql客户端连接服务端时默认使用的端口 port=3306 default-character-set=utf8mb4 注意此处的路径为你自己安装的路径
4.初始化MySQL 在安装时,避免权限问题出错我们尽量使用管理员身份运行CMD,否则在安装时会报错,会导致安装失败的情况
打开后进入mysql的bin目录
在MySQL目录下的bin目录下执行命令:
mysqld --initialize --console 注意! [MY-010454] [服务器]为root @ localhost生成临时密码:9P0gYk-?0,kT其中root @ localhost:后面的9P0gYk-?0,kT就是初始密码(不含首位空格)。在没有更改密码前,需要记住这个密码,后续登录需要用到。复制密码先保存起来!
文章目录 前言1.网络发展背景2.计算机网络分类3.通信协议4.协议分层5. TCP/IP协议6.网络协议支持7. 封装&分用8. 客户端&服务端 前言 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
1.网络发展背景 单机阶段=>区域网阶段=>广域网阶段=>移动互联网阶段
2.计算机网络分类 随着时代的发展,计算机之间互相通信,共享软件和数据越来越频繁,即需要以多个计算机协同工作来完成业务,于是就有了网络互连。
网络互连:将多台计算机连接在一起,完成数据共享。数据共享:本质是网络数据传输,即计算机之间通过网络来传输数据,也称为网络通信。 根据网络互连的规模不同,可以划分为局域网和广域网
局域网(LAN):局域网是一种在小区域内使用的,由多台计算机组成的网络。广域网(WAN):广城网是一种远程网,主要是指把区域网连接起来(使用更多的路由器、交换机),当局域网规模够大,就形成了广域网。 3.通信协议 IP地址:IP地址主要用于标识网络主机、其他网络设备的网络地址。简单说,IP地址用于描述一个主机在互联网上的位置端口号:端口号可以标识主机中发送数据、接收数据的进程。简单可以理解为用于区分一个主机上的应用程序 4.协议分层 协议:就是指某种 “约定”(发送方约定他发的数据是啥样的格式,接收方也理解这个格式,两边对上才能正确的进行通信)我们现在常用的协议有TCP/IP协议。协议分层: 在网络通信中,需要约定的协议是非常复杂的,因此我们在组装网络的时候,会把网络拆分成许多小的协议,然后我们通过对这些小的协议进行分类,再通过类别进行分层,我们可以理解为约定了层与层之间的调用关系,要求上层调用下层,下层为上层提供支持、不能进行跨级调用。协议分层的作用: 协议分层可以降低层次之间的耦合程度,在针对一个复杂的协议替换时,我们只需要替换某一层即可,省去了对复杂协议的全部替换。 5. TCP/IP协议 TCP/IP五层网络模型主要包括:应用层、传输层、网络层、数据链路层、物理层
物理层:网络通信的基本设施.网线、光纤等等数据链路层:主要关注两个相邻节点之间的传输网络层:关注两个遥远节点,做路径规划;众多路径中取合适的传输层:只关注起点与终点应用层:关注传输过来的数据干啥用 6.网络协议支持 Java中的网络协议主要封装在java.net中,该包中提供了两种常见的网络协议的支持:TCP和UDP
TCP是一种有连接、可靠传输、面向字节流、全双工的网络协议,是可靠的连接,TCP就像打电话需要对方确认接电话UDP是一种无连接、不可靠传输、面向数据报、全双工的网络协议,UDP是不可靠的,就好比发微信,我只管发,你收没收到我并不清楚 7. 封装&分用 在协议分层的背景下,数据如何通过网络传输:
发送方发送数据,把数据从上到下,一次交给对应的层次协议,进行封装
接收方收到数据,把数据从上到下,依次交给对应的层次协议,进行解析
接收方的每一层只把对该层有意义的数据拿走,然后把其余的部分传递给上一层。
封装过程(从上到下依次增加报头):
(1)应用层将数据交给传输层,传输层添加上UDP的控制信息(称为UDP报头),这个数据单元称为数据段(Segment),加入控制信息的过程称为封装。然后,将数据段交给网络层。
(2)网络层接收到数据段,再添加上IP头部,这个数据单元称为数据包(Packet)。然后,将包数据交给数据链路层。
(3)数据链路层接收到数据包,再添加上发送方的mac地址和接收方的mac地址,这个数据单元称为以太网数据帧(Frame)。然后,将数据帧交给物理层。
(4)物理层将接收到的数据转化为光/电信号,然后在网线中传送。
分用过程:
(1)物理层接收到比特流,经过处理后将数据交给数据链路层。
(2)数据链路层将接收到的数据转化为数据帧,再除去发送方的mac地址和接收方的mac地址,这个除去控制信息的过程称为分用(解封装),然后将包交给网络层。
(3)网络层接收到包,再除去IP头部,然后将段交给传输层。
(4)传输层接收到段,再除去TCP头部,然后将数据交给应用层。
8. 客户端&服务端 客户端:获取服务的一方进程,称为客户端。服务端:在常见的网络数据传输场景下,把提供服务的一方进程,称为服务端,可以提供对外服务。常见客户端服务端模型: 客户端先发送请求到服务端服务端根据请求数据,执行相应的业务处理服务端返回响应:发送业务处理结果客户端根据响应数据,展示处理结果(展示获取的资源,或提示保存资源的处理结果)
前言 俗话说,工欲善其事必先利其器,做嵌入式开发首先需要选择好的工具,对的工具,工具选对了能事半功倍,节省很多时间,那些开发大佬一般都会使用各种各样的工具,不同的环节使用不同的工具,这也是人与动物最大的区别!
以下是我开发多年使用并且觉得好用的工具,基本都是免费有些甚至是开源的工具!
项目管理 XMind:思维导图,帮助梳理框架,理清脉络,也是画图的好工具;
Processon:在线思维导图,如果没安装软件就可以用这个网页版,很方便;
GoJS:在线画图,https://gojs.net/latest/samples/index.html
有道云笔记、语雀:云笔记与他人知识共享等,如果不喜欢打字,可以用有道云语音转换记录
软件开发 Keil:STM32、ARM等MCU开发利器,功能很全,也很好用,社区版是免费的
STM32CubeMx:可视化配置引脚以及外设就可以生成代码,懒人利器
STM32CubeProgrammer:可以刷固件,可以读写芯片flash内容,方便比较与验证
STM32CubeMonitor:可视化监控代码中的某些变量,非常方便输出
Dev C++:Windows程序调试,轻量型软件方便安装使用
Qt Creator:跨平台的界面开发软件,嵌入式、桌面和移动端都可以
flutter:界面开发软件,做的界面更好看,主要用在移动端
调试工具 sscom:我觉的最好用的一款串口调试工具,发送指令可自由编辑,能中英文切换等等
beyond compare:代码比较工具
llcom:集成MQTT/UDP/TCP/USB等各种调试小工具,我主要是用来调试MQTT
比MQTT.fx与MQTTX好用,mosquitto:MQTT代理服务器
wireshark:网络数据抓包,可用来分析协议
SerialChart:串口绘图工具,方便图形输出
pcanView:CAN数据分析,需搭配PCAN-USB工具,或者USB_CAN TOOL(CANalyst-II工具)
远程工具 MobaXterm:远程登录神器,特别好用
向日葵:Windows远程桌面与文件
代码阅读 VS Code:代码阅读利器,扩展性很强,增加一些插件可以编辑Markdown文件,思维导图等等
Notepad++:单个文件编辑、阅读,编码转换,比txt好用
其它 做嵌入式开发也要劳逸结合,累了的时候可以到下面网站听听音乐或者拍拍小视频!
小而美的录屏工具,GIF生成神器
https://www.screentogif.com/
无损音乐下载网站
https://tool.liumingye.cn/music/?page=searchPage#/
保存为NV12格式的yuv420,yyyuvuvuv
#include <string> #include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> int main() { std::string jpgpath = "test.jpg"; cv::Mat img = cv::imread(jpgpath); int w = img.cols; /* 宽 */ int h = img.rows; /* 高 */ int imageLength = h * w * 3 / 2; /* 图像y、u、v个数总和 */ unsigned char*yuv_nv12 = new unsigned char[imageLength]; /* 存储nv12数据 */ unsigned char*yuv = new unsigned char[imageLength]; /* 存储CV_BGR2YUV_I420数据 */ cv::cvtColor(img, img, CV_BGR2YUV_IYUV); /* BGR空间转换为CV_BGR2YUV_I420 */ memcpy(yuv_nv12, img.
目录 前言一、错误原因二、解决方法三、兼容 Python 2.x 和 3.x3-1、使用判断3-2、使用try-except 总结 前言 一般来说,这个错误是由于在 Python 3.x 中错误地调用了字符串的 decode 方法,或者因为导入了不兼容的第三方库或自定义模块而引起的。 一、错误原因 在 Python 3.x 中,大部分情况下不会出现 “AttributeError: ‘str’ object has no attribute ‘decode’” 错误,因为在 Python 3.x 中,字符串已经是 Unicode 类型,不再具有 decode 方法。然而,如果你尝试在字符串上调用 decode 方法,就会引发此错误。
但是,如果你在 Python 3.x 中使用第三方库或遗留代码(可能编写于 Python 2.x),有时可能会出现一些特殊情况,例如:
导入了一个自定义模块,该模块在 Python 2.x 中使用了字符串的 decode 方法,并且没有在 Python 3.x 中进行适当的修改。使用某些第三方库,该库可能包含 Python 2.x 和 Python 3.x 的兼容性问题,导致调用字符串的 decode 方法时出现错误。 二、解决方法 针对以上错误提出以下解决方法:在 Python 3.x 中,字符串已经是 Unicode 类型,不再有 decode 方法。所以,如果你在代码中看到类似 str_.decode(‘utf-8’) 这样的调用,请直接移除它。修改代码中所有错误地调用了 decode 方法的部分。
一、安装和配置svn服务
1、安装subversion
#yum install subversion
2、查看版本
#svn --version
3、创建仓库
#mkdir -p /app/svn
#cd /app/svn
#svnadmin create test
4、启动SVN
#svnserve -d -r /app/svn
5、客户端测试SVN
svn://127.0.0.1/test
6、停止SVN
#killall svnserve
二、配置SVN开机自启动
1、检查svn服务配置
#cat /lib/systemd/system/svnserve.service
[Unit]
Description=Subversion protocol daemon
After=syslog.target network.target
Documentation=man:svnserve(8)
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/svnserve
ExecStart=/usr/bin/svnserve --daemon --pid-file=/run/svnserve/svnserve.pid $OPTIONS
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
没有打出上面的内容则需要vi编辑文件
2、配置启动目录
#vi /etc/sysconfig/svnserve
将 OPTIONS="-r /var/svn" 改为 svn 版本库存放的目录,:wq 保存退出
3、配置自启动服务
#systemctl enable svnserve.service
4、手动启停服务命令
启动服务:
#systemctl start svnserve.service
停止服务:
恢复已经删除的数据取决于多种因素,包括删除的方式、存储设备的类型以及是否有备份等。以下是一些常见的方法,但不能保证所有情况下都能成功恢复数据。在尝试恢复数据之前,请确保不会进一步覆盖原始数据,以提高恢复成功的机会。
回收站: 如果你删除的是电脑中的文件,可以先检查回收站,看看文件是否在那里。如果在回收站中找到文件,你可以将其还原。备份: 如果你有备份数据的习惯,你可以从备份中恢复已删除的数据。数据恢复软件: 有一些专门的数据恢复软件,如傲梅恢复之星,可以扫描存储设备并尝试恢复已删除的文件。 下面,将以傲梅恢复之星为例,为大家讲解怎么恢复已删除的数据。
1. 下载安装并打开傲梅恢复之星,将丢失数据的设备连接到电脑,然后在傲梅恢复之星主界面中选择该设备,再点击“开始扫描”。
2. 根据文件系统和数据丢失情况选择扫描方法,如果需要,可以使用高级设置。
3. 等待扫描完成后,选择你需要的数据,然后点击“恢复x个文件”,再选择恢复文件的保存位置即可。
1.win+r,输入regedit regedit 2.进入以下路径 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 3.右键新建文件DWORD(32)并命名为:FlightSettingsMaxPauseDays 4.双击文件FlightSettingsMaxPauseDays更改数值数据为:999,基数为16进制,并确定 5.找到电脑设置,进入Windows更新,选择暂停更新351周 6.恭喜你完成了全部设置!相信可以用到你再换个本了。若想继续更新点击继续更新即可(相信没人想在更,windows真的坑!)
目录
简介:在换完国内源后,树莓派尝试更新同步/etc/apt/sources.list和/etc/apt/sources.list.d中列出的软件源的软件包版本也就是(apt-get update)和更新已安装的所有或者指定软件包(也即是apt-get upgrade)发生错误:
解决方法:
简介:在换完国内源后,树莓派尝试更新同步/etc/apt/sources.list和/etc/apt/sources.list.d中列出的软件源的软件包版本也就是(apt-get update)和更新已安装的所有或者指定软件包(也即是apt-get upgrade)发生错误: 根据显示的报错,完成下列签名即可,即在本地配置一个公钥:9165938D90FDDD2E
我这里配置的是清华的源,可能你需要配置的公钥与我的不同,按照提示相应换成你的就可以了。
解决方法: gpg --keyserver keyserver.ubuntu.com --recv-keys [提示的公钥]
gpg --export --armor [提示的公钥] | sudo apt-key add -
解决完成后输入:
sudo apt-get update
sudo apt-get upgrade
raspbian | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 另外如果你不知道自己换源的地址,可以在上述的地址中查找
例如,你在第一个红色框中选择自己系统版本等相关信息,下一个红色框会自动生成相应的地址。
文章目录 1,前言2,实现思路3,实现代码 1,前言 事情的起因是这样的,项目是用cli搭建的uni-app小程序。申请了两个appid,一个用作开发人员调试使用,体验版和正式版都是dev环境。一个体验版是测试环境或者beta环境,而正式版是线上环境。基于这种情况,我想了两个方案来动态配置。
1,用node动态更换appid,并且写4个环境env文件,配置不同的打包命令(结果uview这个库在打包test和beta环境时一直报错,短时间没找到原因)2,还是用node动态更换appid,并且写4个环境env文件,配置不同的打包命令,但是多加了一个json文件,用node动态修改文件,在App.vue里导入。 2,实现思路 首先,小程序运行时,自带一个运行环境变量,值是一个字符串,如下表:
环境值开发版develop体验版trial正式版release 根据这个值,我这边创建了env.dev.js,env.test.js,env.beta.js,env.pro.js,四个文件在根目录。里面写了四个环境对应的appid,和本地版请求地址,体验版接口请求地址,正式版请求地址。并且在src目录新增了requestPath.json文件和modifyManifest.js文件,具体用法如下。
3,实现代码 env.dev.js /* 1,VUE_APP_WX_APPID字段是小程序的appid 2,xxx_url字段是小程序各版本的请求域名 */ module.exports = { PROGRAM_NAME: '小程序名字', VUE_APP_WX_APPID: '987654321', develop_url: 'dev-baidu.com', // 本地版 trial_url: 'dev-baidu.com', // 体验版 release_url: 'baidu.com' // 线上版 } env.prd.js /* 1,VUE_APP_WX_APPID字段是小程序的appid 2,xxx_url字段是小程序各版本的请求域名 */ module.exports = { PROGRAM_NAME: '小程序名字', VUE_APP_WX_APPID: '123456789', develop_url: 'dev-baidu.com', // 本地版 trial_url: 'dev-baidu.com', // 体验版(正式环境发版,需要提交审核,审核不可能给微信客服人员正式环境来测试,所以这里的体验版是开发环境) release_url: 'baidu.com' // 线上版 } modifyManifest.js const fs = require('fs') const envDev = require('../env.dev') const envTest = require('.
目录 1,前言2,介绍3,安装和使用效果图后记 1,前言 有些项目中,或者是视频网站,都需要视频播放功能。我们可以用H5的video标签实现播放,但是原生的样子视频播放器不太好看,功能也需要自己封装。这时候可以站在巨人的肩膀上,使用已造好的轮子vue-video-player
2,介绍 vue-video-player目前在Github上拥有3.9K的star,拥有一系列的监听和事件回调,自带有倍速,全屏,拖动进度条和音量调节等功能,很实用。
详细文档地址:vue-video-player文档
3,安装和使用 安装:
npm install vue-video-player --save 全局引入:
// main.js中 import VideoPlayer from 'vue-video-player' require('video.js/dist/video-js.css') require('vue-video-player/src/custom-theme.css') Vue.use(VideoPlayer) 局部引入:
// 在组件中引入 import { videoPlayer } from 'vue-video-player' import 'video.js/dist/video-js.css' // 注册 components: { videoPlayer } HTML部分:
PS:class名vjs-big-play-centered是播放按钮居中
<template> <div id="player"> <video-player ref="videoPlayer" class="video-player vjs-big-play-centered" :playsinline="false" :options="playOptions" @ready="onPlayerReady" @play="onPlayerPlay($event)" @pause="onPlayerPause($event)" @ended="onPlayerEnd($event)" /> </div> </template> less部分:
#player{ width: 1000px; height: 500px; margin: 0 auto; } 事件部分:
🌈介绍 基于 vue3.x + CompositionAPI + typescript + vite 的可拖拽、缩放、旋转的组件
拖拽&区域拖拽支持缩放旋转网格拖拽缩放 在线示例
源码地址
这节主要来分享如何使用es-drager,根据现有功能实现拖拽时生成辅助线、撤销重做等画布常用功能
话不多说,咱们开始吧!
画布准备工作 这里只是一个简单的画布模板
画布数据源 import { ref, CSSProperties } from 'vue' // 组件类型 type ComponentType = { component: string // 内部组件名称,自定义组件需要提前全局注册 text?: string // 文本 width?: number height?: number top?: number left?: number angle?: number style?: CSSProperties // 样式 } interface EditorState { componentList: ComponentType[] } const data = ref<EditorState>({ componentList: [ { component: 'div', text: 'div1', width: 100, height: 100, left: 0, top: 0 }, { component: 'div', text: 'div2', width: 100, height: 100, top: 100, left: 100 } ] }) 循环渲染组件到画布上
🌈介绍 基于 vue3.x + CompositionAPI + typescript + vite 的可拖拽、缩放、旋转的组件
拖拽&区域拖拽支持缩放旋转网格拖拽缩放 在线示例
源码地址
上一篇实现细节的文章遗留下了两个问题
旋转后再缩放会很奇怪旋转后鼠标经过缩放圆点上时的样式也不相称 由于这两个问题代码量较多,建议大家直接去看源代码
这篇文章主要分享一下网格拖拽和缩放比的实现及es-drager组件的具体使用,建议大家先看看第一篇文章 可拖拽、缩放、旋转组件实现细节
网格拖拽和缩放比实现 效果展示 这块功能主要是最近有朋友在github上提过相关需求,就给es-drager加上了
添加相关props const props = { // ... snapToGrid: Boolean, // 是否开启网格 gridX: { // 网格X大小 type: Number, default: 50 }, gridY: { // 网格Y大小 type: Number, default: 50 }, scaleRatio: { // 缩放比 type: Number, default: 1 } } 在移动的时候校验 主要关注onMousemove里对网格的判断即可
const onMousemove = (e: MouseEvent) => { // 使用缩放比后的移动距离计算 let moveX = (e.
文章目录 1.命令简介2.命令格式3.选项说明4.常用示例5.authorized_keys 和 known_hosts参考文献 大咖好呀,我是恋喵大鲤鱼。 !!! 我的第二本开源书籍《后台开发命令365》上线啦,欢迎大家协同共建。
1.命令简介 ssh-keygen 是 OpenSSH 身份验证密钥实用工具。
ssh-keygen 用于 OpenSSH 身份验证密钥的生成、管理和转换,它支持 RSA 和 DSA 两种认证密钥。
2.命令格式 ssh-keygen [OPTIONS] FILE... 3.选项说明 下面只列出常用的选项,更多选项可参考手册。
-b BITS 指定密钥长度。 -e 读取私有或公共 OpenSSH 密钥文件并以 -m 选项指定的格式之一将密钥打印到标准输出。 -C 添加注释。 -f FILENAME 指定用来保存密钥的文件名。 -i 以 -m 选项指定的格式读取未加密的私钥(或公钥)文件,并将 OpenSSH 兼容的私钥(或公钥)打印到 stdout。 -l 显示公钥文件的指纹数据。 -m KEY_FORMAT 为 -i(导入)或 -e(导出)转换选项指定密钥格式。支持的密钥格式为:“RFC4716”(RFC 4716/SSH2 公钥或私钥)、“PKCS8”(PEM PKCS8 公钥)或“PEM”(PEM 公钥)。 默认转换格式为“RFC4716”。 -N 提供一个新密语。 -P PASSPHRASE 提供(旧)密语。 -q 静默模式。 -t 指定要创建的密钥类型。可能的值为“dsa”、“ecdsa”、“ecdsa-sk”、“ed25519”、“ed25519-sk”或“rsa”。 -y 从 OpenSSH 格式的私钥导出公钥。 4.
解决方法 一般来说是驱动问题,但下驱动要下到点子上,不能瞎下,先找问题根源。
问题背景:新买的笔记本 神舟z8d6,装了win11系统以后,发现触摸板只能普通滑动和点击,无法设置手势等快捷操作。
首先查看 win11设置里触摸板栏有什么问题?
只有一个点击选项,调整灵敏度,下面手势设置什么的都没有了。
判断触摸板硬件是否正常 ,普通的单指鼠标滑动,点击功能,如果基本功能都有问题的话,先初步解决硬件问题。
打开设备管理器,查看硬件是否在,驱动是否报warning叹号
博主一开始鼠标和其他指针这一栏里是没有 HID-compliant Device这一项的,这张图是解决后的样子。主要问题根源就是设备管理器里没有hid这一项
由于触摸板基本操作没问题,首先排除硬件问题。
一般来说,笔记本触摸板是集成在主板上的,涉及IO,首先想到了两个驱动:
HID驱动IO接口驱动 进入神舟官网,服务与支持,驱动下载,找到HID驱动和IO接口驱动
先安装完HID驱动之后,没什么反应,问题没有解决,依然无法双指滑动。
安装intel IO接口驱动,问题解决。设备管理器中鼠标和其他指针设备栏恢复正常,人体工学设备HID恢复。
提示:下滑文章左侧可以查看目录!本教程分为多篇,总目录如下。
总目录:
README.md · Python-ZZY/Python-Pygame最完整教程 - Gitee.com
1 初识pygame 1.1 简介 pygame是python中一个流行的GUI编程模块,是专门为了开发游戏而设计的。这是一个第三方模块,是SDL和Python的接口。
pygame的最新官网是:https://pyga.me/
pygame以前的官网是:https://www.pygame.org/
SDL的官网是:https://www.libsdl.org/
1.2 pygame的优势 pygame的核心功能使用的是C代码,大大提高了运行的速度。
pygame支持在大部分操作系统运行,可跨平台,在经过编译后可以在Andriod手机和网页上运行。
pygame十分简单而且易于掌握,自由性强。
pygame功能全面。其支持的功能包括:图片、文字、绘图、OpenGL 3D、音频、摄像头、游戏手柄等。
1.3 安装pygame pygame是一个第三方模块,这意味着需要在安装后才能使用。
使用pip工具就可以安装,在cmd输入后按下回车,稍等一会儿:
pip install pygame-ce 注意:此处的pygame-ce是pygame官方的社区编辑版,推荐使用。普通版的pygame可用pip install pygame安装
安装完成后,尝试导入pygame,会打印出一段文字,提示pygame的版本:
在本教程中,使用的是较新版的pygame2。
1.4 pygame子模块 pygame的许多功能都定义在不同的子模块里面。下面列举了常用的子模块。读者可以了解一下。
模块名描述camera操作系统摄像头cursors加载、编译光标图像display配置pygame的显示表面draw在表面上绘制形状event管理用户事件(如键盘、鼠标)font加载和绘制TrueType字体freetypefont模块的扩展,提供更多字体操作gfxdraw绘制抗锯齿的形状image加载、保存图片文件joystick管理游戏手柄key管理键盘输入locals此模块储存所有的pygame常量mixer播放声音mouse管理光标位置和事件midiMIDI输入与输出管理scrap管理剪贴板sndarray处理声音样本数据sprite管理精灵surfarray处理图像像素数据system获取或管理当前系统上的一些信息time管理时间和帧率transform变换表面(如缩放、旋转等)_sdl2一些实验性的东西 注:pygame还增加了许多功能,作者后期会进行补充
pygame中一些常用的模块会自动导入,所以大部分模块无需额外导入。
1.5 关于本教程 众所周知,教程和文档是两个不同的东西,文档最为全面但不易学,教程易学但不可能涵盖所有内容。
本教程为了达到完整性,会先在每一节介绍模块中较常用的使用方法,最后以“模块索引”的形式列举所有方法。
标题标注为红色的是重要内容,制作游戏中必然会用到。黑色的标题读者可自行了解,灰色的标题表示不重要、不常用。
1.6 表面 pygame可以绘制一些图片、文本。为了在窗口上显示它们,pygame提供了一系列的方法来导入、渲染。但在这之前,所有的绘制内容都会转化成一个pygame.Surface对象(表面对象,可以理解成一张纸,上面可以绘制内容),这样才能进行绘制。表面由像素构成,是一个矩形。pygame也提供了一些方法处理表面。
整个pygame窗口除去标题栏的部分可以按照一个表面来操作。在操作表面的时候,比如要在某个地方绘制一段文字,必然会涉及到坐标的处理。在pygame中,最简单的一种坐标表示方式是使用一个形如(x, y)的可迭代对象,如(0, 0), (100, 50)等等。
pygame的坐标系中,原点(0, 0)在左上角,x轴正方向向右,y轴正方向向下。
2 第一个pygame示例 import pygame as pg #导入pygame模块,通常为了简便而命名为pg pg.init() #初始化 screen = pg.display.set_mode((400, 400)) #建立一个400x400的窗口 pg.
如何监测MySQL是否命中索引?感觉这篇文章介绍得比较详细,就搬过来了,在日常工作中,我们有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,此时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描。所以我们深入了解MySQL的基于开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪种策略预计会被优化器采用。(QEP:sql生成一个执行计划query Execution plan)
mysql> explain select * from servers; +----+-------------+---------+------+---------------+------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+---------------+------+---------+------+------+-------+ | 1 | SIMPLE | servers | ALL | NULL | NULL | NULL | NULL | 1 | NULL | +----+-------------+---------+------+---------------+------+---------+------+------+-------+ 1 row in set (0.03 sec) expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,下面对这些字段出现的可能进行解释:
一、 id
我的理解是SQL执行的顺序的标识,SQL从大到小的执行
1.id相同时,执行顺序由上至下
2.如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
3.id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行
二、select_type
示查询中每个select子句的类型
在Java中,如果你想拷贝一个List对象到一个新的List对象,并且修改原来的List不影响新的List中的内容,有几种方法可以实现: 使用构造函数: 可以使用List的构造函数,传递原始List作为参数来创建一个新的List对象。这样做会创建一个新的List对象,两个List对象互相独立,修改其中一个不会影响另一个。 List<String> originalList = new ArrayList<>(); // 添加一些元素到originalList List<String> newList = new ArrayList<>(originalList); // 修改originalList不会影响newList 使用addAll()方法: 可以使用List的addAll()方法将原始List中的所有元素添加到一个新的List中。 List<String> originalList = new ArrayList<>(); // 添加一些元素到originalList List<String> newList = new ArrayList<>(); newList.addAll(originalList); // 修改originalList不会影响newList 使用Java 8的stream()方法: 如果你在Java 8及以上版本中,可以使用stream()方法和collect()方法来实现拷贝。 List<String> originalList = new ArrayList<>(); // 添加一些元素到originalList List<String> newList = originalList.stream() .collect(Collectors.toList()); // 修改originalList不会影响newList 无论使用哪种方法,都会在内存中创建一个新的List对象,使其与原始List对象互相独立,从而可以在不影响彼此的情况下对它们进行修改。
文章目录 原20230806 github改了,文件点进去后,右边有个下载按钮,点一下就能下载 原 比如要下载这里:https://github.com/DaveGamble/cJSON 的文件cJSON.c,只需直接点开它:
然后在新页面右边有个Raw,对它右键,选择目标另存为下载即可,
如果没有,比如我用的是360安全浏览器,点击使用360安全浏览器下载或者使用迅雷下载,都是可以的
参考文章:github上如何下载单个文件
20230806 github改了,文件点进去后,右边有个下载按钮,点一下就能下载
我假设你已经在你的服务器上安装了宝塔,于是我们直接进入宝塔页面。
将文件上传到服务器 在这里进行目录的创建与文件的上传:将编译好的能够在linux上运行的文件上传,包括配置文件及静态资源。不依赖包而直接修改环境进行编译可看:go在win环境下编译linux可执行文件_go windows编译linux_陌北v1的博客-CSDN博客找到网站的go项目上传项目 选择上传的可执行文件选择端口,一定不能于其他服务的端口冲突宝塔会自动为你生成命令确认并上传
HTTP协议目录 HTTP的概论HTTP请求HTTP请求HostContent-Type和Content-lenthUser-Agent(UA)RefererCookie HTTP响应状态码 HTTPS HTTP的概论 我在网络那一篇文章中写到:我们常用的网络结构;是5层网络结构。分别是应用层,传输层,网络层,数据链路层,物理层。
应用层:关注数据怎么使用。
传输层:关注整个传输的起点和终点。
网络层:地址管理加路由选择。
数据链路层:相邻节点之间的数据转发。
物理层:基础设施构建等同于现实的高速公路。
http协议是一个使用非常广泛的应用层协议,也是TCP/IP协议栈。
应用层的协议,经常需要自定义协议。协议可定制性就非常强,所以基于HTTP我们可以进行拓展。
只要连接外网,基本上就都会使用HTTP协议。
http是一个一问一答形式的协议,及一个请求,一个响应。
而我们主要是去了解HTTP的报文格式,我们要去理解HTTP的报文格式我们就需要一个外部的工具,将HTTP协议显示出来,而这个工具呢,俗称抓包工具。
一般谷歌浏览器和IE浏览器他们会提供抓包的东西。通常按F12键就可以进入一个网页的开发者模式,我们在开发者模式中找到网络这个选项,就可以在里面找到。相应的报文。
但我们作为一个专业的程序员,我们就应该去选择一个专业的工具,这里呢,我推荐大家使用fiddler。软件有付费版和免费版啊,免费版就够用。
这个HTTP上面的所有东西都要勾选上,不然的话无法抓捕到包头。
软件,左边的是HTTP的列表。主要是相对应的HTTP的具体数据,而我们这里要用的是raw,观看HTTP的具体报头,是纯净版。
一般我们看到的请求大部分都是get请求,在登录和上传文件的时候会看见post请求。
一般我们看HTTP呢就看get和post就足矣,可看可不看。
补充一点:一般post请求不会随意出现,一旦出现必定是上传文件的时候。而在登录的时候,我们也需要去提交材料,提交登录信息,而此时你的密码在抓包工具被抓包的情况下,也就是在boss请求被抓到的情况下,会在下面显示密码。有一些网站对于这一块的保密做的不是很好,就使得有一些。非法分子对其的电脑做一些抓包处理,抓到登录账号和密码。它有一些它是经过加密的,但是经过特殊处理之后还是能被显示出来,所以你账号一定不要注册一个,尽量多注册几个高端密码。
post请求body一般不为空,而get请求body的时候一般为空。
HTTP 报文中要存在 "空行,HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 “粘包问题” 。
就是我们上传的数据计算机无法有效识别。所有的值都成为了一条字符串,无法有效的进行分割。
HTTP请求 Get的语义是从服务器里拿一个东西。
post的语义网服务器里提交一个东西。
http的这种语义通常是一种建议,在实际开发中也可以不一定遵守,对于body有没有,也不能说是绝对,get,有可能会有body,而post也可能会没有有body,只不过这种情况比较少见。
对于get和post这两种方法来说,本质上是没有区别的。也可以互相替换。但是对于操作习惯来说,他们两者是有区别的。
get习惯上用来表示获取一个数据,而post用来表示提交一个数据。
一般没有body需要携带数据,则放到URL中post没有,一般有body。
get经常会被设计成幂等,而post则无要求。什么是幂等?就是我们输入一个变量,他不是随机的。每一次输入这个变量会出现一个固定的值,这个叫幂等。
get可缓存的(提前是幂等), Post则不能。
Get请求可以被浏览器收藏,post不能。
报文格式:
请求
首行( 方法 URL 版本号)请求头 header.空行。正文body。 URL 协议名://IP:端口号/带层次的路径?查询字符串
响应。
首行(版本号,状态栏,状态码,描述)响应头harder。空行。正文body,通常是一个html,css,js或图片。 HTTP请求 Host Host:www.baidu.com
这个属性,除了浏览器,这个请求要访问的服务器是谁。
绝大多数情况下,Host中的值和URL中的域名是一致的。当我们通过代理来访问的时候。此时host和URL就不同了。host是作为最终目标,而URL是当前目标。
Content-Type和Content-lenth Content-Type :描述了body的数据格式。
Content-lenth:描述了body的长度,单位字节。
Content-Type: application/json;charset=utf-8
首先,我建议你检查你的操作系统是否兼容64位的Miniconda3版本。如果你的操作系统是32位的,那么你需要下载适用于32位系统的Miniconda3版本
树莓派是aarch64(64位ARM架构),操作系统是32位的,在装Miniconda3遇到这个错误Miniconda3-py37_4.9.2-Linux-aarch64.sh: line 398: /root/miniconda3/conda.exe: No such file or directory
根据描述的错误信息,在aarch64架构的树莓派上安装Miniconda3时报错找不到conda.exe文件,这很有可能是由于操作系统和Miniconda不匹配导致的。
主要原因在于:
你的树莓派CPU架构是64位的aarch64
但操作系统仍旧是32位的
而你安装的Miniconda3版本是Linux-aarch64,即64位版本
所以就出现了操作系统找不到Miniconda安装包中预期的64位可执行文件conda.exe的问题。
要解决这个问题,需要选择与你的操作系统匹配的Miniconda版本,具体方法是:
确认你的树莓派系统是32位还是64位,使用 getconf LONG_BIT 命令查看,使用uname -a查看树莓派内核信息。
niu@raspberrypi:~ $ getconf LONG_BIT 32 niu@raspberrypi:~ $ uname -a Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux 32代表操作系统是32位,aarch64代表64位ARM版本。
如果是32位系统,应该安装Miniconda3-py37_x.x.x-Linux-armv7l.sh,注意armv7l表示32位ARM版本。
下载正确的版本后再次尝试安装
安装完成后验证conda命令能否正常使用
这样就可以解决不匹配的操作系统位数导致的安装错误。
补充:
树莓派的CPU本身支持64位指令集,这从它的名称“aarch64”就可以看出(64位ARM架构)。
但是树莓派上运行的操作系统可以选择是32位或者64位的。
这主要有以下几个原因:
向后兼容 - 许多早期的ARM板卡都是32位系统,为了兼容旧软件和外设,树莓派提供32位系统选项。内存限制 - 树莓派早期型号内存较小,32位系统对内存需求较少。系统开销 - 64位系统相比32位会有更高的内存开销,对于资源受限的设备来说32位系统更省资源。软件生态 - 一些 third-party 软件和库只提供32位版本,为了易用性树莓派将其作为默认选项。系统稳定性 - 32位系统相比64位,存在时间更长,会更加稳定可靠。 综上所述,尽管CPU本身支持64位,出于兼容性、资源限制和生态多样性的考虑,树莓派可以选择运行32位操作系统。但对于资源充足的应用,运行64位系统同样可以发挥硬件全部性能。这种设计提供了更好的平衡。
我来总结一下不同架构和位宽对应的缩写:
目录
一、消息存储格式设计
🍅 1、queue_data.txt:保存消息的内容
🍅 2、queue_stat.txt:保存消息的统计信息
二、消息序列化
三、自定义异常类
四、创建MessageFileManger类
🍅 1、约定消息文件所在的目录和文件名字
🍅 2、队列的统计信息
🍅 3、创建队列对应的目录和功能
🍅 4、实现删除队列的文件和目录
🍅 5、检查队列的目录和文件是否都存在
🍅 6、把消息写入到文件中
🍅 7、删除文件中的消息
🍅 8、将硬盘中的数据加载到内存中
🍅 9、实现消息文件的垃圾回收
🎈 检测是否要进行GC
🎈 构造新目录
🎈 进行GC操作
五、测试MessageFileManager类
🍅 1、“准备工作”和“收尾工作”
🍅 2、测试创建文件是否存在
🍅 3、测试writetStat和readStat是否能够通过
🍅 4、测试sendMessage
🍅 5、测试删除消息
🍅 6、测试垃圾回收
六、小结
一、消息存储格式设计 对于消息,并不打算存储在数据库中:
(1)消息操作并不会涉及到复杂的增删改查
(2)消息的数量可能会非常多,数据库的访问效率并不高
所以,我们直接把消息存储在文件中。
那么消息要如何在文件中存储呢?
首先消息,它是依附于队列的,所以在存储的时候,就把消息按照队列的维度展开。
我们会将队列存储在和数据库同级的data目录中,在data中创建一些子目录,子目录的名字就是队列名。
然后在每个队列的子目录下面,再分配两个文件,用来存储消息。主要是以下两个文件。
🍅 1、queue_data.txt:保存消息的内容 Message是一个二进制格式的文件,包含若干个消息,每个消息都以二进制的方式存储,每个消息都由这几个部分构成:Message对象序列化之后。
Messag对象,会分别再内存和硬盘上都记录一份。内存中的衣服呢会记录offsetBegin和offsetEnd。这样就可以找到内存中的Message对象,能够找到对应的硬盘上的message对象。
关于isValid:是用来标识当前消息在文件中是否有效,为1就是有效的消息,为0就是无效的消息。当为0时就相当于逻辑上的删除消息功能。但是,随着时间的推移,消息的增多,那么该消息可能就会大部分都是无效的消息,针对这种情况,就需要对当前消息的文件,进行垃圾回收。
以下是本程序中实现的垃圾回收功能: 垃圾回收(GC):使用复制算法,针对消息数据文件中的垃圾回收进行回收。直接遍历原有的消息数据文件,把有效的数据拷贝到一个新的文件中,然后把之前的旧文件都删除掉(逻辑删除)。
作出约定(可以不按这个来),当总消息数目超过了2000,并且有效的消息数目低于总数目的50%,就出发一次垃圾回收。
对于RabbitMQ解决垃圾回收的方式如下:
如果某个消息队列中,消息很多,都是有效消息,就会导致整个消息的数据文件特别答,后续针对文件的各种操作,成本就会很高。RabbitMQ解决方案如下:
文件拆分:当单个文件长度达到一定阈值以后,就会拆分成两个文件(拆分次数越多文件就越多)
文件合并:每个单独的文件都会进行GC,如果GC之后,就会发现文件变小很多,当小到一定程度,就会和其他文件合并。
这样就会再消息特别多的时候,也能保证性能上的及时响应。
本文目录 1. 安装 JDK2. 获取 Jenkins 安装包3. 将安装包上传到服务器4. 修改 Jenkins 配置5. 启动 Jenkins6. 打开浏览器访问7. 获取并输入 admin 账户密码8. 跳过插件安装9. 添加管理员账户 1. 安装 JDK Jenkins 需要依赖 JDK,所以先安装 JDK1.8。输入以下命令: yum install java-1.8.0-openjdk* -y 安装目录为 /usr/lib/jvm,可以依次输入以下命令查看: cd /usr/lib/jvm ll cd java-1.8.0-openjdk ll 2. 获取 Jenkins 安装包 下载页面: https://jenkins.io/zh/download/ 安装文件: jenkins-2.190.3-1.1.noarch.rpm 3. 将安装包上传到服务器 注:因为直接在终端进行下载会很慢,还有可能下载失败,所以这里就采用将安装包下载下来,然后上传到服务器的方式。
进行安装,输入以下命令: rpm -ivh jenkins-2.190.3-1.1.noarch.rpm 4. 修改 Jenkins 配置 进入相关配置文件,输入以下命令: vim /etc/sysconfig/jenkins 注:按下键盘的 i 键进入编辑模式。
修改内容如下:
JENKINS_USER=“root”
JENKINS_PORT=“8888”
注:修改完成后,先按 Esc 退出编辑模式,然后输入 :wq 保存并退出。
一、前言 2021 年开始,Ubuntu 官方不再支持 PHP 5.6 版本的维护和更新,因此如果需要在 Ubuntu 上安装 PHP 5.6,则需要使用第三方的 PPA(个人软件包归档)来进行安装。
二、安装步骤 1. 添加paa仓库 add-apt-repository ppa:ondrej/php 说明:上述命令是用于将第三方软件包仓库添加到 Ubuntu 系统的命令。这个特定的命令表示要添加 ondrej/php PPA(Personal Package Archive)。
PPA 是 Ubuntu 中用于存储个人或团队维护的软件包的仓库。通过添加 PPA,你可以轻松地访问和安装这些软件包,而不必手动下载和编译源代码。
在这种情况下,ondrej/php PPA 是由 Ondřej Surý 维护的一个 PHP 软件包仓库。它提供了较新版本的 PHP 和相关的扩展、工具等,可以在 Ubuntu 系统上使用。
2. 更新源并升级系统 sudo apt update sudo apt upgrade 3. 安装 PHP 5.6 sudo apt install php5.6 4. 安装PHP常用扩展 sudo apt install php5.6 php5.6-fpm php5.6-mysql php5.6-gd php5.6-mbstring php5.6-curl php5.6-soap php5.
其实,这个主题似乎应该拿像帝国时代或者星际争霸这样的RTS游戏来讲更合适,但现在貌似MOBA游戏的受众更广一些,所以就拿MOBA游戏中比较流行的王者荣耀来展开。
我们知道,春秋时代早期战争还是很讲礼仪的,大家都讲规矩,按套路出牌。干架前先下战书,先说好准备出多少兵,要在哪里打,对方要是被打败的话追多少距离,还不能在别人天灾人祸时趁人之危。感觉这打仗不是在打打杀杀,是人情事故…而到了春秋朝代末期,大家就开始不讲武德,放飞自我了。玩就是兵不厌诈。一部《三国演义》更是将各种战争谋略写得让人拍案叫绝,单纯如我要是在里边肯定一集都撑不过去就嘎了。当然,最广为人知的还要数兵法传世经典《孙子兵法》。春秋时期军事家孙武将事军事思想凝结成《孙子兵法》一书,成为无比实用的宝贵历史遗产。由于科技的发展,今天的战争已和当时的天差地别,但书里面的很多思想到今天仍然一点都不过时。
我们知道,孙子兵法的英文版叫 《The Art of War》。事实上,它确实也不负这个名头,因为它将战争提到艺术的高度。另一方面,像王者这种MOBA游戏中经常提意识和大局观。这玩意比较抽象,在这里就结合古人的智慧来学习探讨一下。
知彼知己,百战不殆;不知彼而知己,一胜一负;不知彼不知己,每战必败。
《孙子兵法》谋攻篇
这可能是孙子兵法中流传最广的名句之一,也是几乎任何博弈游戏中的金科玉律。MOBA游戏也不例外,它是贯穿整个游戏始终的。下面的很多其实都是这一条的体现。刚开始玩的时候基本是不管阵容选自己擅长的英雄,平时也不看经济面板,不看小地图,看到敌人上去就是一套连招,可是有时奏效有时不奏效,全凭运气。知己知彼,首先要知已,即熟悉自己的英雄。比如被动,技能,连招,核心装备,铭文,强势期,以及衍生出的英雄特有的注意点(比如刘备贴脸伤害高,吕布最好附魔再跳大,典韦2技能踩中是关键,宫本一重势伤害高,铠打单个目标时有额外伤害,曜强化技能用同一个省CD,阿轲从背后攻击能暴击,项羽残血开大伤害高,司空震近战攻速高),怎么取消后摇等等。知彼,就是要熟悉对方英雄技能,阵容,装备,经济,打法,预判位置及操作。只有两者都了解,才能让已方立于不败之地。有些英雄你可能永远也不会去玩,但也要了解一下其技能与特点,因为你不能保证对手不会选。这样,实战中,你就可以有针对的打法,比如对方技能带控制就要捏着免疫技能,对方大招后摇时间长就要捏着位移技能躲开,对方技能CD长的话就骗出技能然后趁着空档期反打,碰到AOE伤害较高就注意走位别被一锅端 。当你知道对方核心伤害是某个技能,那就需要先引其放出并躲开再反打。
要做到知彼知己,就要时刻关注全局状态,最重要的就是其它玩家(包括队友和对方)的状态。游戏中以各种方式提供了很多信息,有些是直接的,有些是间接的。直接的比如位置,血量,等级,是否有大招,装备,属性等。通过这些信息你能大体判断最大威胁可能来自哪里,谁是可以一套秒掉的,对面的可能打法等等。全局信息的一个主要来源就是小地图。几乎所有的经验总结中都会强调要经常看小地图,因为这样才能知道大体局势。另外,看大佬玩会发现他们非常频繁地看经济面板。我们凡人也看,但可能也最多就看看人头数,谁经济高,最多再看看装备。但其实可以通过这些信息推导出其他信息。比如通过经验的动态变化信息猜测对方在做什么(比如是在蹲草埋伏,还是在打野,或是在清兵),打野是红开还是蓝开,以及之后的打法(比如出攻击装还是肉装)。只有持续关注这些信息,并且基于它进行合理推断,才能尽可能在对的时间出现在对的地方,成为制胜的关键因素。
当然,知己知彼的道理谁都知道,但是说起来容易,做起来是极难的。因为英雄多,技能和克制关系复杂,装备也多,还有相互影响,现实情况又多变,关键是游戏具有很强的实时性,很多时候没那么多时间做判断。但如果有这方面的意识,不仅能帮助提高我们的胜率,而且让我们提升得更快。
夫未战而庙算胜者,得算多也;未战而庙算不胜者,得算少也。多算胜少算,而况于无算乎!
《孙子兵法》计篇
事实上,对局从来就不是从泉水开始的,而是匹配完了点“确定”那一刻就开始了。我们知道,游戏为了平衡,每个英雄都有克制,被克制,还有搭配的英雄。这些关系官方主页列了一些,网上也有很多讨论。英雄的克制关系有一些是通用的,比如一般来说,刺客克脆皮射手,战士克刺客和法师,射手克坦克,坦克克战士,真伤英雄(如吕布、貂禅、马克波罗)克制坦克。
还有些是英雄间的天克关系。啥是天克,就像金刚狼碰到万磁王。那英雄之间的天克可能是由于一方的特点或技能可能有效限制另一方。比如马超靠攻速,而夏洛特减速;李元芳挂标记打伤害,而狄仁杰技能可以解除标记;嫦娥擅长加护盾,而伽罗打护盾加伤害;王昭君冰冻恶心,而庄周擅长解控。要是选的英雄被克制,那打起来自然会很吃力。
也就是说,在pick/ban英雄时就是博弈的开始了。这个过程中可能需要考虑的因素:
已方英雄克制对方英雄(技能上克制,类型上克制等)已方英雄避免被对方英雄克制已方英雄与队友形成搭配(英雄搭配,可以能力互补,多人连招等)禁掉对方英雄的搭配英雄已方的阵容搭配(比如是不是有前排,是不是有输出,是不是有控制,是不是都是前期或后期英雄等)自己的英雄池与战力/熟练度… 将它们作为优化问题的约束,这可以建模成一个线性规划问题。理论上,我们可能求出一个约束下的最优解。当然,现实中可能会有其它考量,因此会更复杂一些。另外,英雄之间强势期可能是不同的。有些英雄前期强势,有些后期强势。一个队伍里要尽量错开,别都整后期强制英雄,否则很可能根本撑不到后期…这个阶段如果一不注意,开局自带逆风,相当于游戏开始就选了个hard模式。
在这个阶段其实已经开始制定打法了,比如你是打野,看到对方有些后期强势的英雄,如吕布,伽罗等,前期就要想办法限制发育。再比如对方打野选个裴擒虎,云中君,再配个东皇,那就做好被反野的准备。对方有个兰陵王,那脆皮要格外小心了。对方伤害高法师多,装备可能就要考虑加个魔女斗篷,碰到回血狂就考虑加个梦魇。对方控制多,出个抵抗鞋等等。如果有蹲草老六,那路过每个草丛可都要当心点了。
然后是对局加载,这个阶段其实也很关键。以前觉得它可有可无,和一般游戏中的"Loading"界面没区别,等着就行。但其实这个阶段的信息也很关键,可以指导我们如何开局(如出装、技能打点、刷野路线、打法等)。我们知道,钻石局以下前面阶段是看不到对方选的啥英雄的,只有到这个时候才能看到。所以这时候就可以根据对方英雄推断对方的打法,并且选择自己的打法和出装。此外,它还告诉我们一些额外信息。比如熟悉度、战区排名、段位、巅峰赛排名、亲密关系等等。像我们打的低端局,就不用关注这么多了,可以瞄下双方的携带技能,熟练度及皮肤,及红蓝方:
最重要的信息是携带技能,这是可以大体推断出对面的打法的。对方对抗路带个惩戒的,野区要小心,别被偷了。另外打龙也要小心,别被半道截胡。熟练度和皮肤大体也能看出哪些是高手的概率大些(尽管也不完全准)。红蓝方会影响发育路和对抗路的方向,继而影响野怪的相对位置。比如打野的英雄如果是红蓝都可以开那种,为了优先抓对抗路(对抗路相对好抓而且有传送),就要据此选择红开或蓝开。 如果看对面出现一些吊诡的情况,比如有明显缺位(比如没人带惩戒,或者没有射手,法师),要么对方就是不走寻常路的绝顶高手,要小心了,要么就是没协调好…那就可以相应地从弱点击破。
最后,还有可能比运筹规划更重要的就是心态。很多时候我们是单排的,碰到的队友可能根本不按套路来。有时一上来就是三个射手,三个打野,又或者选个百里守约,说要打野,然后还不带惩戒,这时候可能心态就容易直接崩了。碰到这种情况,千万别崩开始摆烂。毕竟,万一对面集体掉线了呢…
记住,很多时候我们最大的敌人不是强大的对手,而是自己的心态。
故用兵之法,十则围之,五则攻之,倍则分之,敌则能战之,少则能逃之,不若则能避之。故小敌之坚,大敌之擒也。
《孙子兵法》谋攻篇
自古战争中能打赢的,其核心之一就是优势打劣势。所谓的以弱胜强,本质上其实也是局部的优势打劣势。不管三七二十一拿起板砖往前冲,惩匹夫之勇,图一时之快,这和赌没啥区别。如果是士兵这么干是害了自己,将军这么干,无异于拿士兵的命去赌。那么,现实中优势从哪来,天时、地利、人和,展开就很多了。好在游戏中没那么复杂。团战前看看英雄人数,克制关系,buff等因素是否有优势,有优势再上,没优势就先苟着。否则上去也是被团灭,对方还可能趁机把自家水晶推了。当然,但很多时候单排是没有那么多默契与配合的,有时候看大家都一股脑儿上了,只能硬着头皮上碰碰运气。
团战的优势重要来源之一就是人数,以多打少自然就会有很大的优势。网上很多一打三甚至一打五的视频,你细看的话会发现要么经济高2,3级,要么有瑶或者小明跟着,要么有红、蓝buff,要么对面根本不放技能配合演出。要是不看前提头铁往往就是瞬间蒸发。话说回来,对局双方在人数上是公平的,即5打5。那么,如何形成以多打少的有利局面呢?当然,趁对方英雄回泉水等复活时一波是一种。但很多时候如果双方有生力量相当,那就要在对方抱团时想办法分解对方。比如带线牵制,让对方分出人力运营兵线和守塔。这也呼应了后面会提到的“致人而不致于人”。另外,我们都知道支援的重要性,即不要一直呆在线上,尽量多去其他路支援。其本质也是利用了兵线空隙形成局部的以多打少。此外,我们还可以“拉拢”更多的中立力量。比如,但当对面打了龙,龙就成为了敌方的敌人。所谓敌人的敌人就是朋友。因此,有时候,可以集合在龙坑旁边的草里埋伏,趁对方打了一半时开团抢龙。这时对方可能已经在打龙时消耗了一波血量与技能,从而我方就可以利用三方力量形成优势打劣势。还有兵线是推塔时的重要帮手,没有兵线的话除非有干扰否则很难强推。因此打团前最好先清兵线,否则打赢意义也不大,打输就更惨,甚至可能打着打着莫名其妙地就输了。反过来,当已方劣势时就要想办法断对方的兵线,让对方难以推上高地。
非利不动,非得不用,非危不战。
《孙子兵法》火攻篇
前面提到,团战要优势打劣势,多数打少数,其实也是这条的体现。在单挑中也是类似的道理,比如路上碰到对方狭路相逢1vs1,可不总是勇者胜。在冲上去前最好先看看英雄是不是被克制,等级是不是比你高,装备是不是比你好,有没有支援,血量是否健康,自己与对方是否有技能。比如你看到残血程咬金就上,结果打得差不多了人家回半管血,就很绝望。再比如蹲草,好不容易蹲来了人,结果上去了却被对方反打一套带走,就很尴尬了。
是故胜兵先胜后求战,败兵先战而后求胜。
《孙子兵法》形篇
这些都体现了孙子兵法中非常重要的思想,即“先胜而后战”。输赢,其实在打之前就很大程度上已经确定了。游戏中,无论是单挑还是团战都先计算权衡下,如果没有胜算的话撤退也是一种重要的策略。因此,书中还提到:
善战者,无智名,无勇功。
《孙子兵法》形篇
大家都喜欢一些险中求胜,绝地求生的情节,因此这些故事通常更容易被广为流传,为人所津津乐道。但《孙子兵法》告诉我们如果你战前已算出胜局,一切都是按照计划一步一步走下来,自然就不太会有太多惊险刺激的事发生。就好像大家都听说过孙武与《孙子兵法》,但很少有人知道他的著名战役,可能他练兵杀宠妃的故事都还要更有名一些…
昔之善战者,先为不可胜,以待敌之可胜。不可胜在已,可胜在敌。
《孙子兵法》 形篇
孙子提出的一个很重要的观点就是“胜可知不可为”,即善战者只能使自己不被战胜,但无法使敌人一定被打败。因为这事它不能强求,只能看敌人是否自己露出破绽。战国四大名将之一的赵国将领李牧,十年坚守不出,等匈奴放松警惕,大军来犯之时,果断出击突袭包夹,全奸匈奴主力,而后匈奴十年不敢来犯。这里难的不是“打”,而是“不打”,是能看出敌人破绽,知道何时该打。十年时间里,赵王曾觉得这样缩着不合适,因此将李牧换下,换上的新将军出击,结果大败。于是李牧又被请了回来,才有了后边的事。想象一下,十年坚守一定会面临巨大的压力,老大觉得是在划水摸鱼都是轻的,万一怀疑你通敌叛国那就凉凉了。
游戏中,我们知道前期掉点对节奏的影响比较大,不仅影响发育,而且可能导致塔被推掉,继而丢掉野区控制权。因此,前期要稳一些,要做到“先为不可胜”。可能所以新玩家常犯的错误就是打着打着上头,看到残血,不管三七二十一就是拿着冻鱼追一路,不拿人头绝不放弃。直到对面窜出个人支援,多人夹击把自己送回泉水。
看过专业比赛,可能会惊讶于比赛中击杀数如此之少。可能打到十分钟了,两边加起来才几个人头。直到水晶爆了加起来才十几个人头。要是在低端局,打完了一局人头数加起来少说也几十个,甚至半百了。单挑时拉扯也是一样的道理。这和拳击时类似,除非有绝对优势,否则你不太会看到拳击手一上去就猛攻的。一般都是边绕边试探,直到抓住对手破绽就是闪现开大。当然,对方也可能是故意露假破绽骗你攻击让你露破绽。因此,高手出手前都会等对方的破绽,或者用假破绽骗出对方的真破绽。那如果没有破绽怎么办呢?答案是不可能。即使是专业比赛也会有破绽,何况路人局。很多时候可能静候时机就是最好的选择。
但是知易行难,要做到其实非常非常难。不仅是因为人性中贪功冒进的弱点,还有一些外在因素都在无时不刻影响着玩家,比如评分和音频。一局完了会给个KDA,而影响它的主要因素之一是人头数。这让玩家不自觉地要多拿人头,从而偏离主要目标。要记住王者本质上是推搭游戏,场场败方MVP也只能反向冲分。另外王者中的音频可不是随便播放的,而是经过精心设计的(腾讯天美GDC分享:《王者荣耀》8年音频设计回顾)。适时激昂的背景音乐,还有“first blood”,“double kill”,“决战开始”等等语音,都会隐式地提升玩家的紧张感,让人上头,从而影响打法。这和商场里通过背景音乐影响消费者心理,从而间接影响行为是类似的。
兵者,诡道也。故能而示之不能,用而示之不用,近而示之远,远而示之近。利而诱之,乱而取之,实而备之,强而避之,怒而挠之,卑而骄之,佚而劳之,亲而离之,攻其无备,出其不意。
《孙子兵法》计篇
孙子提出“兵以诈立”,而这是对兵不厌诈具体操作的高度概括总结。游戏中也有不少体现,比较典型如实则虚之在配合打野抓人上的应用。比如对抗路或射手看到队友来抓人,就示弱一下往回撤,一般对方经验不多或者打上头了的话会上钩。但如果对面之前已经栽过几次跟头,知道在一些关键时间节点(像1分半)就会特别小心。更谨慎些的,对面看到中、野、辅不露视野,便不会冒进。这时候就考验演技了,比如乱放个技能,让对方觉得是纯萌新或者练英雄的。别明明有线权,血量比别人多,还嘤嘤嘤的往回跑,别人傻子才会上当…
故智将务食于敌.食敌一钟,当吾二十钟;萁杆一石,当吾二十石。
《孙子兵法》作战篇
游戏中的战争与现实中的是类似的。表面上是干架,其实是拼经济。所谓的战术、技巧那也是在经济差不多的前提下才讲的。无论是RTS还是MOBA游戏,经济差太多的话,哪怕英雄或兵种被克制,那打起来也是砍瓜切菜。蒙古大军席卷欧亚大陆,很大程度上也是因为人家对补给没那么依赖。尤其是冷兵器时代,其它先不说,光是大军所耗费的粮食就是个很大的决定性因素。军队断粮那基本就意味着凉了。战线过长的话,送粮成本会极大增加,因为送粮的人本身也要吃粮,而且还得来回,路上还可以被截。带20份粮食,真正送到前线士兵的可能就1份。虽然感性上也知道补给耗费大,但第一次看到这个估计数据时还是有些吃惊的…因此孙武提出要“取用于国,因粮于敌”。食敌一钟,当吾二十钟。
游戏中的经济非常重要,经济差个几千团战就很难打了。等级差个1级单挑就容易被压制,要是等级高个2,3级经常可以冲到对方人堆里乱打(所以有“养猪流”这种打法)。因此,提升经济几乎是前中期最重要的事,可以说没有之一。在保证安全的前提下,对方的野怪和中立资源的优先级要比已方更高。如果团战赢了,但兵线还没到,强行推搭感觉没把握就先把对面野区刷了,也算是“因粮于敌”了。因为如果各刷各的野区,顶多也就经验五五开,而如果刷了对方野区,意味着已方多一份,对方少一份,这样经济优势就一下子出来了。如此一来,就可以有效地累积优势,从而滚起雪球。这时对面人员就算全复活了也会被压着。另外,抓人或者单杀这种事有自然最好,没有的话也别强求。一个人头还不如一波兵线,但难度和风险却显著高于后者。所以不要捡了芝麻丢了西瓜。
善守者,藏于九地之下,善攻者,动于九天之上。
《孙子兵法》军形篇
有人说视野是游戏中最重要的东西之一,有一定的道理。敌在明我在暗,自然就有了主动权和优势。因此藏视野就显得很重要了。即使没有成功奇袭,让对方看不到我们,也不敢轻举妄动。
游戏中视野范围是对等的,也就是说,近距离范围内如果就只有自己和敌方时,一般情况下自己能看到对方时,对方也能看到我。但这样就没有优势可言。那要做到我能看到对方,但对方看不到我,就需要藏视野。一种方法是利用一些英雄的特殊技能,如百里,兰陵王,阿轲。但这种方法不够通用。另一种是利用友军,如队友或者兵线的视野。因为友军视野是共享的,所以能做到在对方看不到我的情况下看到对面。这在抓人的时候需要利用。还有一种最常用的方法就是利用草丛。王者里再小的草丛也是能蹲五个大汉的。在对方必经之路上蹲草埋伏,适时出击,那对于对方来说可就是神兵天降,可能会被打个措手不及。埋伏也不一定要力求带走对方,有时打掉对方状态就行。这样让对方补状态不敢冒进,同时让对方以后走过每个草丛都小心翼翼,要浪费个技能探草或者绕着走多花些时间,效果就达到了。
另一方面,考虑到对面也会蹲草,那除了比较肉的坦克或者辅助可以脸探草,其他人可能在没有对方视野的情况下路过一些容易埋伏的草丛时就要用技能(有些英雄技能或者被动可用于探草,像小鲁班,后羿,狄仁杰,铠,猴子,关羽等)或者装备(回响,日暮,形昭等)探个草。
军行有险阻、潢井、葭苇、山林、蘙荟者,必谨覆索之,此伏奸之所处也。
《孙子兵法》行军篇
已方会蹲草,对方自然也会蹲。因此路过一些高危地带要小心,觉得有人蹲的话用技能或者装备探个草。辅助或者坦克也可以适时帮忙探个草,避免C位一套被秒。
故善动敌者,形之,敌必从之,以利动之,以卒待之。
《孙子兵法》势篇
同时,埋伏的时机和位置也很重要。因为如果埋伏半天对方不来,蹲了个寂寞反倒使自己错过发育时机,那就偷鸡不成蚀把米了。这时候就需要调动敌人了。
一些对局中经常看到英雄脱战后先往一个方向走,再往另一个方向走,这便是为了给对方造成假视野。比如让对方认为你走上路,但其实你走下路,或是认为你走了,其实你折返了。这样可以迷惑对方,从而让对方做出错误的判断。
故善战者,致人而不致于人。能使敌人自至者,利之也;能使敌人不得至者,害之也。
《孙子兵法》虚实篇
0. My Conclusion CoWs on PASTURE: 擅长零样本的视觉语言对象导航,主要解决了LLM辅助下的任务级动作执行任务VoxPoser: 擅长设计一些未预定义的动作轨迹,主要解决了LLM辅助下的动作轨迹设计任务Relational Pose Diffusion:擅长将已有的动作迁移变换到新场景下的动作,增强机械臂的泛化能力,主要解决了Diff模型辅助下的复杂多变的场景动作轨迹适应能力的任务 1. 牧场中的奶牛:语言驱动的零样本对象导航的基线和基准 Samir Yitzhak Gadre Mitchell Wortsmany Gabriel Ilharcoy Ludwig Schmidty Shuran Song
(2022-12-14) CoWs on PASTURE: Baselines and Benchmarks for Language-Driven Zero-Shot Object Navigation
(0) 摘要 为了使机器人普遍有用,即使没有对域内数据进行昂贵的导航训练(即执行零样本推理),它们也必须能够找到人们描述的任意对象(即由语言驱动)。
我们在统一的环境中探索这些功能:语言驱动的零样本对象导航(L-ZSON)。受到图像分类开放词汇模型最近成功的启发,我们研究了一个简单的框架,CLIP on Wheels (CoW),使开放词汇模型无需微调即可适应此任务。为了更好地评估 L-ZSON,我们引入了 PASTURE 基准,该基准考虑寻找不常见的对象、由空间和外观属性描述的对象以及相对于可见对象描述的隐藏对象。我们通过直接在 HABITAT、ROBOTHOR 和 PASTURE 中部署 21 个 CoW 基线来进行深入的实证研究。总的来说,我们评估了超过 90k 的导航片段,发现 (1) CoW 基线经常难以利用语言描述,但擅长查找不常见的对象。 (2) 一个简单的 CoW,具有基于 CLIP 的对象定位和经典探索,无需额外的训练,与在 HABITAT MP3D 数据上训练 5 亿步的最先进的 ZSON 方法的导航效率相匹配。与最先进的 ROBOTHOR ZSON 模型相比,同一 CoW 的成功率提高了 15.
😊 @ 作者: Eric
💖 @ 主页: https://blog.csdn.net/weixin_47316183?type=blog
🎉 @ 主题:CentOS7安装JDK8(实操版 | 源码安装和yum安装)
⏱️ @ 创作时间: 2023年08月04日
该文章纪录的是CentOS安装JDK操作,每一步都有记录,争取每一位看该文章的小伙伴都能操作成功~
方式一:yum安装 1、yum方式比较简单,一个命令就能搞定
yum install java-1.8.0-openjdk* -y 安装目录为:/usr/lib/jvm/java-1.8.0-openjdk
2、验证是否安装成功过
java -version 输出以下内容则表示安装配置完成:
openjdk version "1.8.0_222" OpenJDK Runtime Environment (build 1.8.0_222-b10) OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode) 方式二:源码安装 jdk源码获取链接:https://pan.baidu.com/s/1SyUyllG9bieMcwytrc4AXA?pwd=Eric 提取码:Eric
第一步:先上传JDK到CentOS系统中(我这里放到:usr/local 目录下)
第二步:解压安装包 # 切换目录 cd /usr/local # 解压文件 tar -zxvf jdk-8u351-linux-i586.tar.gz 第三步:建立软连接
ln -s /usr/local/jdk1.8.0_351/ /usr/local/jdk 第四步:修改环境变量
vim /etc/profile 在最下面加上以下配置
针对近期学习内容进行整理,按照车联网、AutoSAR、SOME/IP、DoIP/UDS、时间同步、MQTT、4G/5G通信协议 进行如下分类。
(更多车载软件开发领域的总结文档,在W信"坐看云起会有时"里发布,欢迎一起学习交流。)
车联网:
《YD∕T 3707-2020 基于LTE的车联网无线通信技术网络层技术要求》
《智能网联汽车测试监管系统第1部》
《智能网联汽车测试监管系统 第2部分》
《智能网联汽车测试监管系统 第3部分》
《新能源汽车GB32960报文解析工具》
《专用短程通讯DSRC介绍》
《T-Box 功能说明》
《GB-T-32960国标重点解读 - 总则》
《GB-T-32960国标重点解读 - 车载终端》
《GB-T-32960国标重点解读 - 通信协议及数据格式》
《新能源车国家标准符合性检测的梳理》
《车联网、自动驾驶、开发流程等方面的缩写》
《车联网OTA安全实践》
《算法相关的杂烩》
《车联网 1 简介》
《车联网 2 技术路线选择》
《车联网 3 C-V2X》
《车联网 4 专用短程通讯DSRC介绍》
《车联网 5 CV2X缩写》
《车联网 6 5G车联网车载设备》
《车联网 7 CSAE V2X应用层MAP消息解读》
《报告分享 - 华为鸿蒙座舱》
《CAN周期波动优化方法》
《一文入门CAN协议》
AutoSAR:
《初识AutoSAR架构》
《AutoSAR 通信服务》
《AUTOSAR架构概览》
《AUTOSAR 信息安全框架和关键技术分析》
《ETAS实战:手动添加基于Can的通讯信息》
《AUTOSAR之分层架构(1)》
《AUTOSAR SWC学习笔记》
《车载开发涉及的缩写》
《关于AutoSAR学习的疑问》
如何实现CAN-SOME/IP通信路由测试 (qq.com)
AutoSAR SOMEIP与SOC vsomeip通讯 (qq.com)
利用commonAPI和vSomeip对数据进行序列化 (qq.com)
Vector - CANoe - VCDL与SomeIP (qq.com)
使用Wireshark 查看SOMEIP的方法 (qq.com)
基于AutoSAR的车载以太网测试 - SOMEIP之ECU做为服务消费者 (qq.com)
基于AutoSAR的车载以太网测试 - SOMEIP之服务提供者 (qq.com)
如果无法打开以下链接,请联系个人weixin"坐看云起会有时",包含很多近期对车载软件开发领域的学习内容进行总结,如 车联网、AutoSAR、SOME/IP、DoIP/UDS、时间同步、MQTT、4G/5G通信协议 等。
AutoSAR 系列的文档:
AUTOSAR基础篇之EcuM
AUTOSAR基础篇之EcuM
AUTOSAR基础篇之OS(上)
AUTOSAR基础篇之OS(上)
AUTOSAR基础篇之OS(下)
AUTOSAR基础篇之OS(下)
AUTOSAR基础篇之BswM
AUTOSAR基础篇之BswM
AUTOSAR基础篇之StbM
AUTOSAR基础篇之StbM
AUTOSAR基础篇之FiM
AUTOSAR基础篇之FiM
AutoSAR之基础篇CanNM
AutoSAR之基础篇CanNM
AUTOSAR基础篇之CanTsyn
AUTOSAR基础篇之CanTsyn
AUTOSAR基础篇之DTC
AUTOSAR基础篇之DTC
符合AUTOSAR标准的RTA-OS --Task详解
符合AUTOSAR标准的RTA-OS --Task详解
Autosar Os 入门介绍
Autosar Os 入门介绍
从手写代码到AUTOSAR工具链 - RTE入门篇
从手写代码到AUTOSAR工具链 - RTE入门篇
从手写代码到AUTOSAR工具链_EcuM应用篇
从手写代码到AUTOSAR工具链_EcuM应用篇
从手写代码到AUTOSAR工具链-BswM应用篇
从手写代码到AUTOSAR工具链-BswM应用篇
从手写代码到AUTOSAR工具链_MCAL应用篇
从手写代码到AUTOSAR工具链_MCAL应用篇
车载以太网基础篇之Ethernet Driver
车载以太网基础篇之Ethernet Driver
车载以太网基础篇之EthIf
车载以太网基础篇之EthIf
车载以太网网络管理之UdpNm
车载以太网网络管理之UdpNm
AutoSAR CP的DoIP模块的IP地址分配方式
AutoSAR CP的DoIP模块的IP地址分配方式
AutoSAR CP模块EthIf的EthIfFrameType参数
AutoSAR CP模块EthIf的EthIfFrameType参数
AutoSAR CP里EthTSyn模块的参数EthTSynTimeValidationEnable 的作用
AutoSAR CP里EthTSyn模块的参数EthTSynTimeValidationEnable 的作用
AutoSAR CP 模块BswM - 设计理解
启动: systemctl start firewalld关闭: systemctl stop firewalld查看状态: systemctl status firewalld开机禁用 : systemctl disable firewalld开机启用 : systemctl enable firewalld 重新加载配置 firewall-cmd --reload 重启防火墙 service firewalld restart 查看已经开放的端口 firewall-cmd --list-ports 关闭已开放的端口,以80端口为例 firewall-cmd --permanent --remove-port=80/tcp 批量开放80到90之间的所有端口 firewall-cmd --zone=public --add-port=80-90/tcp --permanent 批量关闭80到90之间的端口 firewall-cmd --permanent --remove-port=80-90/tcp --remove-port=80-90/tcp 限制单个ip,限制192.168.1.100这个ip访问80端口 firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.0.200' port protocol='tcp' port='80' reject" 批量限制ip,限制192.168.3.x的所有ip访问80端口 firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.3.0/24' port protocol='tcp' port='80' reject" 允许单个ip访问80端口 firewall-cmd --permanent --remove-rich-rule="rule family='ipv4' source address='192.
智能优化算法改进算法
摘要:为了方便大家对智能优化算法进行改进,复现多种智能优化改进算法供大家参考。所有代码均根据已经发表的文章,来复现方便大家参考别人的原理,代码会不定时更新。
1.文献复现:基于变因子加权学习与邻代维度交叉策略的改进乌鸦算法Matlab代码
[1]赵世杰,高雷阜,于冬梅,徒君.基于变因子加权学习与邻代维度交叉策略的改进CSA算法[J].电子学报,2019,47(01)**:40-48.
2.文献复现:自适应t 分布变异的缎蓝园丁鸟优化算法 Matlab代码
[1] 韩斐斐,刘升.基于自适应t分布变异的缎蓝园丁鸟优化算法[J].微电子学与计算机,2018,35(08)**:117-121
3.文献复现:混沌麻雀搜索优化算法 matlab 代码
[1]吕鑫,慕晓冬,张钧,王震.混沌麻雀搜索优化算法[J/OL].北京航空航天大学学报:1-10[2020-11-16].https://doi.org/10.13700/j.bh.1001-5965.2020.0298.
4.文献复现:非均匀变异的互利自适应缎蓝园丁鸟优化算法Matlab代码
[1]王依柔,张达敏,樊英.非均匀变异的互利自适应缎蓝园丁鸟优化算法[J/OL].计算机工程与科学:1-10[2020-11-23].http://kns.cnki.net/kcms/detail/43.1258.TP.20200803.1202.004.html
5.文献复现:基于自适应权重的缎蓝园丁鸟优化算法 Matlab代码
[1]鲁晓艺,刘升,韩斐斐,于建芳.基于自适应权重的缎蓝园丁鸟优化算法[J].智能计算机与应用,2018,8(06)**:94-100
6.文献复现:多段扰动共享型乌鸦算法 matlab代码
辛梓芸,张达敏,陈忠云,张绘娟,闫威.多段扰动的共享型乌鸦算法[J].计算机工程与应用,2020,56(02)**:55-61
7.文献复现:正弦余弦指引的乌鸦搜索算法 Matlab 代码
[1]肖子雅,刘升,韩斐斐,于建芳.正弦余弦指引的乌鸦搜索算法研究[J].计算机工程与应用,2019,55(21)**:52-59.
8.文献复现:多子群的共生非均匀高斯变异樽海鞘群算法Matlab代码
[1]陈忠云,张达敏,辛梓芸.多子群的共生非均匀高斯变异樽海鞘群算法[J/OL].自动化学报:1-9[2020-11-25].https://doi.org/10.16383/j.aas.c190684.
9.文献复现:疯狂自适应的樽海鞘算法 Matlab代码
[1]张达敏,陈忠云,辛梓芸,张绘娟,闫威.基于疯狂自适应的樽海鞘群算法[J].控制与决策,2020,35(09)**:2112-2120.
10.文献复现:正余弦算法的樽海鞘算法 Matlab代码
[1]陈忠云,张达敏,辛梓芸.正弦余弦算法的樽海鞘群算法[J].计算机应用与软件,2020,37(09)**:209-214.
11. 文献复现:自学习策略和Levy飞行的正弦余弦优化算法 Matlab代码
[1]李银通,韩统,赵辉,王骁飞.自学习策略和Lévy飞行的正弦余弦优化算法[J].重庆大学学报,2019,42(09)**:56-66.
12.文献复现:融合柯西变异和反向学习的改进麻雀算法 Matlab代码
[1]毛清华,张强.融合柯西变异和反向学习的改进麻雀算法[J/OL].计算机科学与探索:1-12[2020-12-16].http://kns.cnki.net/kcms/detail/11.5602.tp.20201203.1601.006.html
13.文献复现:扇区搜索机制的果蝇优化算法 Matlab代码
[1]曹珍贯,李智威,余俊峰.扇区搜索机制的果蝇优化算法 [J].计算机工程与设计,2019,40(06)**:1590-1594.
14.文献复现:一种基于Levy飞行的改进蝗虫优化算法 Matlab代码
[1]赵然,郭志川,朱小勇.一种基于Levy飞行的改进蝗虫优化算法[J].计算机与现代化,2020(01)**:104-110.
15.文献复现:基于曲线自适应和模拟退火的蝗虫优化算法 Matlab代码
[1]李洋州,顾磊.基于曲线自适应和模拟退火的蝗虫优化算法[J].计算机应用研究,2019,36(12)**:3637-3643.
16.文献复现:混合柯西变异和均匀分布的蝗虫优化算法 Matlab代码
[1]何庆,林杰,徐航.混合柯西变异和均匀分布的蝗虫优化算法[J/OL].控制与决策:1-10[2021-01-08].https://doi.org/10.13195/j.kzyjc.2019.1609.
17.文献复现:基于模拟退火的改进鸡群优化算法(SAICSO) Matlab代码**
[1]李振璧,王康,姜媛媛.基于模拟退火的改进鸡群优化算法[J].微电子学与计算机,2017,34(02)**:30-33+38.
18.文献复现:一种改进的鸡群算法(ICSO) Matlab代码**
[1]孔飞,吴定会.一种改进的鸡群算法[J].江南大学学报(自然科学版),2015,14(06):681-688.
19.文献复现:全局优化的改进鸡群算法(ECSO) Matlab代码**
[1]韩斐斐,赵齐辉,杜兆宏,刘升.全局优化的改进鸡群算法[J].计算机应用研究,2019,36(08)**:2317-2319+2327.
20.文献复现:混沌精英哈里斯鹰优化算法(CEHHO) Matlab代码**
[1]汤安迪,韩统,徐登武,谢磊.混沌精英哈里斯鹰优化算法[J/OL].计算机应用:1-10[2021-01-29].http://kns.cnki.net/kcms/detail/51.1307.TP.20210114.0947.032.html.
21.文献复现:基于翻筋斗觅食策略的灰狼优化算法(DSFGWO)Matlab代码
[1]王正通,程凤芹,尤文,李双.基于翻筋斗觅食策略的灰狼优化算法[J/OL].计算机应用研究:1-5[2021-02-01].https://doi.org/10.19734/j.issn.1001-3695.2020.04.0102.
22.文献复现:基于透镜成像学习策略的灰狼优化算法(LIS-GWO)Matlab代码
[1]龙文,伍铁斌,唐明珠,徐明,蔡绍洪.基于透镜成像学习策略的灰狼优化算法[J].自动化学报,2020,46(10)**:2148-2164.
一、安装Vant 1、在 资源管理器 空白位置,点右键打开 在外部终端窗口打开
2、初始化NPM
npm init -y
3、安装命令
npm i @vant/weapp@1.3.3 -S --production
4、构建NPM包
在 工具 里选择构建NPM包
5、删除style:v2
在app.json里,删除"style":"v2"
6、按需引入
// app.json "usingComponents": { "van-button": "@vant/weapp/button/index" } 7、使用
<van-button type="primary">按钮</van-button> 二、CSS自定义样式 1、定义
element { --main-bg-color: brown; } :root { --main-bg-color: brown; } 2、使用
element { background-color: var(--main-bg-color: brown); } 三、自定义TabBar 1、配置
在app.json中的 tabBar 配置中加上 "custom": true, 表示要自定义,不再使用list
为了兼容低版本,list虽然作废,但是也不能删
"tabBar": { "custom": true, "list": [ { .... 2、新建自定义文件
第十一关:Reflected Cross Site Scripting (XSS) low 这一关没有任何防护,直接输入弹窗
<script>alert('xss')</script>
打开网页源代码, 从源代码中我们可以看到,前面是输出的第一部分Hello,我们输入的脚本被成功解析执行,所以出现了弹窗
medium 查看源码,发现对<script>进行了过滤,把<script>替换成空,但是其实还是不够安全
构造payload 双写绕过 <scr<script>ipt>alert("xss")</script>
或者大小写绕过<ScrIpt>alert("xss")</script>
high 查看源码,/i是大小写通用,只要出现script的都会被替换掉
所以我们要使用别的语句来替换含script的脚本
我们可以用图片插入语句
<img src =1 onerror = alert("xss")>
impossible 可以看出多了user_token和session_token,这是防csrf的,因为经常是xss+csrf结合攻击,然后他对我们输入的内容用htmlspecialchars() 函数进行处理
htmlspecialchars() 函数的定义和用法,类似于转义
目录 一、Kubeadm搭建K8S1.1环境准备1.2所有节点安装docker1.3所有节点安装kubeadm,kubelet和kubectl1.4部署K8S集群1.5所有节点部署网络插件flannel 二、部署 Dashboard 一、Kubeadm搭建K8S 1.1环境准备 服务器IP配置master(2C/4G,cpu核心数要求大于2)192.168.243.107docker、kubeadm、kubelet、kubectl、flannelnode01(2C/2G)192.168.243.108docker、kubeadm、kubelet、kubectl、flannelnode02(2C/2G)192.168.243.109docker、kubeadm、kubelet、kubectl、flannelmaster02192.168.243.110docker、kubeadm、kubelet、kubectl、flannel //修改主机名 hostnamectl set-hostname master01 hostnamectl set-hostname node01 hostnamectl set-hostname node02 //所有节点修改hosts文件 vim /etc/hosts 192.168.80.10 master01 192.168.80.11 node01 192.168.80.12 node02 //调整内核参数 cat > /etc/sysctl.d/kubernetes.conf << EOF #开启网桥模式,可将网桥的流量传递给iptables链 net.bridge.bridge-nf-call-ip6tables=1 net.bridge.bridge-nf-call-iptables=1 #关闭ipv6协议 net.ipv6.conf.all.disable_ipv6=1 net.ipv4.ip_forward=1 EOF //生效参数 sysctl --system 1.2所有节点安装docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce docker-ce-cli containerd.io mkdir /etc/docker cat > /etc/docker/daemon.json <<EOF { "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"], "exec-opts": ["native.cgroupdriver=systemd"], "
重新学习这两个API的起因 在本周五有线上的项目,16:30开始验证线上环境。 开始都是顺顺利利,一帆风顺。 大概17:50左右,我正在收拾东西。 准备下班去王者峡谷骑着我的船溜达一圈。 可是天降意外,给我派了一个bug。 测试给我说:有一条数据的详情页有数据但是在页面中没有显示数据。 不可能,绝对不可能。当时我信誓旦旦的。蛮自信。 当时怀疑是这条数据本身就没有详细数据。用户还没有补充详情。 但是测试给我发了一张图片。 我看见控制台出现红色的 Uncaught SyntaxError 映入我的眼球,感觉就像在向我宣战: 此时我虚了,感觉十有八九就是一个bug。 后来经过排查,发现是 JSON.string()引起的。 故而,今天周六简单记录一下 JSON.string它并不是我们想的那样简单。 大家对 JSON.string() 的第一印象是什么? 我现在依稀记得: JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串。 其他的就没有什么特别的印象。 其实,它在对不同类型数据处理时,会做出不同的反应。 下面坐好我在峡谷买的船,一起来看一下。 JSON.string()转换的值中有 toJSON() 方法,那么返回值直接替代当前这个对象 var obj = { name:'小魔神', like:'喜欢和乌鸦说话', toJSON: function () { return '活下去'; } }; var newStr = JSON.stringify(obj); console.log(newStr); 此时,你认为输出的值是什么? 认真考虑10s。是什么? 最后会输出 '活下去' 是不是很意外,是不是很惊喜。竟然是这个结果。 这的是我们都没有想到对吧? 子所以这这个结果: 因为:obj这个对象中有 toJSON()方法。 那么这个方法的返回值将会替代当前这个对象。所以是 '活下去' 有 toJSON() 方法没有返回值会怎么样? 有的小伙伴这个时候就在想了。 你说的是因为转换中有 toJSON()方法并且有返回值(retuen)才会替代当前的对象。 如果有 toJSON()方法但是没有返回值是不是就不会替换当前这个对象了呢? 于是我们写下了这样的代码 let obj = { name: '小魔神', like: '喜欢和乌鸦说话', toJSON: function() { console.
目录
摘要
2.1 问题 1 的问题分析
2.2 问题 2 的问题分析
2.3 问题 3 的问题分析
完成版论文见此
摘要 问题一,我们使用了390名3至12个月婴儿及其母亲的相关数据,探讨了母亲的
身体和心理指标对婴儿的行为特征和睡眠质量的影响。我们首先进行了描述性统计分析,
通过绘制母亲年龄、教育程度、妊娠时间、整晚睡眠时间以及入睡方式等的分布图来了
解数据的概括特征。然后,通过One-Hot编码处理婴儿行为特征和入睡方式,我们使用 随机森林模型来评估母亲的身体指标(如年龄、婚姻状况、教育程度等)和心理指标(如
CBTS、EPDS、HADS等)与婴儿的睡眠质量之间的关系。结果显示,母亲的心理健康
状态确实与婴儿的睡眠质量有显著关联,特别是母亲的抑郁和焦虑症状与婴儿的睡眠质
量负相关。此外,母亲的教育程度和婴儿的入睡方式也与婴儿的睡眠质量有一定关系。
这些发现强调了母亲心理健康对婴儿发展的重要性,也为未来的干预策略提供了依据。
问题二,从数据预处理到特征工程,再到模型的建立与求解。目标是基于给定的特
征预测目标变量。在数据加载与检查阶段,我们加载了数据并进行了基本的检查和概览。
数据预处理阶段包括了对类别变量的编码、处理缺失值以及数据规范化。特征工程阶段
对数值特征进行了缩放以满足模型的需求。模型建立与求解阶段,我们尝试了逻辑回归、
支持向量机、k-最近邻、梯度提升树等基础模型,以及随机森林、Adaboost、XGBoost 等 集成模型,并对随机森林模型进行了 GridSearch 超参数优化。在尝试的多个模型中, 逻辑回归表现最佳,准确率约为 64.10%。我们还通过各种图表和可视化方法深入了解
了数据分布和模型性能。
问题3,主要探讨了如何通过数学建模和优化技术来评估将婴儿的行为特征从矛盾
型改变为中等型或安静型所需的最小治疗费用。首先,我们从提供的数据集中提取了相
关特征。然后,我们使用线性插值模型来建立治疗费用与患病得分(例如CBTS、EPDS
和HADS得分)之间的关系。接下来,我们构建了线性规划模型,以最小化治疗费用,
同时确保达到目标得分,例如中等型或安静型婴儿的平均得分。
问题4首先要对婴儿的睡眠质量进行优、良、中、差四个等级的综合评判。评估基
于三个关键因素:整晚睡眠时间、睡醒次数和入睡方式。整晚睡眠时间以分钟为单位进
行分析,根据不同的时间区间赋予分值。睡醒次数根据醒来的次数赋予分值,反映睡眠
的连续性。入睡方式则根据入睡的舒适度和有效性赋予分值,包括五个级别,如哄睡法、
抚触法等。通过结合这些因素,我们计算了每个样本的总评分,并根据总评分将睡眠质
量分为四个等级。针对处理好的数据进行缺失值处理等手段进行数据完整性的检查,并
进行有序编码。然后,针对数据运用XGBoost进行特征的筛选,删除无用的特征。随 后构建了一个堆叠融合分类模型来预测睡眠质量评级。使用了随机森林、支持向量机和
梯度提升机作为基本分类器,并通过网格搜索找到了最佳参数组合。模型在测试集上的
准确度为91.54%。我们还绘制了各个模型的ROC曲线和混淆矩阵,并使用训练好的模
型对新的特征值进行了预测。
2.1 问题 1 的问题分析 在本研究中,我们关注的问题是母亲的身体和心理指标如何影响婴儿的行为特征和
睡眠质量。通过分析来自390名3至12个月婴儿及其母亲的数据,我们旨在揭示母亲
的年龄、婚姻状况、教育程度、妊娠时间、分娩方式、心理健康状态等与婴儿的睡眠质
量和行为特征之间的潜在关系。
问题分析必须考虑以下几个方面:
(1) 数据理解:我们需要了解数据的结构和内容,包括各种指标的意义和可能的关联,
以确定分析的方向和方法。
(2) 特征处理:由于数据包括数值和分类特征,我们需要考虑如何处理这些特征,例如
使用 One-Hot 编码来转换分类特征。 (3) 模型选择:选择合适的模型是关键。在本案例中,随机森林模型被选为合适的算法,
Kibana 运维 ElasticSearch 与之对应的Java Api
基础使用 Insert 创建索引库, 并设定 分片数量 和 副本数量 // 格式: PUT /索引库名称 PUT /xinmeng { "settings": { # 设定分片数量 "number_of_shards": 3, # 设定副本数量 "number_of_replicas": 3 } } 给指定的索引库创建映射 // 给指定索引库的映射树添加映射字段 PUT /xinmeng/_mapping { "properties":{ "color": { "type": "keyword" } } } Delete 删除指定的索引库(普通删除) // 格式: DELETE /索引库名称 DELETE /xinmeng Search 查看指定索引库的映射树 // 格式: GET /索引库名称/_mapping GET /xinmeng/_mapping Close / Open 索引库 // 格式: POST /索引库名称/_close POST /xinmeng/_close // 格式: POST /索引库名称/_close POST /xinmeng/_open 文档相关操作 Insert 添加文档, 指定文档id /* 新增索引库数据: POST /索引库名称/文档名称 { "
目录
目录
一、定义
二、声明方式
三、使用
3.1用指针的方式
3.2用宏定义的方式
四、printf的实现
一、定义 一般函数的参数列表是固定的,所以在调用时传入的实参的个数和格式必须和实参匹配;在函数式中,不需要关心实参,直接调用形参即可。
变参函数,就是参数的个数及类型都不确定的函数,常见变参函数如printf、scanf。因为传入的参数列表是不确定的,所以在函数实现时要对传入的参数的个数以及类型进行判断乃至处理。
二、声明方式 声明方式:返回值 函数名(第一个参数, ...);
注:声明或定义变参函数时,第一个参数必须要有,其主要作用是明确到底有多少个参数,以及参数类型,后面的参数用“...”代替。
三、使用 3.1用指针的方式 很多教材以及网上给出的示例代码:
void print_num(int count, ...) { int *args; args = &count + 1; for( int i = 0; i < count; i++) { printf("*args: %d\n", *args); args++; } } int main(void) { print_num(5,1,2,3,4,5); return 0; } 这是有问题的!
运行结果:
打印出来的结果是混乱的。
函数实现思路是定义一个变参函数print_num,在函数内部先取得第一个参数的地址赋值给一指针,然后将指针后移,取得后面的参数并打印出来。
错误原因:
1.指针在64位系统中大小为8byte,示例代码中的“args++;”偏移的是一个int数据类型的大小,即4byte。
2.第一个参数和第二个该参数之间的距离为28byte。通过“gcc -S 源文件”命令,生成后缀为“.s”的汇编代码文件,在汇编文件中找到的这个信息,具体原因我也还不知道。
从上图可以看到在函数print_num中,第一个参数位置为196,第二个参数位置为168,二者之间相差28byte。从第二个参数开始,后续参数之间的距离为8byte。
关于这个示例代码的错误,这篇文章很有参考价值:https://www.cnblogs.com/lularible/p/15129183.html
正确代码:
void print_num(int count, .
目录
前言
一:负载均衡概述
二:为啥负载均衡服务器这么快呢?
编辑
2.1 七层应用程序慢的原因
2.2 四层负载均衡器LVS快的原因
三:LVS负载均衡器的三种模式
3.1 NAT模式
3.1.1 什么是NAT模式
3.1.2 NAT模式实现LVS的缺点
3.1.3 NAT模式的注意事项
3.2 DR模式 3.2.1 什么是MAC欺骗?
3.2.2 为什么Real Server需要处于同一个局域网内?
3.2.3 如何实现VIP的对内可见,对外隐藏
3.2.4 为什么DR模式要快
3.3 TUN隧道模式
3.3.1 实现原理
3.3.2 优缺点
四:Real Server调度算法 4.1 如何监控每台Real Server的负载情况?
4.2 客户端长连接
前言 在互联网发展早期,由于用户量较少,业务需求也比较简单。对于软件应用,我们只需要一台高配置的服务器,把业务所有模块全单机部署,这样的软件架构模式称为单体架构模式。
随着用户量的增加,客户端请求的并发量越来越大,在这个过程中单体架构会产生两个问题。
1)单机的硬件资源是有限的,哪怕使用高配置服务器,其硬件资源仍然会称为瓶颈,随着客户端请求并发量越来越大,但单机性能的上涨受限,进而使得软件的性能逐渐下降,访问延迟越来越高。
2)容易出现单点故障
为了解决上述的问题,我们引入了将应用进行分布式集群化部署的架构,分为两种水平架构部署和垂直架构部署。
1)水平架构部署:应用程序分片集群化部署,例如Redis的分片集群。实现高性能和高拓展。
2)垂直架构部署:为了解决单点故障问题,一般会对应用程序进行主备/主从架构,例如Redis的主从。
但是新的架构设计有两个问题亟待解决:
1)客户端的请求如何均匀的分发到多台目标服务器上呢?
2)如何检测每台目标服务器的健康状态,避免客户端向已经宕机的服务器发起请求导致请求失败呢?如何支持目标服务器进行动态的上下线呢?
一:负载均衡概述 为了解决前言中提到的两个问题,于是引入了负载均衡技术的设计。简单来说负载均衡的核心目的就是做分治,将客户端的请求均匀的分发到多台目标服务器上,并支持目标服务器动态上下线的功能。 由于进行了分治处理,目标服务器多台的性能得到了释放,因此能够接受更大的客户端请求并发,实现了高并发负载均衡的目标。
那负载均衡的具体实现是什么呢?
首先实现负载均衡的可能方式有两种:
1)客户端层面做负载均衡。
2)把负载均衡功能解耦出来单独部署成一个单独的负载均衡服务器。
首先第一种方案,在客户端层面做负载均衡显然是不可取的,因为每一台Real Server服务器都有一个提供服务的RIP,如果让客户端记录所有的Real Server对应的RIP显然是非常荒谬的。
比如想象这样一件事,百度的网页放在了多台Tomact目标服务器上部署,比如今天突然百度新上线了一台Tomcat服务器,难道要打电话给所有使用百度的用户,告诉他们新的Tomact服务器的IP地址,让后让他们去访问新的Tomcat服务器?这显然是不对的。
第二种方案显然是可行的,其基础设计图如下:
注意:在这种设计模型下,客户端其实根本就不知道后端服务器集群是否使用了负载均衡,这对客户端都是透明的,客户端只要向后端服务器集群暴露的统一流量入口VIP发起请求就行了,其内部是如何进行请求分发的,对客户端来根本就不重要。
此时我们再想一个问题,Real Server为啥要集群化部署呢?还不是因为单台Real Server扛不住很高的并发因此需要集群化部署。那么疑问就来了,为啥单台Real Server抗不住的并发,需要多台Real Server才能抗住的并发,单台负载均衡服务器就能抗住?
前言 秋招即将来临,很多同学会问Java面试八股文有必要背吗?
我的回答是:很有必要。你可以讨厌这种模式,但你一定要去背,因为不背你就进不了大厂。
国内的互联网面试,恐怕是现存的、最接近科举考试的制度。
而且,我国的八股文确实是独树一帜。以美国为例,北美工程师面试比较重视算法(Coding),近几年也会加入Design轮(系统设计和面向对象设计OOD)和BQ轮(Behavioral question,行为面试问题)。
那么为什么国内面试不采取这样的考察方式呢?简单来说,互联网IT行业的求职者太多了,如果考察的是清一溜的算法题和设计题,那么会要求面试官有极高的技术水平,还要花大量的时间成本和精力。
也许现行的八股文面试不是最优的解法,但的确是最符合当前国内IT环境的做法。
所以,我采访了超过20位资深大厂面试官后,一直在尽量精炼准确的整理一套切实可行的八股文,现在已经有329位粉丝通过这套题走入了理想的岗位,所以分享出来给大伙看看,有什么不足之处欢迎评论补充。
篇幅所限本文就只贴一下题目了,同学们可以自己先看看有哪些题是会的
一、Java基础 44 道 1. 解释下什么是面向对象?面向对象和面向过程的区别?
2. 面向对象的三大特性?分别解释下?
3. JDK、JRE、JVM 三者之间的关系?
4. 重载和重写的区别?
5. Java 中是否可以重写一个 private 或者 static 方法?
6. 构造方法有哪些特性?
7. 在 Java 中定义一个不做事且没有参数的构造方法有什么作用?
8. Java 中创建对象的几种方式?
9. 抽象类和接口有什么区别?
10. 静态变量和实例变量的区别?
11. 12、short s1 = 1;s1 = s1 + 1;有什么错?那么 short s1 = 1; s1 += 1;呢?有没有错误?
12. Integer 和 int 的区别?
13. 装箱和拆箱的区别
14. switch 语句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上?
目录 1 首先检查网络管理器服务是否开启 (ubuntu需要界面)
2 创建并配置需要共享的wifi
首先,明确下这篇文章说的是啥,是为了在ubuntu系统的电脑上,搭建一个wifi热点,供其他移动设备连接上网。就像你的手机开启一个热点,让别人能连接并上网。不能说非常相似,只能说一模一样。
本人采用 ubuntu20.04,其他版本的ubuntu可能界面有一点不一样,但大体上操作方式是相同的。
1 首先检查网络管理器服务是否开启(ubuntu需要界面) 如果没有该软件需要通过apt-get install network-manager安装
# 检查网络管理器的状态 sudo systemctl status network-manager # 启动网络管理器 sudo systemctl start network-manager 2 创建并配置需要共享的wifi 1)在终端中执行命令,打开网络连接配置器(或者直接通过界面打开网络管理)
打开后,当我们在配置wifi时,下面会不断打印出消息,如果配置的有问题,我们可以在终端查看报错消息 nm-connection-editor # 例如,以下是打印出的部分消息 ** Message: 16:43:34.611: Cannot save connection due to error: 无效设置 Wi-Fi: 802-11-wireless.ssid: 缺少属性 ** Message: 16:44:03.969: Cannot save connection due to error: 无效设置 Wi-Fi: 802-11-wireless.ssid: 缺少属性 ** Message: 16:44:09.126: Connection validates and can be saved ** Message: 16:44:23.
目录
1. 单例模式介绍
2.单例模式实现
1. 单例模式介绍 有些时候我们在做 qt 项目的时候,要用到很多类. 例如我们用到的类有 A,B,C,D. 其中,A 是 B,C,D 中都需要用到的类,A 类非常的抢手. 但是,A 类非常的占内存,定义一个 A 对象需要 500M 内存,假如在 B,C,D 中都定义一个 A 类对象,对 内存的消耗是可想而知的.
所以 B,C,D 分别都定义一个 A 类对象是不可能的. 那么我们此时就希望: 能不能把 A 定义成"全局变量",然后这样子 B,C,D 类都能访问,并且整个程序就只有这一个 A?
答案是可以的,定义 A 的时候以单例模式定义即可
单例模式作为一种常用的软件设计模式,主要是用来保证系统中只有一个实例,例如一般一个程序中只有一 个日志输出实例,一个系统中只有一个数据库连接实例,这时候用单例模式非常合适。
单例模式用来做什么
正如之前所说,单例模式:
(1) 整个程序只有一个对象;
(2) 整个程序都能访问到它;
(3) 分为"懒汉模式"和"饿汉模式";
(4) "懒汉模式"是用到单例的时候才创建,否则不创建对象;
(5) "饿汉模式"是在程序启动时就需要创建变量;
懒汉模式是时间换空间,饿汉模式是空间换时间。
单例模式是在大型项目用到非常多的,例如:
(1) 一个日记记录类,必须整个程序只能有一个,假如有 2 个,在写日志文件时会相互"践踏".
(2) 数据库操作,连接类,必须整个程序只能有一个,假如有 2 个就会出问题,你想看假如 2 个进程同时使用 同一个账号,然后写入同一个数据会发生什么事情...
EXTI (Extern Interrupt) 外部中断
EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序
支持的触发方式:上升沿/下降沿/双边沿/软件触发
支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断
(1) 不同端口、同一pin口,共用一个中断线:如PA1、PB1、PC1共用外部中断线1——EXTI_Line1;
(2) 同一pin口共用一个中断线,但16个中断线却只共用7个中断服务函数:其中中断线EXTI_Line0-4独立拥有一个中断服务,中断线5-9共用一个中断服务函数,中断线10-15共用一个中断服务函数。
GPIO_PIN不能相同:PA1和PB1不行,PA6和PA7可以,PA9和PB15可以,PB0和PB1可以
(图来源于江协科技)
(图源于《STM32F10XXX参考手册》)
如上图,GPIO_PIN相同的gpio共用了一个中断线。
中断线和中断服务之间的关系
DCD EXTI0_IRQHandler ; EXTI Line 0 DCD EXTI1_IRQHandler ; EXTI Line 1 DCD EXTI2_IRQHandler ; EXTI Line 2 DCD EXTI3_IRQHandler ; EXTI Line 3 DCD EXTI4_IRQHandler ; EXTI Line 4 DCD EXTI9_5_IRQHandler ; EXTI Line 9..5 DCD EXTI15_10_IRQHandler ; EXTI Line 15..10 注意:不可以同时配置PA6和PA8触发外部中断
因为EXTI_Line6和EXTI_Line8是共用一个中断服务函数的,那触发EXTI_Line6和触发EXTI_Line8就进同一个中断服务函数了
解决方案:
进服务函数之后,判断是哪根中断线触发的就行:
if(ITStatus EXTI_GetITStatus(EXTI_Line6)){ 中断线6程序+清标志位6 } if(ITStatus EXTI_GetITStatus(EXTI_Line8)){ 中断线8程序+清标志位8 } 通道数:16个GPIO Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒
Mac安装npm全面指南 NPM是一个极为重要的Node.js软件包管理器,它允许用户轻松安装、更新、卸载任何需要的Node.js软件包。本文将提供Mac用户NPM安装的全面指南。
一、准备工作 在安装NPM之前,我们需要确保我们已经安装了以下软件:
1、Node.js:NPM是随Node.js一起发布的。如果没有安装Node.js,可以在Node.js官网下载。
2、Xcode命令行工具:可以在这里下载并安装Xcode命令行工具。
3、Homebrew:它是一个Mac OS X下的包管理器,可以在Homebrew官网上找到详细的安装说明。
安装完成后,可以运行以下命令检查是否成功安装了这些软件:
$ node -v $ npm -v $ brew -v 如果顺利地输出了版本信息,则表明这些软件已经成功安装。
二、安装NPM 有多种方法可以在Mac上安装NPM,举几个例子:
1、通过NVM管理器安装 安装NVM管理器,参考NVM官网的安装说明。安装完成后,可以运行以下命令:
$ nvm install --lts 该命令将安装最新的LTS版本。
2、通过Node.js官方安装程序安装 可以在Node.js官网下载Mac的.pkg文件,并按照提示安装。安装完成后,NPM已经随Node.js一起安装了。
3、通过Homebrew安装 可以使用以下命令在终端中安装NPM:
$ brew install node 三、更新NPM 为了获得最新的软件包并修复可能存在的错误和漏洞,需要定期更新npm。以下是更新npm的三种方法:
1、通过npm自身更新 可以使用以下命令更新npm:
$ npm install -g npm 2、通过Homebrew更新 可以使用以下命令更新npm:
$ brew update $ brew upgrade node 3、通过NVM更新(仅限于使用NVM安装的用户) 可以使用以下命令更新npm:
$ nvm install node --reinstall-packages-from=node 四、卸载NPM 有时候需要卸载npm,可以使用以下命令:
$ brew uninstall node $ npm uninstall npm -g $ sudo rm -rf /usr/local/{lib/node{,/.
本文目录 1. 下载 Harbor 安装包2. 解压3. 修改配置文件4. 安装 Harbor5. 修改 docker 配置6. docker 登录方式7. 访问 Harbor Web 界面8. 创建证书9. 生成证书10. 更新配置11. 网页登录 说明:在搭建 Harbor 镜像仓库之前,虚拟机要先安装 docker 和 docker-compose。
本文接下来的命令都是在 root 身份下运行的。
1. 下载 Harbor 安装包 直接下载可以使用以下命令:wget https: /github.com/goharbor/harbor/releases/download/v2.8.2/harbor-offline-installer-v2.8.2.tgz 直接在虚拟机内部执行上面这条命令的话,下载速度会很慢,所以此处通过外部主机下载后共享文件夹导入虚拟机中。 2. 解压 输入以下命令进行解压:tar -xvf harbor-offline-installer-v2.8.2.tgz 新建一个目录,将 harbor 目录下的文件移动到该目录下。依次输入以下命令:
mkdir /opt/harbor mv harbor/* /opt/harbor cd /opt/harbor 3. 修改配置文件 复制一份 harbor 的配置文件并改名 harbor.yml,输入以下命令:
cp -ar harbor.yml.tmpl harbor.yml 进入配置文件,输入以下命令:
vim harbor.yml 修改 hostname 和 port:
弹窗显示异常报错如下所示:
问题根因:添加tab顺序,修改图中的tab顺序
修改为
忘记密码重置步骤:
1、重启系统,当系统进入引导界面时,按e键。就可以编辑引导选项,在引导选中加入参数rd.break,如图所示:
2、编辑完引导选项后,按Ctrl+x组合键引导系统进入紧急模式,在紧急模式下原来的系统分区将被以只读方式挂载到/sysroot目录下。接下来需要以可读写的方式挂载/sysroot,并以此作为根目录修改root密码,如图所示:
mount -o remount,rw /sysroot 以可读写权限重新挂载/sysroot
chroot /sysroot 以/sysroot作为根目录建立环境
passwd root 运行passwd密码,修改root用户的密码
exit 退出/sysroot建立的环境
reboot 重启系统
以下是过去20年中FPGA领域中具有重要影响力的25个研究成果的一些例子:
Partial Reconfiguration: 针对FPGA动态可重构的能力,实现部分重配置,从而在运行时动态地更新部分逻辑。High-Level Synthesis (HLS): 将高级语言(如C/C++)转换为FPGA可编程逻辑的硬件描述语言(HDL),提高开发效率。Dynamically Reconfigurable Datapath Arrays: 实现动态可重构数据通路,使FPGA可以在不同应用之间灵活切换。FPGA-based Acceleration for Deep Learning: 利用FPGA在深度学习加速方面的优势,提供高性能、低功耗的解决方案。Logic Cluster-based Architectures: 通过重新组织逻辑资源,提高FPGA中逻辑单元的利用率和性能。FPGA-based Cryptography Accelerators: 利用FPGA实现高速和可定制的硬件加密解密加速器。Dynamic Power Management Techniques: 通过动态调整FPGA的电源管理策略,降低功耗和热量。High-Speed Serial Transceivers: 实现高速串行通信接口,提供更高的数据传输速率和带宽。Multi-FPGA Systems: 构建多个FPGA的系统,扩展计算和存储能力。FPGA-based Network Processing: 利用FPGA处理网络数据包,提供高性能、低延迟的网络加速解决方案。FPGA-based Software-defined Radio (SDR): 基于FPGA实现的软件定义无线电,实现灵活的射频通信系统。Approximate Computing on FPGAs: 利用FPGA灵活度高的特点,实现逼近计算,提供低能耗的近似计算解决方案。FPGA-based Image and Video Processing: 基于FPGA的图像和视频处理加速,提供高性能和低功耗的处理能力。High-Speed Memory Controllers: 实现高速内存接口,提供更快的存储访问速度。FPGA-based Hardware Trojans Detection: 使用FPGA进行硬件木马检测和分析,提高系统安全性。Configurable SoC Platforms: 将FPGA与处理器核心集成,提供可配置的SoC平台,实现灵活性和性能的平衡。FPGA-based Emulation and Prototyping: 使用FPGA进行电路仿真和原型验证,加速硬件设计的开发周期。Automatic Design Space Exploration: 利用自动化工具对FPGA设计空间进行探索,以寻找最佳设计解决方案。Reconfigurable Multi-Core Architectures: 利用FPGA构建多核系统,提供灵活配置的多核计算能力。Energy-efficient FPGA Design Techniques: 开发功耗优化的FPGA设计技术,提高能源利用率。FPGA-based Genome Sequencing Acceleration: 利用FPGA加速基因组测序处理,提供高吞吐量和低功耗的解决方案。FPGA-based Fault-tolerant Systems: 使用FPGA构建容错系统,提供高可靠性和冗余处理能力。Multi-Context FPGAs: 实现多上下文的FPGA架构,提供更大的逻辑密度和灵活性。FPGA-based Neuromorphic Computing: 利用FPGA实现神经形态计算,提供类脑计算的解决方案。FPGA-based Real-time Video Processing: 基于FPGA实现实时视频处理,包括视频编解码、滤波和特效处理等。 这些研究成果代表了过去20年FPGA领域的一些重要进展和创新,推动了FPGA技术的发展和广泛应用。当然,还有许多其他研究成果也对FPGA领域产生了重要影响,具体清单可能因个人观点和研究领域的不同而略有差异。
15年FPGA工作经验:诚实、耐心和不断学习的关键
作为一位有15年FPGA工作经验的工程师,我能够感受到这个行业的不断变化和技术的不断发展。回顾这些年的工作经历,我深刻体会到了几个重要的心得体会,这些体会成为我职业生涯中的指南。我想与大家分享这些经验,希望对其他从事或有意从事FPGA工程师的人有所帮助。
首先,诚实是我所坚守的原则之一。作为一名FPGA工程师,我们承担着开发关键系统的责任。在工作中,我始终坚持诚实,确保我设计的系统的可靠性和稳定性。任何时候,无论是遇到挑战还是犯错误,我始终毫不犹豫地承认并解决问题。诚实不仅建立了信任,也促进了团队的协作和成长。
其次是耐心。在FPGA编程中,遇到的问题可能会很复杂且难以调试。而且,新技术和新挑战也会不断涌现。在这些时候,耐心是取得成功的关键。我学会了逐步分析问题,仔细排查,遵循系统性的方法解决问题。耐心使我在困难面前不轻易放弃,才能找到最佳解决方案。
另外,持续学习是我始终坚持的。FPGA技术在不断变化,在过去的15年里,我见证了FPGA的快速发展和革新。为了跟上行业的步伐,我始终保持学习和探索的态度。我持续关注最新的技术发展,参与培训和研讨会,并不断学习新的编程语言和工具。通过持续学习,我能够拓宽自己的技术能力,并更好地适应行业的要求。
此外,团队合作也是我在工作中非常重视的。作为一个FPGA工程师,与其他团队成员合作是至关重要的。我经常与系统设计师、软件工程师和硬件工程师紧密合作,共同解决问题和实现项目目标。通过相互合作和协调,我们能够共同创造出更好的设计和解决方案。
最后,我要提醒每位FPGA工程师,在工作中要保持批判性思维。技术发展迅速,新的工具和方法不断涌现。我们必须始终保持开放的思维方式,审视旧有的方法和做法,并积极接受新的思想和技术。只有不断革新和改进,我们才能在这个竞争激烈的领域中立于不败之地。
总结起来,我的15年FPGA工作经验教会了我诚实、耐心和持续学习的重要性。这些品质帮助我在不断变化的环境中取得成功,并为未来的发展奠定了坚实的基础。我相信,只要我们保持这些追求,我们将在FPGA领域中不断成长和创新。
1、this.$router.back(); //返回上一级 2、父组件可以使用 props 把数据传给子组件。 3、子组件可以使用 $emit 触发父组件的自定义事件。 Moment (超常用,时间转换) 1、将时间转换为时间戳(每次这么简单,我为啥记不住)
moment(start_time).valueOf() / 1000 2、只有时间可以转换为moment对象(反显在组件上面)
[moment(start_time), moment(end_time)] [moment( 2019-12-18 14:27:38), moment( 2019-12-18 14:27:38)] 3、将时间戳转为时间
moment(item.deal_info.time * 1000).format("YYYY-MM-DD HH:mm:ss") 4、将组件选择的当前时间转为当天的零点(难受)
moment(moment(date[0]).format("YYYY-MM-DD 00:00:00")).valueOf() / 1000 5、将时分秒格式为时间戳
//将选中的时间初始为当天的凌晨 export function initFormatMorning(data) { return moment(moment(data).format("YYYY-MM-DD 00:00:00")).valueOf() / 1000; } // 将选中的时间初始为者当天的最后时分秒 export function initFormatEvening(data) { return moment(moment(data).format("YYYY-MM-DD 23:59:59")).valueOf() / 1000; } //将时间戳格式为年月日,时分秒 export function formatTime(data) { return moment(data * 1000).format("YYYY-MM-DD HH:mm:ss"); } /将时分秒直接格式为时间戳 export function timeStamp(data) { let delDataTime = moment( moment() .
Java SPI 文章来源
学习自b站
SPI全称是 Service Provider Interface 他是从java6 开始引入的,是一种基于ClassLoader来发现并加载服务的机制
一个标准的SPI由3个组件构成,分别是:
Service: 是一个公开的接口或抽象类,定义了一个抽象的功能模块
Service Provider: 是Service接口的一个实现类
ServiceLoader: 是SPI机制中的核心组件,负责在运行时发现并加载Service Provider
Java SPI的运行流程 蓝色为jar包内的内容
与Java SPI的作用和设计思想 以JDBC为例来学习
Java SPI在JDBC中的应用 在Java SPI出现之前,程序员们使用Class,forName来加载数据库驱动
如: Class.forName(“com.mysql.jdbc.Driver”)
那么为什么Class.forName就能加载数据库驱动呢? 这是因为JDBC要求Driver实现类在类加载的时候,能将自身的实例对象自动注册到DriverManager中,从而加载数据库驱动
那么"com .mysgl.jdbc.Driver",“oracle.jdbc.driver.OracleDriver”
"com.microsoft.sqlserver.jdbc.SQLServerDriver"这些类名是不是可以写在配置文件里?这样更换数据库驱动时就不用修改代码了?
例如: my-app.yml: driver-name:com.mysql.jdbc.Driver 但是这样也不够完美,还得记住不同数据库厂商提供的Driver的类名! 所以让数据库厂商来提供配置文件,程序员也省事,数据库厂商也省事,程序员不用了解具体的驱动类名,而厂商也可以轻松升级驱动
但是由厂商提供配置文件的话,我们怎么去读取它呢? 还记得类ClassLoader么?他除了可以加载类之外,还提供了方法getResource/getResources,可以工具指定的路径,读取classpath中对应的文件,我们可以用它来读取厂商放在Jar包中的配置文件,当然,我们要实现约定好配置文件的路径和格式----这套机制就是SPI
Java SPI的三大规范要素 在JDBC中的对应实现 1.文件路径:
将mysql的jar包解压后,可以看到目录META-INF/services下确实存在一个名为java.sql.Driver的配置文件,文件内容则是mysql的数据库驱动类
2.可以看到mysql的驱动类中确实存在一个默认的无参构造方法
我们只需要通过maven,将mysql的驱动jar包作为依赖引入后,JDBC就会自动加载mysql的数据库驱动
总结一下Java SPI Java SPI与SpringBoot自动配置 SpringBoot与其他框架集成时,不支持扫描注入其他框架的配置类,所以要使用Auto-configuration机制,基于引入的依赖jar包,对SpringBoot应用进行自动配置,换而言之,就是将其它jar包的配置类注入到IOC容器内
uni-app 如何使用 painter 库生成海报 前言`提示:源码我就不放了,涉及业务,有问题下面评论留言,或者私聊我, 以下是本篇文章正文内容,下面案例可供参考` 一、painter是什么?二、使用步骤1.如何使用 painter-custom-poster 绘制海报图片2.painter使用 !!!下面是 uni-app 中的写法,小程序的写法库里面有教程 总结 前言 在实际的开发当中,我们因该都遇到过类似的需求,譬如说,项目中有一个 分销的功能,A用户想要分销下机用户的话,会生成一个专属于自己的二维码,但是这个二维码太单一了,加一个效果,这个时候生成一张有二维码的海报,效果是比较好的,还有其他的列子不只是分销功能,像扫码点餐,邀请好友,助力等都使用了这个原理,那么接下来我们一起实现这个功能模块。
提示:源码我就不放了,涉及业务,有问题下面评论留言,或者私聊我, 以下是本篇文章正文内容,下面案例可供参考 一、painter是什么? 在这个我介绍两个 GitHub 上面的仓库
1. painter-custom-poster 这个库的具体功能是编辑我们想要生成的海报图,这个库我们不需要自己部署一套的话,可以直接使用 这个库的 线上demo 环境
2. painter 这个库才是我们在自己的开发代码中用来生成海报页面的库,这个库通过 JSON 数据来动态生成我们想要的海报
二、使用步骤 1.如何使用 painter-custom-poster 绘制海报图片 在这里我推荐一个哔哩哔哩上一个叫Liu-Nano的优秀UP主,视频链接放在下面了:视频地址
2.painter使用 !!!下面是 uni-app 中的写法,小程序的写法库里面有教程 1下载到项目 如果你当前是在 uni-app 上面开发微信小程序的话,打开插件市场搜索 painter 下载到你的项目当中
HbuilderX 开发工具的话直接回下载到你知道的开发项目当中,
vscode 开发工具的话,直接下载压缩包,在你的项目中创建一个wxcomponents 文件夹把 压缩包解压后放到里面
图片效果:
2.代码中使用
1. 在page.json 文件中,找到你要生成海报的页面,示例图
2. 在 开发页面进行引入示例图, 代码中 @imgOK 用来返回生成好的海报地址
调用生成的方法
接收生成后的海报
把在 painter-custom-poster 生成的json 放到一个 js文件当中,我就放在了 hb,js中 hb,js中的代码, return 复制大json, 吧需要替换的字段通过变量把原来json中的 url 给替换掉 示例图