迪杰斯特拉算法 迪杰斯特拉算法(Dijkstra)是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
C语言代码实现如下:
//【贪心算法】单源最短路径问题 #include <stdio.h> #include <stdlib.h> #define N 5 // 5个顶点,1、2、3、4、5 #define M 9999 // maxint,大整数 void Dijkstra(int n, int v, int dist[], int prev[], int c[][N + 1]); void Traceback(int v, int i, int prev[]); int main() { int v = 1; // 源点为1 int dist[N + 1]; // 从源到顶点i的最短特殊路径长度 int prev[N + 1]; // 从源到顶点i的最短路径上前一个顶点 // 带权有向图的邻接矩阵,行和列下标从1开始 int c[N + 1][N + 1] = { {M, M, M, M, M, M }, {M, M, 10, M, 30, 100 }, {M, M, M, 50, M, M }, {M, M, M, M, M, 10 }, {M, M, M, 20, M, 60 }, {M, M, M, M, M, M }, }; // Dijkstra算法 Dijkstra(N, v, dist, prev, c); // 输出 printf("
本案例要求使用抽象类知识编写一个程序,可以根据用户要求在控制台打印出不同的图形。例如,用户自定义半径的圆形和用户自定义边长的正方形。
此案例有四个类
MyPrint,MyPrintCircle, MyPrintSquare,Test Myprint类 public abstract class MyPrint { public abstract void show(); } Myprintcircle(圆形)类 public class MyPrintCircle extends MyPrint { @Override public void show() { //打印圆形 for (int y = 0; y <= 10; y +=2) { int x =(int)Math.round(5-Math.sqrt(10*y-y*y)); int len =2*(5-x); for (int i = 0; i <= x; i++) { System.out.print(" "); } System.out.print("*"); for (int j = 0; j <= len; j++) { System.
目录
1 知识回顾
2 岂曰无衣,与子同裳
3 简单的冠状病毒模型(Matlab代码实现)
1 知识回顾 新冠病毒传播模拟(Matlab实现)
2 岂曰无衣,与子同裳 位卑未敢忘忧国:
3 简单的冠状病毒模型(Matlab代码实现) % Cellular Automata % Corona clear all; n = 200; x = linspace(0,1,n); y = linspace(0,1,n); p_InitialInfection = 0.05; lambda_0 = 0.25; Tend = 40; lambda_r = 0.15; lambda_contact = 3; kmax = 1000; Dt = Tend / (kmax + 1); Times = linspace(0,Tend,kmax+1); TDeath = 5; Tsusc = 10; ProbabilityInfection = zeros(n,n); pcontact = 1 - exp(-lambda_contact *Dt); %[X,YY] = meshgrid(x,y);Y = YY'; %S = round(rand(n,n)); Sinit = S; S = ones(n,n); I = zeros(n,n); R = zeros(n,n); D = zeros(n,n); InfectionTime = zeros(n,n); for i = 1:n for j = 1:n if (x(j)-0.
1.创建house.html 效果图如下:
代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <!-- width=device-width 当前窗口宽度等于100% initial-scale=1 缩放级别为1--> <!-- 步骤一:适配移动端视口 --> <meta name="viewport" content="width=device-width,initial-scale=1" /> <title>房屋装饰网站</title> <style> /* 取消轮廓线 */ input{ outline: none; } </style> </head> <body> <!-- 步骤二:搭建页面主体结构和内容 --> <!-- 头部标签 --> <header width=375px align="center"> <!-- 步骤三:创建搜索栏 required:字段必须要填写不能为空 spellcheck true/false 针对英文如果拼写错误 会有红色波浪线提示 一半用于文本框和文本域 对用户输入的文本内容进行拼音和语法检查 使用表单表桥自带属性placeholder在input框内设置提示信息 accesskey:"任意键"在Windows系统下 按alt+值 相当于快捷键的作用 --> <form action="" method="get"> <input type="text" required="required" spellcheck="true" placeholder="请输入关键词" /> <input type="submit" value="搜索" accesskey="
对于常见数据类型通用打印支持
整形
浮点型
字符串类型,char
vector 包括多维度数组
map
set
T ah[N] 类型数组,包括多维数组
array<T, N> 和 多维度数组*
main.cpp
// C #ifndef _GLIBCXX_NO_ASSERT #include <cassert> #endif #include <cctype> #include <cerrno> #include <cfloat> #include <ciso646> #include <climits> #include <clocale> #include <cmath> #include <csetjmp> #include <csignal> #include <cstdarg> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #if __cplusplus >= 201103L #include <ccomplex> #include <cfenv> #include <cinttypes> // #include <cstdalign> #include <cstdbool> #include <cstdint> #include <ctgmath> #include <cwchar> #include <cwctype> #endif // C++ #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <exception> #include <fstream> #include <functional> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <iterator> #include <limits> #include <list> #include <locale> #include <map> #include <memory> #include <new> #include <numeric> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <stdexcept> #include <streambuf> #include <string> #include <typeinfo> #include <utility> #include <valarray> #include <vector> #if __cplusplus >= 201103L #include <array> #include <atomic> #include <chrono> #include <condition_variable> #include <forward_list> #include <future> #include <initializer_list> #include <mutex> #include <random> #include <ratio> #include <regex> #include <scoped_allocator> #include <system_error> #include <thread> #include <tuple> #include <type_traits> #include <typeindex> #include <unordered_map> #include <unordered_set> #endif using namespace std; template <typename T> concept isPrintable = requires(T t) { cout << t; }; // 是否支持 inplace loop for template <typename T> concept LoopAble = requires(T t) { // t 有begin()函数 且能 前++, 注意operator++(int) 是后++ // 约束 1 ++t.
win10电脑虚拟内存怎么设置?虚拟内存别称虚拟存储器,电脑所运行的程序均需经由内存执行,如果内存不足的时候可以适当设置虚拟内存来帮忙。那么win10电脑虚拟内存怎么设置比较合适呢?今天系统之家小编就为大家介绍win10电脑设置虚拟内存的相关内容。
Win10提示虚拟内存不足怎么办?
win10电脑虚拟内存如何设置:
1.首先,鼠标右键点击“此电脑”图标,在弹出的菜单中选择“属性”;
2.然后,在选择“高级系统设置”;
3.在弹出的面板中点击“Advanced”选项,然后在性能的右下方选择“Settings”打开;
4.弹出一个“性能选项”界面,选中上面的“高级”,然后选择“更改”选项打开;
5.去掉“自动管理所有驱动器的页面文件大小”,选择“自定义”,选择托管的系统作为C盘;
(当然也可以选择D盘设置虚拟内存)
6.设置内存大小通常使用默认值,如果觉得内存不足时再进行一次设置也可以,建议最多不超过2倍实际内存,内存越小,磁头定位越快,效率越高,在设置完之后,点击“确定”按钮,然后重新启动系统就可以应用设置了。
希望这些介绍对你有帮助。很多时候想要流畅运行游戏,都是需要设置虚拟内存的。
相关命令用法 add_libraries将指定的源文件生成库文件
add_executable将指定的源文件生成可执行文件
target_link_libraries跟在add_xxxx后,表示在上述两命令生成的文件后进行外部库的链接。
link_libraries已弃用,用法是在上述两add前进行外部库链接,不需要写target。
示例: cmake_minimum_required(VERSION 3.20) project(getStatus) set(CMAKE_CXX_STANDARD 14) set(SOURCE_FILES getStatus.cpp) add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES}) target_link_libraries(${PROJECT_NAME} HD) 参考来源
多文件目录 外层目录需要用add_subdirectory()包含子目录,才可检测到子目录的CMAKELISTS;
CMAKE_MINIMUM_REQUIRED(VERSION 3.20) project(TouchX_Status) set(CMAKE_CXX_STANDARD 14) message(${PROJECT_SOURCE_DIR}) add_subdirectory(${PROJECT_SOURCE_DIR}/src) #include_directories(${PROJECT_SOURCE_DIR}/src) add_executable(${PROJECT_NAME} main.cpp) target_link_libraries(${PROJECT_NAME} getStatus)
snprintf()函数用于将格式化的数据写入字符串,其原型为:
int snprintf(char *str, int n, char * format [, argument, …]);
【参数】str为要写入的字符串;n为要写入的字符的最大数目,超过n会被截断;format为格式化字符串,与printf()函数相同;argument为变量。
【返回值】成功则返回参数str 字符串长度,失败则返回-1,错误原因存于errno 中。
snprintf()可以认为是sprintf()的升级版,比sprintf()多了一个参数,能够控制要写入的字符串的长度,更加安全,只要稍加留意,不会造成缓冲区的溢出。
snprintf()与sprintf()使用方法类似,请参考:C语言sprintf()函数
注意:snprintf()并不是标C中规定的函数,但是在许多编译器中,厂商提供了其实现的版本。
在GCC中,该函数名称就snprintf(),而在VC中称为_snprintf()。由于不是标准函数,没有一个统一的标准来规定该函数的行为,所以导致了各厂商间的实现版本可能会有差异。
差异发生在参数 n。在GCC中,参数n是要向str写入3个字符,包括’\0’字符;在VC中,参数n是要写入的字符串的总字符数。
在GCC中运行如下程序:
#include <stdio.h> int main() { char str[5]; int ret = snprintf(str, 3, "%s", "abcdefg"); printf("%d\n",ret); printf("%s",str); return 0; } 输出:
7
ab
在VC中运行如下程序:
#include <stdio.h> int main() { char str[5]; int ret = _snprintf(str,3,"%s","abcdefg"); printf("%d\n",ret); printf("%s",str); return 0; } 输出:
-1
abc
从输出结果可以知道:
GCC中的参数n表示向str中写入n个字符,包括’\0’字符,并且返回实际的字符串长度。
VC中的参数n表示会向str中写入n个字符,不包括’\0’字符,并且不会在字符串末尾添加’\0’符。当字符串长度超过参数n时,函数返回-1,以表示可能导致错误。
目录
1. 数据化运维体系是什么
2. SREWorks数据化运维平台
3. 基于SREWorks数据化运维实践
3.1 稳定性建设
3.2 成本建设
3.3 效率建设
3.4 运营中心
4. 结语
开源Elasticsearch是一个基于Lucene的实时分布式的搜索与分析引擎,是遵从Apache开源条款的一款开源产品,是当前主流的企业级搜索引擎。作为一款基于RESTful API的分布式服务,Elasticsearch可以快速地、近乎于准实时地存储、查询和分析超大数据集,通常被用来作为构建复杂查询特性和需求强大应用的基础引擎。
2017年,阿里云携手Elastic合作推出了阿里云Elasticsearch服务,在100%兼容开源功能的同时,支持开箱即用、按需付费。通过 Elastic 创新的检索技术与阿里云自研的云原生高性能内核、达摩院 NLP 分词与向量检索等能力,帮助企业客户提升业务成效,并节约费用支出。在切实提高企业应用程序性能的同时,提升业务的敏捷性和智能化,缩短解决问题所需时间,使客户可以专注于自身业务创新。
基于"源于开源,又不止于开源"的产品理念,阿里云Elasticsearch持续在包含智能运维在内的可观测场景进行云原生引擎能力升级,作为业内首个Serverless Elasticsearch云服务,云上日志增强引擎可提供基于读写分离架构的Indexing Service写入加速服务、Openstore海量存储服务,从而实现Elasticsearch写入及存储Serverless,为用户带来更低成本、更高性能、更简单易用的全观测场景能力。
ELK作为业界处理与分析日志首选的解决方案,由搜索引擎Elasticsearch、采集与解析工具 Logstash、轻量级采集组件Beats、可视化分析工具Kibana等工具组成,形成了一整套生态矩阵。目前阿里云已经成功将全套ELK搬到了云上为用户提供服务,可以被广泛应用于实时日志处理、全文搜索和数据分析等领域。SREWorks正是基于以Elasticsearch为主的生态矩阵,构建了一套应用全观测数据化运维最佳实践。
1. 数据化运维体系是什么 数据化运维体系,是一套把所有系统的运维数据采集起来、真正打通,深度挖掘这些数据的价值,通过数据驱动运维并为运维提供数据决策,同时能将生产系统进行“运维量化管理”的数据化运维业务模型。基于该模型建立标准化运维数仓,建设数据运维平台,在平台中规范运维数据的采集,存储,计算以及分析,并提供一系列数据化服务,供上层运维场景使用。
2. SREWorks数据化运维平台 SREWorks数据化运维平台包含一个核心和多个数据服务,一个核心即运维数据仓库,提供标准运维数据模型;多个数据服务即围绕运维数据的采集、存储、计算以及分析的数据化链路,提供的规范化数据服务,支撑应用的运维量化。
运维数仓
基于开源Elasticsearch建设标准化运维数仓,抓住数据化运维本质,抽象三大数据主题和九个数据域,内置涵盖云原生数据运维场景的数据实体和数据模型。数仓具备灵活的用户自定义实体/模型能力,充分满足用户的个性化需求。
数仓数据后端采用Elasticsearch存储,其分布式索引架构、多副本、索引生命周期管理以及数据冷热存储分离等特性,很好的满足了数仓的稳定性和动态性基本特性。同时可以对接多种数据处理工具(Logstash、Spark、Flink、APM Server),最终数据落地Elasticsearch,支撑起整个运维数仓的存储和检索能力。
数据采集服务
集成metricbeat、filebeat、skywalking等数据采集agent,以全托管方式,进行可观测数据采集,包括Node/Pod/Container资源/负载指标、状态指标、运维事件、Prometheus外围指标、服务(容器)日志采集解析、服务追踪调用链采集分析等。metricbeat支持基于标签的服务自动发现能力,默认监听10800端口,主动采集满足标签条件服务上报的业务指标数据。
作业平台采集场景服务,属于自研数据采集服务,支持多种数据采集脚本,关联数仓模型,通过SREWorks运维数仓托管业务的运维数据。
数据计算/分析服务
开源Apache Flink是一个⼀站式实时大数据分析平台,通过标准SQL降低业务开发门槛,提供端到端实时数据分析能力。同时内置常规数据处理UDF(阈值检测、数据聚合、数据降采样),支撑时序数据的流式加工处理。
作业平台数据化场景服务,覆盖巡检、分析、诊断等多个数据化场景,可自定义数据处理逻辑,满足用户个性化数据处理要求。
指标服务
提供指标定义和指标实例的配置与管理,已经内置基础资源和基础性能指标,用户可以按需新增指标。新增指标可以关联到采集场景服务,支持指标数据推送kafka队列,用于进行下游数据计算消费。
数据集服务
数据集服务提供快速将运维数仓模型存储数据表或者用户自定义数据源表生成API的能力,用户无需具备编码能力,即可快速配置数据接口,实现数据的管理和消费。目前优先支持elasticsearch和mysql数据源。
3. 基于SREWorks数据化运维实践 3.1 稳定性建设 服务链路全观测建设
由于IT系统日益增加的复杂度、大量云原生技术的采用,使得服务快速排障变得越来越难。而指标、日志和追踪三大可观测性支柱,可以实现服务的白盒监控能力。
SREWorks数据平台集成metricbeat、filebeat、skywalking等数据采集agent和自研数据采集场景作业,提供全托管一站式可观测数据采集能力,可以直接获取运行系统的指标、日志和调用链,协助问题的排查和诊断,缩短故障恢复时长(TTR)。
健康管理服务建设
为了帮助用户更好的感知系统运行状态,实现系统的监控管理,结合阿里Emon团队的智能检测服务和自研作业场景服务,构筑健康管理服务。包括事件采集管理、风险巡检、指标告警检测、异常诊断场景作业,帮助用户识别风险、分析告警、进行异常诊断和自愈以及故障管理。
建设规范化健康管理平台,能够降低或者消除系统隐患,尽最大可能将潜在故障扼杀在萌芽状态。一旦故障发生及时通知关联人员,进一步提升应对效率,确保行动的有效性。
3.2 成本建设 当前云原生服务成为云计算主流的服务形态,但由于云原生化的应用程序及其资源需求常常是动态变化,这也导致云成本的计算复杂性。为此,SREWorks内置一套完整的成本管理解决方案,包含资源消耗计量计费的可视化、资源使用明细分析,用于辅助用户优化和治理云资源成本。
SREWorks系统设置下的成本定价模型,重点从资源层面(CPU、内存、存储)进行成本核算。平台会自动按照应用粒度,每天进行应用资源用量和成本计费汇总,汇总数据自动同步至数据仓库应用成本模型(APP_COST)存储。
3.3 效率建设 运维效率即运维活动的效率,代表了运维的平台化能力,包括自动化运维操作和自动化的构建部署等,而人效比是最能直接体现运维效率,衡量人力资源价值的指标。
3.4 运营中心 运营中心从质量、成本、效率三个维度,提供应用的实时健康分、健康实例统计、应用可用率、应用成本占比、资源分配、运维人效、运维操作统计等关键数据看板,致力于保证用户获取准确可靠的应用运行状况、健康趋势、成本资源水位以及人力消耗,从而作出稳定性保障、预算准备、资源扩容等运维决策。
1、电容电压不能突变
理论公式Ic=C*du/dt,可以看到电容电流跟电容电压的变化率有关系,也就是说如果电容上电压的变化率为0,那么Ic=0,这就是我们常说的电容具有隔直流通交流的特性。
如下仿真,为了显示电容的指数上升特点需要先进行如下设置,所有元件的初始状态都设置为0:
从图可以看到A、B通道电压差为0的时候流过电阻R1的电流为0,跟上面的理论公式相符,如果减小R1的阻值,则电容电压上升很快,也说明充电电流很大,可能拉低电源或者产生操作过电压,从而引起误保护,在设计电路的时候需要考虑到充电电流是否对电路其他部分有影响。
电容充电电流与电容电压关系图
2、电感电流不能突变,电压可以突变 (UL=L*di/dt)
Multisim—用示波器观察电流波形,仪表里面的current probe:它显示实时电流,但无法将电流波形在示波器中显示。仿真Simulate >仪器Instruments > 电流探针 current clamp:也就是电流钳,它能够将流经的电流转成电压并输入到示波器中进行显示。双击图纸上的电流钳,打开的设置界面如下图所示,要设置的参数主要是电压对电流的比例,也就是电流钳在流经单位电流的时候输出的电压大小。下图中设置为1V/mA,也就是说如果回路中流过的电流是1mA,则电流钳输出的电压为1V。该参数可以按需设置。
通过BUCK降压变换器工作原理及Multisim实例仿真BUCK降压变换器工作原理及Multisim实例仿真来说明:
开关电源(Switching Mode Power Supply)即开关稳压电源,是相对于线性稳压电源的一种的新型稳压电源电路,它通过对输出电压实时监测并动态控制开关管导通与断开的时间比值来稳定输出电压。由于开关电源效率高且容易小型化,因此已经被广泛地应用于现代大多数电子产品中。如果说每个现代家庭都至少有一个开关电源都不为过,如电视机(彩色的)、电脑、笔记本、电磁炉等等内部都有开关电源,虾米?这些东西你们家都没有?我去!那手机有没有?手机充电器也是一个小型的开关电源,中招了吧!手机也没有,那就是古代家庭了,忽略之!
如下图所示为线性稳压电源电路的基本原理图:
之所以称其为线性电源,是因为其稳定输出电压的基本原理是:通过调节调整管(如三极管)的压降VD来稳定相应的输出电压VO,也因调整管处于线性放大区而得名。如果某些因素使得输出电压VO下降了,则控制环路降低调整管的压降VD,从而保证输出电压Vo不变,反之亦然,但这样带来的缺点是调整管消耗的功率很大,使得该电路转换效率低下,当然,线性电源的优点是电路简单,纹波小,但是在很多应用场合下,转换效率才是至关重要的。为了进一步提升稳压电路中的转换效率,提出用处于开关状态的调整管来代替线性电源中处于线性状态中的调整管,而BUCK变换器即开关电源基本拓扑之一,如下图所示:
其中,开关K1代表三极管或MOS管之类的开关管(本文以MOS管为例),通过矩形波控制开关K1只工作于截止状态(开关断开)或导通状态(开关闭合),理想情况下,这两种状态下开关管都不会有功率损耗,因此,相对于线性电源的转换效率有很大的提升。开关电源调压的基本原理即面积等效原理,亦即冲量相等而形状不同的脉冲加在具有惯性环节上时其效果基本相同,如下图所示:
同样是从输入电源10V中获取5V的输出电压,线性稳压电源的有效面积为5×T,而对应在开关稳压电源的单个有效周期内,其有效面积为10×T×50%(占空比)=5×T,这样只要在后面加一级滤波电路,两者的输出电压有效值(平均值)是相似的。下面我们来看看BUCK转换电路的工作原理(假设高电平开关闭合,低电平开关断开)。
当开关K1闭合时,输入电源VI通过电感L1对电容C1进行充电,电能储存在电感L1的同时也为外接负载RL提供能源。
当开关K1断开时,由于流过电感L1的电流不能突变,电感L1通过二极管D1形成导通回路(二极管D1也因此称为续流二极管),从而对输出负载RL提供能源,此时此刻,电容C1也对负载RL放电提供能源。相关波形如下图所示:
通过控制开关K1的导通时间(占空比)即可控制输出电压的大小(平均值),当控制信号的占空比越大时,输出电压的瞬间峰值越大,则输出平均值越大,反之,输出电压平均值越小,理想状态下(忽略损耗),则输出电压与输入电压的关系如下式:
其中,Ton表示一个周期内开关闭合的时间,Toff表示一个周期内开关断开的时间,Ton/(Ton+Toff)也叫做矩形波的占空比,即一个周期内高电平脉冲宽度与整个周期的比值,亦即输出电压为输入电压与控制信号占空比的乘积,如下图所示:
BUCK变换拓扑通过配合相应的控制电路,实时监测输出电压的变化,适时地动态调整占空比开关管的导通与截止时间的比值,即可达到稳定输出电压的目的,如下图所示:
这种通过控制占空比的方式也叫做脉冲宽度调制技术(Pulse Width Modulation, PWM),它是一种频率固定而占空比变化的控制试,相应地,也有脉冲频率调制技术(Pulse frequency Modulation, PFM),或两者的结合。从公式中也可以看出,BUCK拓扑结构只能用来对输入电压VI进行降压处理(升压方案可参考Boost拓扑),因为控制信号的占空比是不可能超过1的,这一点与线性电源是类似的,而且设计比较好的开关电源电路,其效率可达到90%以上,这看起来似乎是个不错的降压稳压方案,但任何方案都不会是完美的,随之而来的问题也接踵而至,比如纹波、噪声、EMI等问题,下面我们简单介绍一下:
纹波即上图所示的输出电压波动成分的峰峰值,自然是越小越好。要降低纹波有很多途径,增大电感量或电容量就是常用的途径之一,电感量或电容量增加后,充放电速度(时间常数增大)都会下降,相应的纹波峰峰值也会下降,如下图所示:
对于具体的BUCK拓扑降压芯片,厂家都会提供典型的应用电路及相关的参数值,如下图所示为TI公司的集成降压芯片LM2596典型应用电路图:
我们也可以通过提高开关的频率来降低纹波,这样,在同样的电感量与电容量条件下,每次充放电的时间缩短了,这样纹波的峰峰值就下降了,如下图所示:
换句话说,在相同的纹波值条件下,如果选择开关频率较高的芯片,电感与电容值相对会小一些(即成本低一些),如下图所示为LM2596的内部开关频率为150KHz,相应的也有超过MHz的开关频率芯片。
我们用下图所示的电路参数仿真:
其中,信号发生器XFG1设置驱动峰值电压为12V,频率为150KHz,占空比50%,如下图所示:
而监测的电路参数主要是开关之后的电压、电感电流及输出电压(理论计算应为6V),我们看看下图所示的仿真结果:
其中,红线表示电感电压,绿线表示开关后的电流,蓝线表示输出电压(其值为5.79V)。看起来输出电压还是比较稳定的,我们将输出电压曲线放大一下并测量一下其纹波值,如下图所示: 放大后可以看到基本没有纹波,当然这是理论上的,同时可以看到电感电压可以突变,但电感电流是不能突变的。还有一个效率问题,与线性电源不同的是,BUCK变换器的输入电流与输出电流是不一样的,因此,不能简单地用输出电压与输入电压的比值来表征,我们只有用最原始的方法了,就是计算输出功率与输入功率的比值,如下式:
仿真电路如下图所示:
根据上述公式计算电源效率为:(1.16*5.79)/(0.591*12)=0.947=94.7%。
续流二极管也是损耗的一种来源,由于续流二极管存在一定的压降,只要续流二极管中有电流就存在损耗,即P=ID×VD,很明显,降低二极管损耗的有效办法是选择低压降的二极管,如肖特基二极管,更多文章可关注《电子制作站》微信订阅号dzzzzcn,但是低压降的肖特基二极管漏电流与结电容也大,会产生更大的损耗,因此需要综合各种因素考虑,我们也可以采用同步整流的方案,即使用MOS管来代替续流二极管,如下图所示:
同步整流电路方案中,Q1导通时Q2截止,则Q1截止时Q2导通,即可代替肖特基二极管的续流功能。假设原方案中的肖特基二极管压降为0.4V,流过其中的电流为3A,则损耗的功率为1.2W,如果选择导通电阻较小的MOS管(如0.01欧姆),则同样的电流条件下损耗为0.09W,大大提高了电路的效率。理想的MOS管在工作时(即导通或截止)的压降及流过其中的电流应如下图所示:
其中,VDS表示MOS管两端的压降,而ID表示流经MOS管的电流,在任意时刻,VDS与ID都会有一个参数为0,因此消耗的功率P=U×I也应当是0,但是实际MOS管的开关与闭合都是需要过渡时间的,真实的开/关状态如下图所示:
在阴影区域,电流与电压都不再为零而引起了开关损耗,它主要与开关的切换频率有关,频率越高则单位时间内开关的次数越多,因此相应的开关损耗也越大。另外,为避免开关电源带来的EMI问题,应该对开关电源电路的PCB布局布线格外关注,如下图所示:
在进行PCB 布局布线时,应尽量使开关管与相关的续流二极管、储能电感及输出电容的电流回路是最小的,LM2596S布局布线实例如下图所示:
网元可视化视图组件(Network) 层次结构 Network分为三个层次,最底层是view(div),在此基础上放置两个Canvas,分别是rootCanvas和topCanvas。
rootCanvas用于绘制背景和网元,topCanvas可用于绘制附件、告警、编辑框等元素。
view View是最底层div元素,rootCanvas和topCanvas均放置在这个div上。
获取方式:network.getView()
示例:如修改背景颜色
network.getView().style.backgroundColor = "#ccc" network.getView()能直接拿到view这个div。
rootCanvas rootCanvas:用户绘制一些比较底层的元素,如背景、网元、自定义其他元素。
获取方式:
network.getRootCanvas(); 绘制顺序:
(1)绘制背景,内部调用$backgroundUI.draw(ctx, this);
(2)拦截绘制paintBottom内容:内部调用this.paintBottom(ctx, dirtyRect);
(3)绘制网元:ui.paint(ctx);
添加背景图片
box.setStyle('background.type', 'image'); box.setStyle('background.image', 'image_name'); 实现:
首先注册图片
returnRegisterImage("/static/topoimages/ditu.png", network) // returnRegisterImage("/static/topoimages/dev2.png", network) // 添加背景图片 首先注册图片 box.setStyle('background.type', 'image') box.setStyle('background.image', 'ditu') 在背景图片和网元之间绘制一张网状表格例子
topCanvas 获取方式:network.getTopCanvas(); 绘制顺序:
(1)绘制Marker等元素:this.paintMarker(ctx);
(2)拦截绘制paintTop内容:内部调用this.paintTop(ctx,dirtyRect);
示例:在topCanvas层绘制公司信息
network.paintTop = function (ctx, dirtyRect) { var img = new Image(); img.src = "./twaver.png"; ctx.drawImage(img, 1150, 500, 100, 100); ctx.font = "
1、停止mysql服务
systemctl stop mysqld.service
2、编辑配置文件
vim /etc/my.cnf
#在[mysqld]下添加
skip-grant-tables
3、启动mysql服务,直接回车登陆
systemctl start mysqld.service
mysql -uroot -p
[root@mysql5 bin]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.34 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
什么是makefile? 或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。必竟,这个make是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。
在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。这里所默认的编译器是UNIX下的GCC和CC。
2 关于程序的编译和链接
——————————
在此,我想多说关于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。
编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。
链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。
总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File.
好,言归正传,GNU的make有许多的内容,闲言少叙,还是让我们开始吧。
3 Makefile 介绍
———————
make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。
首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:
1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。
3.1 一、Makefile的规则
在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
target ... : prerequisites ... command ... ... target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。 prerequisites就是,要生成那个target所需要的文件或是目标。 command也就是make需要执行的命令。(任意的Shell命令) 这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。
说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。呵呵。还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。内容还多着呢。:)
3.2 二、一个示例
记录不经常使用容易忘记,和不知道的MYSQL知识
MYSQL基础相关 官方文档位置 https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html MYSQL原理图
查看表的创建和库的创建信息
show create [table or database ] name ;查看编码命令
show variables like 'character_%'; show variables like 'collation_%';插入数据时乱码
原因是访问的客户端与mysql编码不一致,解决方案,设置当前连接的客户端字符集 “SET NAMES GBK;”修改表和数据库的编码
1.更改表的编码
alter table [tablename] charset utf8;
2.更改表中字段的编码
alter table [表名] modify [字段名] varchar(20) charset utf8;
3.修改数据库的编码
alter database [数据库名] charset utf8; 查询语句 SQL执行顺序 以下面这个SQL为例
From 子句执行顺序为从后往前、从右到左,从最后一张表到第一张,最后一张表最为驱动表,所以表应该从大到小的写。
比如:select * from students,user; 那么顺序就是从user开始到student的数据生成一张笛卡儿积的虚拟表1,user表是驱动表,如果是小表的话效率比较高。
SELECT 是先执行 FROM 这一步的。在这个阶段,如果是多张表联查,还会经历下面的几个步骤: 首先先通过 CROSS JOIN 求笛卡尔积,相当于得到虚拟表 vt(virtual table)1-1;通过 ON 进行筛选,在虚拟表 vt1-1 的基础上进行筛选,得到虚拟表 vt1-2;添加外部行。如果我们使用的是左连接、右链接或者全连接,就会涉及到外部行,也就是在虚拟表 vt1-2 的基础上增加外部行,得到虚拟表 vt1-3。 On 在生成虚拟表后,会用On对数据进行筛选,把筛选出来的保存成虚拟表2Join添加外部表,如果有外连接查询中保留表会追加到虚拟表2,形成虚拟表3,如果from包含多个表,第三张表会和前两张表的结果,重复From-On-Join的步骤,直到处理完所有的表。
题库来源:安全生产模拟考试一点通公众号小程序
2022年氧化工艺考试练习题为氧化工艺判断题的新全考试题型!2022年氧化工艺考试模拟100题及在线模拟考试依据氧化工艺新版考试题库。氧化工艺考试100题通过安全生产模拟考试一点通上查找答案。
1、【单选题】 1211灭火器的使用方法分为七步:拿,站,(),压,查。( A )
A、拔,握,对
B、压,握,拔
C、拔,压,握
2、【单选题】 两相触电比单相触电()。( A )
A、更危险
B、更安全
C、一样
3、【单选题】 个人剂量监测档案应保存()。( A )
A、终生保存
B、50年
C、80年
4、【单选题】 为减少污染,含硫污水应采用的输送方式是()输送。( C )
A、连续式
B、开放式
C、密闭式
5、【单选题】 乙炔是最()的炔烃。( C )
A、稳定
B、复杂
C、简单
6、【单选题】 保护接零就是将电气设备的金属外壳接到()上。( B )
A、大地
B、中性线
C、避雷针
7、【单选题】 化工污染物都是在生产过程中产生的,其主要来源()。( C )
A、化学反应副产品,化学反应不完全
B、燃烧废气,产品和中间产品
C、化学反应不完全的副产品,燃烧废气,产品和中间产品
8、【单选题】 化工生产中的主要污染物是“三废”,下列那个有害物质不属于“三废”。( B )
A、废水
B、有害物质
C、废气
9、【单选题】 原子间通过共用电子对所形成的化学键叫()。( C )
A、离子键
B、氢键
C、共价键
10、【单选题】 在一定温度下,溶液上方蒸气中某一组分的分压等于该组分的饱和蒸气压与它在溶液中的()的乘积。( B )
Dell PERC H710P导入RAID卡阵列信息 1.将一台服务器(A)的硬盘依次拔出,按相同顺序插入另一台同样配置的服务器(B)
2.启动服务器(B)
3.按提示键盘按下ctrl+R进入raid卡配置界面。
光标移动到PREC H710P Mini处,按F2->Foreign Config-> Import 导入完成,会看到导入以后的raid信息,然后退出。
4.退出以后重启服务器,导入完毕。
注:如果是不同型号raid卡之间的导入,则需要提前了解一下是否兼容的问题,否者有可能导入不成功。
附:raid卡阵列知识普及。
我们常用的raid阵列卡PERC H700 和 H800 至 PERC H710P 和 H810都支持将raid配置重新导入到另一台服务器,实现服务器的冷迁移,尤其是在服务器应该故障,硬盘完好的情况下,非常有用。
下面是查看阵列卡信息常用的两个命令:
①显示Raid卡型号,Raid设置,Disk相关信息
MegaCli -cfgdsply -aALL -nolog
②显示raid卡信息
MegaCli -AdpAllInfo -aALL -nolog
参照:http://www.linuxidc.com/Linux/2015-02/113618.htm
线性表 读完本篇文章你能学会什么?(要求) 理解线性表的概念熟练掌握线性表的基本运算掌握线性表的顺序存储结构及基本运算掌握线性表的链式存储结构及基本运算掌握在顺序表和链表上算法设计的基本技能理解顺序表和链表的优缺点 线性表的基本概念 线性表(Linear List)是一种线性结构,它是由若干个结点按照“一对一”的逻辑关系组织起来的有穷序列。当线性表的长度为0时我们称它为空表,记为()。数据元素又称结点,当线性表的长度大于0时,线性表可表示为(a1,a2,a3......an),a1称为头结点,an称为尾结点(终端结点)。对任意一个结点(除头结点和尾结点)任意一个结点都有一个直接前驱和直接后继。a2的前驱是a1,a2的后继是a3。
基本特征:线性表中的结点具有“一对一”的关系,如果结点数不为0,除起始结点没有直接前驱外,其他每个结点有且仅有一个直接前驱;除尾结点没有直接后继外,其他每个结点有且仅有一个直接后继。
线性表中,每个结点可以代表不同的意义。在不同应用中各不相同。并且在一个解决方案中同一个线性表中的所有结点所代表的含义都是相同的。如每个结点可以表示一个数字,每个结点可以存储学生信息档案。当然可以存储更复杂的信息。
线性表的基本运算 初始化Initiate(L):建立一个空表L=(),L不含任何数据元素。获取表长Length(L):返回线性表L的长度。读取元素Get(L,i):返回线性表L的第i个数据元素。定位Locate(L,e):查找线性表L中与e相同的数据元素值返回第一个,如果没有返回0。插入Insert(L,i,e):在线性表L中的第i个位置插入e。删除Delete(L,i):删除线性表L中的第i个元素。输出Show(L):输出线性表的所有数据元素值。 线性表的顺序存储结构 线性表的顺序存储结构是这样的:
顺序存储结构是最简单的一种存储方式,对于线性表这种逻辑结构我们可以通过数组转换成存储结构。
顺序表的顺序存储结构:将表中的结点一起存放在计算机内存中的连续空间内,数据元素在顺序表的邻接关系就是它们在存储空间中的邻接关系。线性表的顺序存储结构是简单的,一般使用数组来实现。
【例1】学生档案信息标的顺序存储实现
typedef struct { int studentID; //学号 char name[8]; //名字 char sex[2]; //性别 int age; //年龄 int score; //成绩 }DataType; //定义一个学生信息档案的结构 typedef struct { DataType data[MAXSIZE]; //存放数据的数组 int length; //存放表长度 }SeqList; SeqList student; //建立空表,此时student表中没有任何数据元素 预先定义一个MAXSIZE宏定义常量,作为数组的最大长度。数据域data是一个数组,线性表的n个元素分别存在数组中的0—(length-1)中。
线性表的基本运算在顺序表中的实现 插入Insert(L,i,e):在线性表L中的第i个位置插入e。无返回值。
//实现思路:从表的最后一个结点开始遍历到第i个位置,将i和i后的元素向后的所有结点向后移动一个位置,将e插入到i的位置 void Insert(SeqList L, int i, DataType e) { int n; if (L.length == MAXSIZE) { cout << "
效果:可以自动生成 Controller Service Mapper DAO层的基本代码,免去自己去写实体类映射数据库的繁琐操作 提效神器之代码自动生成MybatisPlus-Generator+Lombok Mybatis-plus-generator介绍
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。底层是模板引擎技术,可以自定义生成的java类模板大家以前或多或少用过基础版mybatis-genarator 第一步 添加依赖 <!-- 代码自动生成依赖 begin --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.1</version> </dependency> <!-- velocity --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.0</version> </dependency> <!-- 代码自动生成依赖 end--> 第二步
实现代码(标记TODO的记得修改)
将下方代码放入测试类运行即可生成
package net.xdclass.manager; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.GlobalConfig; import com.baomidou.mybatisplus.generator.config.PackageConfig; import com.baomidou.mybatisplus.generator.config.StrategyConfig; import com.baomidou.mybatisplus.generator.config.rules.DateType; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.boot.test.context.SpringBootTest; import java.
1.更新驱动,点击USBDriver的两个.bat文件进行驱动更新
2.拔掉stlink,然后刷入老版固件。插上stlink ,解决!!!
介绍 本教程包含两个示例。 在第一个示例中,我们将从LoRa发送者/发送者向接收者发送一条简单的“ Hello World”消息。 但是在第二个示例中,我们将无线发送传感器数据。 BME280气压传感器提供气压,温度,湿度等信息。STM32 LoRa发送器将传感器数据发送到STM32 LoRa接收器。
硬件 LoRa模块 引脚1:ANT –此引脚将连接到天线引脚2、9、16:GND –电源和控制器共同接地的接地引脚引脚3:3.3V –要给设备加电,引脚3将有助于输入电源引脚4:RESET –引脚4用于通过外部信号复位模块引脚5、6、7、8、10、11:DIO0,DIO1,DIO2,DIO3,DIO4,DIO5 –要通过模块执行常规I / O功能,DIO引脚会有所帮助。这些引脚可定制为中断引脚引脚12:SCK – SCK引脚用于SPI通信期间的时钟脉冲引脚13:MISO – MISO表示主进和从出,将数据传输从模块传输到控制器。主站为控制器,SX1278为从站引脚14:MOSI – MOSI表示主机输出从机输入。因此,此引脚将从控制器接收数据引脚15:NSS – NSS是芯片选择/启用引脚,将有助于激活从机 LoRa频率分配
LoRa频率并非到处都是合法的。SX1278的频率为433MHz,因此除了用于学术目的之外,不允许长时间使用它。 同样,请检查您所在国家/地区允许的范围,并确认您可以使用实际的频率范围。 LoRa模块确实提供了不同的频率范围,最常见的是433MHz,915MHz和868MHz。
连接图 详情参阅 - 亚图跨际
转自:http://blog.sina.com.cn/s/blog_668aae780101iou9.html
http://yaogangshi.iteye.com/blog/1001690
http://bbs.csdn.net/topics/390019506
问题:在用c++扩展php进行调试时,用malloc或new开辟数据空间并将php的array数据传入时,出现异常:Unhandled exception at 0x777F5624 (ntdll.dll) in php.exe: 0xC0000374: 堆已损坏
原因:堆被破坏的问题通常是因为内存写越界造成的。因为你分配的两段内存可能恰好连续,前一段内存在写的时候越界,写到第二段的开头,将一些堆数据破坏了。因此报堆损坏的错。也可能是内存不足造成的。
进程分配内存(显式调用new,allocate,隐式分配内存比如调用strdup,strstreambuf::str等)
然后传递给DLL进行释放。都可能因为使用了不同的CRT库造成内存非法访问和栈破坏。
每一份CRT库的都有独立和唯一一份状态,并且每一份CRT库都有自己的对管理器。DLL和EXE可能使用了不同的CRT库,所以分配和释放内存的堆不能匹配从而导致了堆破坏。
修复方法:EXE和所有的DLL都必须动态链接/MD到同一份CRT。
解决:把dll和exe的Settings的C/C++选项卡的Code Generation的Use Run-time liberary改成Debug Multithreaded DLL,在Release版本中改成Multithreaded DLL;这样使用一个CRT了——MSVCRT.DLL
详细解决方案:
1、
这是运行库文件时的错误。
解决方案:打开项目属性-->配置属性-->C/C++-->代码生成-->运行时库,改成多线程调试DLL
编译运行,然后可能会出项如下错误:
fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD
解决方案:打开项目属性-->配置属性-->常规-->项目默认值-->MFC的使用,选择“在共享 DLL 中使用 MFC”,就OK了~
如果上面这些都没用,那么就不是库文件运行的错误了,你可以试一下“清理解决方案”,然后重新生成,没准就行了。这个好像没有什么道理,可能是Visual Studio的一个bug吧
如果还不可以可以尝试下面的方法
2
一个模块一个堆,一个线程一个栈。
dll里malloc的内存,在exe里free会出错。
CRT(C运行时期库)不是使用进程缺省的堆来实现malloc(new中调用malloc)的,而是使用一个全局句柄 HANDLE _crtheap来分配内存的。这个_crtheap是在XXXCRTStartUp(CRT提供的进口点函数)中创建的。 由于CRT静态连接,则楼主的DLL里有也有一个CRT,因此也有一个_crtheap。而在dll中的new使用dll中的_crtheap句柄分配 堆,在exe中的delete使用exe中的_crtheap释放堆,当然失败!
1.所需头文件 #include <math.h>
2.使用方法 输入double类型参数,并返回double类型
注意:输入参数应为弧度制(radians),而不是角度制(degrees)
2_1.弧度制与角度制的转换 弧度制几何意义:弧度rad = 圆弧长度l ÷ 半径r,表示了在圆上移动l距离对应的角度。
常见的 = 3.1415926...便是弧度,一弧度 = 180°/ 角度
转换:deg = 180°/ * rad red = / 180° * deg
deg: 角度 rad : 弧度 3.示例 3_1.代码展示 在编写简单的小游戏 “见缝插针” 中,sin()、cos()函数便作为核心。
#define _CRT_SECURE_NO_WARNINGS #include <math.h> #include <easyx.h> #include <stdio.h> #define width 500 #define height 500 void Launch(ExMessage* msg, float Arg[], int* num, int* score)//发射函数 { if (peekmessage(msg, EM_MOUSE)) { if (msg->lbutton) { Arg[*num] = 0; (*num)++; (*score)++; Sleep(10);//按键消抖,防止按一下插入多根针 } } } int Lose(float Arg[], int* num)//失败函数 { if (*num > 1) { for (int i = 0; i < (*num) - 1; i++) { if (Arg[i] <= Arg[(*num) - 1] + 2 && Arg[i] >= Arg[(*num) - 1] - 2) { return 0; } } } return 1; } void Draw()//画图函数 { setlinecolor(RGB(255, 155, 65)); setfillcolor(YELLOW); fillcircle(width / 2, height / 2, 50); setfillcolor(RGB(255, 155, 65)); solidellipse(width / 2 - 20, height / 2 - 20, width / 2 - 10, height / 2); solidellipse(width / 2 + 10, height / 2 - 20, width / 2 + 20, height / 2); solidpie(width / 2 - 30, height / 2 - 10, width / 2 + 30, height / 2 + 30, 3.
apply(data, 2, function(x){gsub(pattern = ".*(替换字符).*", replacement = "\\2替换为",x) })
作者:临在、岑鸣、熊兮
一 导读 随着 BERT、Megatron、GPT-3 等预训练模型在NLP领域取得瞩目的成果,越来越多团队投身到超大规模训练中,这使得训练模型的规模从亿级别发展到了千亿甚至万亿的规模。然而,这类超大规模的模型运用于实际场景中仍然有一些挑战。首先,模型参数量过大使得训练和推理速度过慢且部署成本极高;其次在很多实际场景中数据量不足的问题仍然制约着大模型在小样本场景中的应用,提高预训练模型在小样本场景的泛化性依然存在挑战。为了应对以上问题,PAI 团队推出了 EasyNLP 中文 NLP 算法框架,助力大模型快速且高效的落地。
EasyNLP 背后的技术框架如何设计?未来有哪些规划?今天一起来深入了解。
二 EasyNLP简介 EasyNLP 是 PAI 算法团队基于 PyTorch 开发的易用且丰富的中文NLP算法框架,支持常用的中文预训练模型和大模型落地技术,并且提供了从训练到部署的一站式 NLP 开发体验。EasyNLP 提供了简洁的接口供用户开发 NLP 模型,包括NLP应用 AppZoo 和预训练 ModelZoo,同时提供技术帮助用户高效的落地超大预训练模型到业务。除此之外 EasyNLP 框架借助 PAI 团队在通信优化、资源调度方面的深厚积累,可以为用户提供大规模、鲁棒的训练能力,同时可以无缝对接 PAI 系列产品,例如 PAI-DLC、PAI-DSW、PAI-Designer 和 PAI-EAS,给用户带来高效的从训练到落地的完整体验。
EasyNLP 已经在阿里巴巴内部支持 10 多个 BU 的业务,同时在阿里云上提供了 NLP 解决方案和 ModelHub 模型帮助用户解决业务问题,也提供用户自定义模型服务方便用户打造自研模型。在经过内部业务打磨之后,我们将EasyNLP 推向开源社区,希望能够服务更多的 NLP 算法开发者和研究者,也希望和社区一起推动 NLP 技术特别是中文 NLP 的快速发展和业务落地。
开源项目地址:GitHub - alibaba/EasyNLP: EasyNLP: A Comprehensive and Easy-to-use NLP Toolkit
EasyNLP is a Comprehensive and Easy-to-use NLP Toolkit
省略生成libmodbus so库的过程,可查看我其余文章,有生成的详细过程。
so库的本质,是一堆 .o文件的集合,熟悉makefile的都知道,.o是.c文件经过编译后产生的object文件。不管是main.c还是mian.cpp,都要编译成main.o 然后main.o再链接其余的依赖库或者其他.o生成最终可执行目标文件。
C语言h文件里,是有函数的声明的,如果在cpp中用到了c.h声明的函数的话,就成了C++混合C编程。 c++因为支持函数重载,其编译规则不同于c,一般需要在c.h里加入extern "C" 来告诉编译器此段程序按C的规则来编译,
#ifdef __cplusplus
extern "C"
{
Cfunc()
}
#endif
在VSCODE里,如果需要使用C++编程,需要定义一下__cplusplus,具体在c_cpp_properties..json里的defines项目里加入。
然后编写个main.cpp函数,发现找不到C++的 iostream文件, 在settings.json文件里加上两行
就可以找到了。
文章目录 解决步骤如下 '前段时间用MacBook 16 Pro的时候发现:Brew这个命令没有' > 错误信息:zsh: command not found 找了许久,本人也捣鼓了许久,但是均未实际解决问题
估计原厂的 brew 是有的,可能有问题导致找不着
'后面发现了下面这篇博客:重新安装了brew命令,解决了问题' [Mac 错误提示:zsh: command not found: brew解决方法]
https://blog.csdn.net/wangyun71/article/details/108560873
2022年4月27日再次更新
可以直接使用官网的最新安装命令
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
如果还是不行的话可以上官网看看:HomeBrew官网
只不过官网非常慢,推荐使用下面的解决方案
解决步骤如下 Mac平台出现brew command not found问题解决方法 错误提示:zsh: command not found: brew 解决方法:mac 安装homebrew, 用以下命令安装,序列号选择中科大(1)的 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 分享一句我特别喜欢的话:每一天都是一个新的日子,走运当然是好的,不过我情愿做到分毫不差。这样,运气来的时候,你就有准备了。 ————海明威《老人与海》
在此之前我是个只会抄写原理图的工程师,每当遇到一个问题时,确需要解决很久,最根本的原因在于不明白其中的原理,这次补充一下单片机复位电路设计
1. 为什么要设计复位电路? 在做一件事情之前需要明白为什么要这么做,我们为什么要设计复位电路呢?一下几点原因是我总结出来的。
当你的电脑出现卡死等问题的时候,大部分人会直接重启(攻城狮除外),目前市面上很多电子产品都会用复位按键,所以一个成熟的产品是大概率需要复位的在产品调试阶段,尤其在调试软件的时候需要经常复位软件, 有些工程师也会采用软件复位, 不过软件复位没有硬件复位来的快捷。 以上两个理由足以说明为什么要复位电路了。
2. 复位时是具体做了哪些工作? 主要做的就是初始化每个寄存器,包括最重要的 PC 指针,不包括 RAM,然后单片机从复位地址开始执行程序。(欢迎补充)
3. 复位的前提需要什么? 3.1 复位信号 每种方式对应一种复位信号,比如硬件复位需要低电平,软件复位需要设置寄存器,看门狗复位需要配置寄存器,下面我们着重讲硬件复位,由STM32的数据手册可知,复位管脚低电平电压需要小于0.8V,输入脉冲时间为100ns。所以只需要在NRST管脚给小于0.8V的电压,持续时间为100ns就可以实现复位了。
3.2 CPU正常工作 为什么CPU需要正常工作?因为复位操作需要设计PC寄存器, 这涉及到软件层面, 故所以需要CPU能正常功能才能进行复位
3.3 晶振正常工作 为什么晶振需要正常工作?由3.2可知CPU需要正常功能, 那么CPU是靠什么正常工作的呢?显而易见CPU是靠晶振提供时钟频率的,所以晶振需要正常工作
3.4 电源正常工作 试想一下,如果电源不稳定,电压波动范围很大, 是不是会影响CPU的运行?的确是这样子的,电源一定要稳定。
3.5 复位信号是不是只要满足低电平时间大于100ns就可以呢? 100ns时间是很短的,很容易达到, 但是有没有试想一下如果只给100nS,那么此时是由复位信号了, 但是电源还没到VCC,晶振还没起振? 这一定存在的,因为上电时,Vcc 的上升时间约为 10ms,而振荡器的起振时间取决于振荡频率,如晶振频率为 10MHz,起振时间为 1ms;晶振频率为 1MHz,起振时间则为 10ms。目前STM32单片机大部分采用8M高速晶振,那么主要问题出在电源的上升时间,为了保证系统的稳定性, 这里我们去2倍吧,20ms的低电平时间。
4. 怎么设计复位电路? 目前市面上的复位电路大部分采用RC复位,这种方式成本低廉,稳定性好,被用于大部分的设计中。
4.1 RC充电原理 4.1.1 什么是电容充电? 电荷在电容器极板上聚集的过程叫做充电过程,这个过程不是瞬间完成的,而是需要一段时间,时间取决于电路的组成元件。
4.1.2 基本RC充电电路 如图1所示,开关闭合的瞬间,电子在电源的作用下从位于电容顶部的极板沿电路移动并聚集到位于底部的极板上,导致在顶部极板聚集了正电荷,在底部极板聚集了负电荷。
开始时,电子的转移非常迅速,随后由于两个极板间产生的电压逐渐接近于所加的电源电压,移动速度减慢。最终,当电容两个极板间的电压达到所加的电源电压时,电子移动过程停止,这时候,极板上的净电荷是:
电荷在极板上聚集的过程叫做瞬态过程 —— 电压或者电流从一个稳态到另一个稳态的过程。电压-时间变化过程曲线如图2所示:
注意:vc 和 Vc 是有区别的。vc是变量,Vc是常量。
从图2中可以看出, t=0s时,电容器两端电压是 0V;一开始,电荷聚集的速度很快,导致电压急剧增加。随着时间的推移,电荷聚集的速度减慢,导致电压变化的速率也减缓,即电压继续增加,但速率变慢。最终,由于极板间电压接近外加电压,充电速率极低,直到极板间电压等于外加电压 —— 瞬态过程结束。
Java设计模式
目录
设计模式 3
1.1 创建型模式 4
1.1.1 工厂方法 4
1.1.2 抽象工厂 6
1.1.3 建造者模式 10
1.1.4 单态模式 13
1.1.5 原型模式 15
1.2 结构型模式 17
1.2.1 适配器模式 17
1.2.2 桥接模式 19
1.2.3 组合模式 23
1.2.4 装饰模式 26
1.2.5 外观模式 29
1.2.6 享元模式 32
1.2.7 代理模式 34
1.3 行为型模式 37
1.3.1 责任链模式 37
1.3.2 命令模式 40
1.3.3 解释器模式 43
1.3.4 迭代器模式 45
1.3.5 中介者模式 49
1.3.6 备忘录模式 52
1.3.7 观察者模式 54
一 首先查看是否已经安装NVIDIA显卡驱动 在terminal运行如下代码:
sudo nvidia-smi 如果显示如下,则表示已经安装,跳过本章.
注意: nvidia驱动版本是470.103.01, 这也是linux推荐的版本, 若没有显示,则继续下面安装 二 查看推荐安装的nvidia 版本 $ ubuntu-drivers devices 此处, 只安装 recommended version, 其他不管 . 安装 nvidia-driver-470
三 添加源 sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt-get update 如果最初已经添加或者已经更新过了,可以省略该步骤 也可以跟随该步骤. 四 进入软件和更新进行安装 进入ubuntu的software &updates. 记住,安装上面推荐的470, 此处的470-server我们不选,这是服务器的. 安装后 close
五. 最后 reboot 在terminal中输入reboot重启.
然后再打开terminal, 输入第一步的,查看是否成功安装
如果安装了,想删除,在terminal输入以下代码.
sudo apt-get purge nvidia* sudo apt-get autoremove sudo reboot 不过 sudo apt-get autoremove 也可以考虑不运行,因为本人运行后导致分辨率出现问题.又重新调整了分辨率(参考本博客配置教程),,若不运行 sudo apt-get autoremove无法删除nvidia成功,那只能尝试添加运行 sudo apt-get autoremove
树莓派安装centos7之后发现根目录只有2G的容量,UP主的SD卡是127G。下面演示调整到127G(最大)的方法。
第一步:
查看一下系统挂载信息:
[root@bogon ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 2.0G 1.4G 621M 69% /
devtmpfs 424M 0 424M 0% /dev
tmpfs 457M 0 457M 0% /dev/shm
tmpfs 457M 12M 445M 3% /run
tmpfs 457M 0 457M 0% /sys/fs/cgroup
/dev/mmcblk0p1 286M 54M 233M 19% /boot
tmpfs 92M 0 92M 0% /run/user/0
查看一下磁盘分区情况,总容量为15.9G。
[root@bogon ~]# fdisk -l
磁盘 /dev/mmcblk0:127.9 GB, 127865454592 字节,127865454592 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
查看接口信息——display ip interface brief查看路由表——display ip routing-table查看vlanif的IP地址配置——display ip interface brief查看switch接口配置模式——display port vlan查看ospf邻居建立详情——display ospf peer brief查看ospf的链路状态数据库——display ospf lsdb查看地址池的信息——display ip pool查看DHCP中继信息——display dhcp relay all查看STP的端口角色信息——display stp brief查看ospf的路由表——display ip routing-table protocol ospf
线程概念 线程是执行任务的路径,也是分配CPU时间的最小单位,也可以说线程是独立调度和分派的基本单位。
线程与进程区别 程序运行起来就是进程,一个程序包含一个或多个进程,需要内存和CPU资源进行运算执行,每个进程有自己独立的内存空间,它是重量级的,需要的系统资源比较多。一个进程包含多个线程,多个线程共享一个进程的内存空间,每个线程单独执行一个任务,它是轻量级的,需要的系统资源比较少。 线程的实现 一、继承Thread类 继承Thread类重写run方法创建线程对象,调用start方法 public class MyThread extends Thread{ /** * 执行线程任务的方法 */ public void run(){ //Thread.currentThread()是获得系统当前执行的线程 System.out.println(Thread.currentThread().getName()+"线程执行了!!!"); } public static void main(String[] args) { //主线程中执行 System.out.println(Thread.currentThread().getName()+"线程执行了!!!"); //创建线程对象 MyThread thread1 = new MyThread(); MyThread thread2 = new MyThread(); //启动线程 thread1.start(); thread2.start(); } } 这里有两个问题在面试时有可能会问到
启动线程使用start()和run()有什么区别? 启动线程要使用start()方法,只有start()方法会去创建并执行线程,运行任务,而run()方法里面写的只是我们要运行的任务,它不会启动线程。
线程执行为什么没有规律? 因为线程的执行是抢占式,它们去抢CPU,哪个线程抢到了CPU,哪个线程才执行。
二、实现Runnable接口 实现Runnable接口实现run方法创建自定义线程对象,作为参数传入Thread对象调用start方法 public class MyRunnable implements Runnable{ /** * 实现run方法 */ @Override public void run() { System.out.println("当前执行的线程是:"+Thread.currentThread().getName()); } public static void main(String[] args) { //创建Thread对象,传入Runnable对象 Thread thread1 = new Thread(new MyRunnable()); //调用start方法 thread1.
什么是 REST? REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。
表述性状态转移是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML(标准通用标记语言下的一个子集)以及HTML(标准通用标记语言下的一个应用)这些现有的广泛流行的协议和标准。REST 通常使用 JSON 数据格式。
HTTP 方法 以下为 REST 基本架构的四个方法:
GET - 用于获取数据。
PUT - 用于更新或添加数据。
DELETE - 用于删除数据。
POS T- 用于添加数据。
RESTful Web Services Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。
基于 REST 架构的 Web Services 即是 RESTful。
由于轻量级以及通过 HTTP 直接传输数据的特性,Web 服务的 RESTful 方法已经成为最常见的替代方法。可以使用各种语言(比如 Java 程序、Perl、Ruby、Python、PHP 和 Javascript[包括 Ajax])实现客户端。
RESTful Web 服务通常可以通过自动客户端或代表用户的应用程序访问。但是,这种服务的简便性让用户能够与之直接交互,使用它们的 Web 浏览器构建一个 GET URL 并读取返回的内容。
更多介绍,可以查看:RESTful 架构详解
创建 RESTful 首先,创建一个 json 数据资源文件 users.json,内容如下:
{ "user1" : { "
目录 性质:左旋与右旋插入情景1:红黑树为空树情景2:插入结点的Key已存在情景3:插入结点的父结点为黑结点情景4:插入节点的父节点为红色插入情景4.1:叔叔结点存在并且为红结点插入情景4.2:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的左子结点插入情景4.2.1:新插入节点,为其父节点的左子节点(LL红色情况)插入情景4.2.2:新插入节点,为其父节点的右子节点(LR红色情况) 插入情景4.3:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的右子结点插入情景4.3.1:新插入节点,为其父节点的右子节点(RR红色情况)插入情景4.3.2:新插入节点,为其父节点的左子节点(RL红色情况) 性质: 红黑树是一种特殊平衡二叉查找树,主要用它存储有序的数据,提供高效的数据检索,时间复杂度为O(lgn),每个节点都有一个标识位表示颜色,红色或黑色,有如下5种特性:
1、每个节点要么红色,要么是黑色;
2、根节点一定是黑色的;
3、每个空叶子节点必须是黑色的;(null即为叶子节点)
4、如果一个节点是红色的,那么它的子节点必须是黑色的;
5、从一个节点到该节点的子孙节点的所有路径包含相同个数的黑色节点;
左旋与右旋 左旋:
右旋:
插入 情景1:红黑树为空树 最简单的一种情景,直接把插入结点作为根结点就行
注意:根据红黑树性质2:根节点是黑色。还需要把插入结点设为黑色。
情景2:插入结点的Key已存在 处理:更新当前节点的值,为插入节点的值
情景3:插入结点的父结点为黑结点 当插入结点的父节点是黑色时,并不会影响红黑树的平衡,直接插入即可,无需做自平衡。
情景4:插入节点的父节点为红色 再次回想下红黑树的性质2:根结点是黑色。如果插入节点的父结点为红结点,那么该父结点不可能为根结点,所以插入结点总是存在祖父结点。
这一点很关键,因为后续的旋转操作肯定需要祖父结点的参与。
插入情景4.1:叔叔结点存在并且为红结点 依据红黑树性质4可知,红色节点不能相连 ==> 祖父结点肯定为黑结点;
因为不可以同时存在两个相连的红结点。那么此时该插入子树的红黑层数的情况是:黑红红。显然最简单的处理方式是把其改为:红黑红
处理:
1.将P和U节点改为黑色
2.将PP改为红色
3.将PP设置为当前节点,进行后续处理
可以看到,我们把PP结点设为红色了,如果PP的父结点是黑色,那么无需再做任何处理;
但如果PP的父结点是红色,则违反红黑树性质了。所以需要将PP设置为当前节点,继续做插入操作自平衡处理,直到平衡为止。
插入情景4.2:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的左子结点 注意:单纯从插入前来看,叔叔节点非红即空(NIL节点),否则的话破坏了红黑树性质5,此路径会比其它路径多一个黑色节点。
插入情景4.2.1:新插入节点,为其父节点的左子节点(LL红色情况) 处理:
1.变颜色:将P设置为黑色,将PP设置为红色
2.对PP节点进行右旋
插入情景4.2.2:新插入节点,为其父节点的右子节点(LR红色情况) 处理:
1.对P进行左旋
2.将P设置为当前节点,得到LL红色情况
3.按照LL红色情况处理(1.变颜色 2.右旋PP)
插入情景4.3:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的右子结点 该情景对应情景4.2,只是方向反转,直接看图。
插入情景4.3.1:新插入节点,为其父节点的右子节点(RR红色情况) 处理:
1.变颜色:将P设置为黑色,将PP设置为红色
2.对PP节点进行左旋
插入情景4.3.2:新插入节点,为其父节点的左子节点(RL红色情况) 处理:
1.对P进行右旋
2.将P设置为当前节点,得到RR红色情况
3.按照RR红色情况处理(1.变颜色 2.左旋PP)
一,检查网络适配器,是否禁用vmware的虚拟机网卡
二,检查vmware net8的地址是否和虚拟机的ip处于同一网段
选中①,鼠标右键查看属性,找到Internet协议版本4,点击属性进行查看
三,检查系统的vmware服务是否启动
四,检查虚拟机的网络适配器是否连接
五,在vmware控制台登录linux,查看是否有ip地址
[root@Linux-Centos7 ~]# ip a
# 重启网卡命令: systemctl restart network
六,查看ssh服务的端口状态
netstat -lntup (sshd 22端口)
七,检查sshd远程服务是否开启
systemctl status sshd
kafka概述 一、kafka概述1.1 定义1.2 消息队列1.2.1 传统消息队列的应用场景1.2.2 消息队列的两种形式 1.3 Kafka 基础架构 二、kafka安装部署2.1安装部署2.1.1.jar包下载2.1.2.解压到指定的文件夹下2.1.3.创建两个文件夹以供后续使用2.1.4. 修改配置文件(1)修改zookeeper.properties 文件(2) 修改server.properties 文件 2.2启动2.2.1.启动 kafka 内置的 zookeeper2.2.2.启动 kafka 服务2.2.3.创建一个名为 test1 的 topic 测试主题 kafka2.2.4.创建消息生产者生产消息2.2.5.创建消息消费者接收消息2.2.6.测试消息发送和接收 三、kafka架构深入理解3.1 Kafka 工作流程3.1.1 写入方式3.1.2 分区(Partition)1.启动zookeeper2 启动服务3 创建主题4 查看主题5 查看主题列表 3.2 Kafka 存储机制3.2.1 数据分片3.2.2 log分段:3.2.3 日志的清除策略以及压缩策略 3.3 Kafka 生产者3.3.1 数据可靠性保证 3.4 Kafka 消费者3.4.1概念3.4.2 消费方式1.消费位移确认2 以时间戳查询消息3 消费速度控制 3.5 Kafka 高效读取数据 四、kafka API4.1 Producer API4.1.1 消息发送流程4.1.2 异步发送 API4.1.3 同步发送 API 4.2 Consumer API4.2.1 自动提交 offset4.2.2 手动提交 offset4.2.3 自定义存储 offset 4.
文章目录 1、出现的错误:1、代码展示2、图片展示问题: 2、 问题解决过程1、在 package.json文件中 2、main.js中添加一句话3、下面内容注释掉参考的博客 1、出现的错误: 1、代码展示 E:\librarycat\admin>npm run serve > app@0.1.0 serve E:\softwork\Practice_Yg\daiding\librarycat\admin > vue-cli-service serve INFO Starting development server... 98% after emitting CopyPlugin ERROR Failed to compile with 1 error 下午2:51:47 error in ./src/App.vue?vue&type=style&index=0&lang=scss& Syntax Error: Error: Loading PostCSS Plugin failed: Cannot find module 'autoprefixer' Require stack: - E:\softwork\Practice_Yg\daiding\librarycat\admin\noop.js (@E:\softwork\Practice_Yg\daiding\librarycat\admin\package.json) at Array.map (<anonymous>) @ ./node_modules/@vue/cli-service/node_modules/vue-style-loader??ref--8-oneOf-1-0!./node_modules/@vue/cli-service/node_modules/css-loader??ref--8-oneOf -1-1!./node_modules/@vue/cli-service/node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/@vue/cli-service/node_modules/postcss-loader/ src??ref--8-oneOf-1-2!./node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??re f--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=0&lang=scss& 4:14-563 15:3-20: 5 16:22-571 @ ./src/App.vue?vue&type=style&index=0&lang=scss& @ ./src/App.vue @ .
目录
指令格式
寻址方式
指令格式 一、指令的一般格式
指令字:二进制的形式,由操作码和地址码构成
操作码:操作特性与功能地址码:指定参与操做的操作数的地址 二、操作码
操作码字段的位数取决于指令系统的规模
若为n位,则有 2^n种操做指令
三、地址码
一条指令中有多少个地址码的字段就是几地址的指令
SS型指令:两个操作数都在寄存器中RS型指令:一个在寄存器,一个要访问主存RR型指令:两个都在主存中 其中速度:SS < RS < RR
四、指令字长度
机器字长:机器一次能处理的二进制长度
指令字长:一个指令字中包含的二进制位数(半字长、单字长、双字长等)
五、指令助记符
用英文缩写来表示操做,指令的种数取决于操作码的位数
寻址方式 直接寻址E = D间接寻址E = (D)寄存器寻址E = R相对寻址E = (PC) + D基址寻址E = (R1) + D 变址寻址E = (R2) + D 寄存器间接寻址E = (R) 其中D为形式地址,E为操作数,R为寄存器,R1为基址寄存器,R2为变址寄存器
立即寻址:形式地址A就为操作数直接寻址:有效地址由形式地址给出间接寻址:有效地址由形式地址间接给出寄存器寻址:形式地址由寄存器的编号给出相对寻址:程序计数器加上形式地址基址寻址:基址寄存器加上形式地址变址寻址:变址寄存器加上形式地址
原创地址: http://t.csdn.cn/mKnNx
**
http://t.csdn.cn/xWk4P **
项目场景: 启动数据中台项目
问题描述 npm run dev前运行npm install安装依赖包报错
解决方案: 在当前目录下进行node-sass 的数据源没设置:
1.npm config set sass_binary_site=https://npm.taobao.org/mirrors/node-sass
2.执行 npm install node-sass
3.npm run dev 重启项目成功
oracle递归查询 1 数据准备2 start with connect by prior递归查询2.1 查询所有子节点2.2 查询所有父节点2.3 查询指定节点的,根节点2.4 查询巴中市下行政组织递归路径 3 with递归查询3.1 with递归子类3.2 递归父类 1 数据准备 create table area_test( id number(10) not null, parent_id number(10), name varchar2(255) not null ); alter table area_test add (constraint district_pk primary key (id)); insert into area_test (ID, PARENT_ID, NAME) values (1, null, '中国'); insert into area_test (ID, PARENT_ID, NAME) values (11, 1, '河南省'); insert into area_test (ID, PARENT_ID, NAME) values (12, 1, '北京市'); insert into area_test (ID, PARENT_ID, NAME) values (111, 11, '郑州市'); insert into area_test (ID, PARENT_ID, NAME) values (112, 11, '平顶山市'); insert into area_test (ID, PARENT_ID, NAME) values (113, 11, '洛阳市'); insert into area_test (ID, PARENT_ID, NAME) values (114, 11, '新乡市'); insert into area_test (ID, PARENT_ID, NAME) values (115, 11, '南阳市'); insert into area_test (ID, PARENT_ID, NAME) values (121, 12, '朝阳区'); insert into area_test (ID, PARENT_ID, NAME) values (122, 12, '昌平区'); insert into area_test (ID, PARENT_ID, NAME) values (1111, 111, '二七区'); insert into area_test (ID, PARENT_ID, NAME) values (1112, 111, '中原区'); insert into area_test (ID, PARENT_ID, NAME) values (1113, 111, '新郑市'); insert into area_test (ID, PARENT_ID, NAME) values (1114, 111, '经开区'); insert into area_test (ID, PARENT_ID, NAME) values (1115, 111, '金水区'); insert into area_test (ID, PARENT_ID, NAME) values (1121, 112, '湛河区'); insert into area_test (ID, PARENT_ID, NAME) values (1122, 112, '舞钢市'); insert into area_test (ID, PARENT_ID, NAME) values (1123, 112, '宝丰市'); insert into area_test (ID, PARENT_ID, NAME) values (11221, 1122, '尚店镇'); 2 start with connect by prior递归查询 2.
Mac 使用Charles进行手机https抓包(超详细教程) 前言 还不知道怎么用手机连内网地址进行测试?
还不知道怎么用Charles抓手机HTTPS的包?
希望下面会对你有些帮助。
操作指南 操作环境:
电脑系统:Mac OS手机系统:iOS 12及以上/AndroidCharles版本:V4.5.6 第一步:安装Charles证书到Mac 1.启动Charles,选择Help-->SSL Proxying→Install Charles Root Certificate
image.png
2、此时会启动“钥匙串访问”APP,并找到刚开安装好的证书,证书名字:Charles Proxy CA,找不到的可以搜索框搜下。
image.png
3、选中该证书,点击显示简介。
image.png
4、更改证书信任权限。更改为始终信任,并关闭窗口输入密码保存。
image.png
5、移动复制该证书到“系统”里面。此时电脑端的证书就配置完毕了!
image.png
6、设置HTTPS端口抓包,点击Charles-->Proxy-->SSL Proxying Settings,出现如下弹窗,点击"Enable SSL Proxying",点击“Add”
image.png
7、按照图中输入,点击保存。至此,电脑端配置已全部完成!
image.png
第二步:安装Charles证书到手机 前提:
1、首先查看电脑IP地址,点击Charles-->Help→Local IP Address
image.png
2、手机必须和电脑在同一个Wi-Fi下。
iPhone证书安装: 1、iPhone,Wi-Fi设置代理。步骤:设置→WIFI -->点击Wi-Fi旁边的i
IMG_4102.PNG
2、划到底部,点击配置代理
IMG_4103.PNG
3、配置代理,IP就是你电脑的IP,端口输入8888,点击存储
IMG_4104.PNG
4、然后打开Safari浏览器,访问:chls.pro/ssl,此时电脑上连接提示,点击allow允许。
image.png
5、此时手机会提示下载描述文件,点击允许
IMG_4105.PNG
6、保存后,点击 设置-->通用→描述文件,安装刚下载好的文件
IMG_4107.PNG
7、安装完成后,点击 设置-->通用→关于本机,下拉到底部,点击证书 信任设置,把刚信任开关打开。
IMG_4109.PNG
8、大功告成,此时你就可以愉快的抓HTTPS的包了。以及访问公司内网。
Android证书安装: 以小米手机为例。
1、设置Wi-Fi代理。设置→WI-FI→代理设置,IP就是你电脑的IP,端口输入8888,保存
image.png
2、使用Chrome浏览器访问"chls.pro/ssl"(注意:一定要使用Chrome浏览器,安卓国产浏览器会将证书视为下载文件,不能直接安装),此时电脑上连接提示,点击allow允许。
小程序框架介绍
注册页面
生命周期
页面路由
事件
一、 事件 什么是事件
事件是视图层到逻辑层的通讯方式。事件可以将用户的行为反馈到逻辑层进行处理。事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。事件对象可以携带额外信息,如 id, dataset, touches。 事件分类
事件分为冒泡事件和非冒泡事件:
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。(eg:bindtap)非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。(eg:catchtap) 普通事件绑定(冒泡事件)————事件绑定的写法类似于组件的属性,如:
<view bindtap="handleTap"> Click here! </view> 如果用户点击这个 view ,则页面的 handleTap 会被调用。
绑定并阻止事件冒泡————除 bind 外,也可以用 catch 来绑定事件。
与 bind 不同, catch 会阻止事件向上冒泡。
例如在下边这个例子中,点击 inner view 会先后调用handleTap3和handleTap2 (因为tap事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递), 点击 middle view 会触发handleTap2,点击 outer view 会触发handleTap1。 <view id="outer" bindtap="handleTap1"> outer view <view id="middle" catchtap="handleTap2"> middle view <view id="inner" bindtap="handleTap3"> inner view </view> </view> </view> 注: 如果有弹出层,要阻止冒泡,否则会穿透。
转载自https://www.jianshu.com/p/1ec6075c0ab6
性别识别是一个2分类问题,网上应该有不少的研究。比如商汤/旷世科技 早已经将人脸属性继承到SDK中,可以供API在线调用,还有针对Android, ios的SDK, 本人测试过,速度很精度都很不错。
简单起见,直接采用预训练模型微调的方式训练一个性别分类器。
网络模型选择 torchvision.models中集成了几个常见的网络模型,ResNet, AlexNet, VGG, DenseNet, SqueezeNet。 AlexNet和VGG模型文件都很大,AlexNet大约230M, VGG更大,下载特别慢,而且这么大的模型文件对于以后往移动平台移植很不利。
SqueezeNet有所了解,这是一个轻量化的网络,网络名称squeeze就是压缩的意思。作者文章介绍到SqueezeNet与AlexNet精度相当,模型参数大大降低。因此决定采用SqueezeNet进行实验,如果效果不错可以考虑Android端的移植。
SqueezeNet SqueezeNet是一个轻量化的网络 ,模型文件比较小,大约4M多,相比AlexNet 230M,算是非常轻量化。
采用pytorch 打印出的SqueezeNet的网络结构。
数据集制作 UTKFace数据集进行训练
https://susanqq.github.io/UTKFace/
训练集,验证集,测试集划分 UTKFace数据需要从Google Drive下载,链接包含2个压缩包。 采用第一个压缩包crop_part1.tar.gz的数据,规模稍微小,先看看效果。训练:验证:测试 = 6:2:2
总共9780张图像训练数据5000+验证数据约2000测试数据约2000
由于UTKFace数据的按照年龄排序的,因此在划分数据时候全部采用随机采样。
划分结果:
使用pytorch加载数据 继承Dataset类, override __len()__, __getitem()__方法采用Dataloder包装,按照mini_batch方式读取 from torch.utils.data import Dataset import torch import torchvision.transforms as transforms import PIL.Image as Image import os import numpy import shutil import random class UTKFaceGenderDataset(Dataset): def __init__(self, root, txt_file, transform=None, target_transform=None): self.root = root self.
一、什么是软考 计算机技术与软件专业技术资格(水平)考试(简称:软考)是由国家人力资源和社会保障部、工业和信息化部领导下的国家级考试,其目的是科学、公正地对全国计算机与软件专业技术人员进行职业资格、专业技术资格认定和专业技术水平测试。
软考既是职业资格考试,又是职称资格考试,可以评职称,并且软考报考任何级别不需要学历、资历条件,只要达到相应的专业技术水平就可以报考相应的级别。
软考具体科目如下:
二、软考的作用 软考主要有以下5个作用:
1.升职加薪:有部分公司规定想要升职就必须要有软考证书
2.积分落户:部分城市有积分落户的政策,证书就是其中一个加积分的方式
3.评职称:软考中级评中级职称,高级评副高级职称。
4.抵扣个税:抵扣当年个税3600元以内
5.个人能力的提升:不管有没有拿到证书,在备考的过程中都会学习到很多新的知识,提高个人能力,
如果还有什么疑问,可以和我私聊讨论!
三、软考高级哪个更容易过? 如图所视,软考高级一共有5个资格考试,分别是信息系统项目管理师、系统分析师、系统架构设计师、网络规划设计师和系统规划与管理师。
我看了有很多文章都在说通过率方面的问题,我这里就不多说了,就从考核内容和岗位方面来说说!
下图是软考高级资格考试的考核内容及相关岗位描述:
从上图我们也能知道信息系统项目管理师考试主要是理论知识,更多的是面向管理岗位,考试也相对简单,而其他四个考试则是技术知识,更多的是面向技术岗位,考试相对较难。
因为大家都是想考一个容易过的软考高级证书,那是可以考信息系统项目管理师的,因为它都是一些理论知识,只要熟记知识点就没有太大关系了,就像我们考语文一样,有选择题、分析题和作文题,零基础也能考过的。
Java基础篇
说说什么是SaaS SaaS也就是常说的软件及服务,是一种软件交付模型,SaaS不向用户交付最终的软件产品,软件作为用户使用的服务而存在。它就相当于软件中的租借而非购买。
也就是说,我只需要能连接上互联网,并且给saas平台交租金,我就能用saas平台给我提供的服务。
SaaS数据隔离方案有哪些 、为每个租户提供一个独立的数据库系统 实现方式是所有租户共享同一个应用,但应用后端会连接多个数据库系统,一个租户单独使用一个数据库系统。这种方案的用户数据隔离级别最高,安全性最好,租户间的数据能够实现物理隔离。但成本较高。
、每个租户提供一个表空间 就是所有租户共享同一个应用,应用后端只连接一个数据库系统,所有租户共享这个数据库系统,每个租户在数据库系统中拥有一个独立的表空间。
、按照租户的id区分租户 这种方案是多租户方案中最简单的设计方式,即在每张表中都添加一个用于区分租户的字段(如租户id或租户代码)来标识每条数据属于哪个租户,其作用很像外键。当进行查询的时候每条语句都要添加该字段作为过滤条件,其特点是所有租户的数据全都存放在同一个表中,数据的隔离性是最低的,完全是通过字段来区分的。
说说HashMap的底层实现 在JDK1.8之前
HashMap是数组 + 链表结合在一起使用也就是 散列表。HashMap key的hashCode经过扰动函数处理过后得到hash值,然后通过(n -1) & hash判断当前元素存放的位置(n指的是数组长度),如果当前位置存在元素的话,就判断元素与要存入的元素的hash值以及key是否相等,如果相同的话直接覆盖,不相同就通过拉链法解决冲突。
所谓的扰函数指的就是HashMap的hash方法,使用扰动函数可以减少hash碰撞。
所谓的拉链法就是 将链表和数组相结合,也就是说创建一个链表数组,数组中的每一格就是一个链表,如果遇到hash冲突,则将冲突的值加到链表中即可。
JDK1.8之后
相比较于JDK1.8之前,JDK1.8之后的HashMap在解决冲突时有了较大的变化,当链表的长度大于阈值(默认为8)之后就会将链表转换为红黑树,如果当前数组的长度小于64,那么会选择先进行数组扩容,而不是转换为红黑树,链表转换为红黑树以减少搜索的时间。
HashMap的长度为什么是2的幂次方?
为了能够让HashMap存取高效,尽量减少碰撞,也就是要尽量的把数据分配均匀,所以使用了2的幂次方。
HashMap多线程操作导致死循环问题
主要原因就是在于并发下的Rehash会造成元素空间形成一个循环链表,不过JDK1.8版本之后解决了这个问题,但是还是不建议在多线程下使用HashMap,因为多线程下的HashMap还是会存在其他问题比如数据丢失,并发下推荐使用CurrentHashMap,这个是线程安全的。
说说HashMap的扩容机制 (1)、HashMap1.8扩容时会首先检测数组元素的个数,因为loadFactor的默认值是0.75,它含有的桶的数量默认是16,它的阈值是 16 * loadFactor,当它哈希桶占用的容量大于12的时候,就会触发扩容。就把数组的大小扩展为 2 * 16 = 32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知了HashMap的个数,那么最好就提前预设元素的个数能够有效的提高性能,
(2)、如果当某个桶中的链表长度达到8的进行链表扭转为红黑树的时候,会检查总的桶数是否小于64,如果总桶数小于64也会进行扩容。
(3)、当new完HashMap之后,第一次往HashMap进行put操作时,首先会进行扩容
说说数据库三大范式 第一范式:每一列都必须是原子性的
第二范式:首先必须满足第一范式,并且所有非主属性都完全依赖于主码
第三范式:满足第二范式,所有非主属性对任何候选关键字都不存在依赖传递。也就是说每个属性和主键都有直接关系而不是间接关系。
链表和数组 数组简单易用,在实现上使用的是连续的内存空间,这样就可以借助CPU的缓存机制,预读数组中的数据,所以访问效率效率很高,而链表在内存中并不是连续存储的,无法利用CPU的缓存机制,没有办法有效预读。
如果你的代码对内存的使用非常苛刻,那么数组就更适合你,因为链表中的每个节点都需要消耗额外的内存空间去存储一份指向下一个节点的指针,所以内存消耗会翻倍,而且对链表频繁的插入和删除操作,还会导致频繁的内存申请和释放,容易造成内存碎片,Java就会导致频繁的GC。
如何实现一个LRU缓存淘汰算法 维护一个有序单链表,越靠近链表尾部的节点就是越早之前访问的。当有一个新的数据被访问的时候,我们从链表头开始顺序遍历链表。
如果此数据没有在缓存链表中,又可以分为两种情况
、如果此时的缓存未满,,直接将新的数据插入到链表的头。、如果此时缓存已满,则链表尾节点删除,将新的数据节点插入到链表头部。 但是这种思路时间复杂度会比较高。
如何优化?
引入Hash,来记录每个数据的位置,将换粗访问的时间复杂度直接降到O(1),
使用双向链表
可以通过 O(1) 的时间淘汰掉双向链表的尾部,每次新增和访问数据,都可以通过 O(1)的效率把新的节点增加到对头,或者把已经存在的节点移动到队头。
HashMap 的PUT过程 HashMap的put操作做了什么?
HashMap的是由数组和链表构成的,JDK7之后加入了红黑树处理哈希冲突。put操作的步骤是这样的:
根据key值计算出哈希值作为数组下标。如果数组的这个位置是空的,把k放进去,put操作就完成了。
如果数组位置不为空,这个元素必然是个链表。遍历链表逐一比对value,如果value在链表中不存在,就把新建节点,将value放进去,put操作完成。
如果链表中value存在,则替换原节点的value,put操作完成。
如果链表节点数已经达到8个,首先判断当前hashMap的长度,如果不足64,只进行resize,扩容table,如果达到64就将冲突的链表为红黑树。
文章目录 背景扩展AC自动机 背景 最近参与了某业务系统的开发, 需要根据城市的名字简称,找到其官方的完整名称。比如云南的大理,其实其完整的名称是大理白族自治州。可以参考官方的行政区划,点这里。
通常来说,城市的简称,都是其完整名称的前缀。所以任务就转化成了:根据前缀,在一堆字符串中,找出满足条件的字符串。
Trie树可以派上用场,只需要对全国所有城市的完整名称,建一颗Trie树即可。这种前缀补全的功能,也有其他的一些经典应用,比如在命令行下,输入一个命令的前缀,或文件名的前缀,敲下 Tab,能够进行自动补全,也是利用了Trie树这种数据结构。
Trie树的原理参考我之前的这篇文章
代码如下
import java.util.*; /** * @Author yogurtzzz * @Date 2022/3/31 15:57 * * 利用 Trie 树实现字符串的存储和快速查找 * * 该类的功能是, 给定一个字符串数组 list , 给定一个字符串 s * 返回在 list 中所有前缀为 s 的字符串 * * 简单地说, 该类的功能是做字符串前缀匹配, 或者自动补全 * * 比如, 输入 "内蒙", 能够查找到完整的名称为 "内蒙古自治区" **/ public class TrieTree { private Node root = new Node('0'); /** * 添加一个字符串到 [集合] 中 * **/ public void addString(String s) { Node cur = root; for (int i = 0; i < s.
PIL踩坑记录:读取图片方向异常(yolov5标签错位) 奇怪的现象 今天用 YOLOv5 做项目时,对数据集的标记出现了奇怪的现象,在下述测试用例中可明显看到,标记框偏离了物体,故发文阐述原因和解决方法. ——©️ Sylvan Ding 转载需注明出处!
下载了一份数据集UNIMIB2016,使用 PIL 读取其中一张照片并标记 bbox.
from PIL import Image img_name = '20151127_120643.jpg' img = Image.open(img_name) img.show() from PIL import ImageDraw from PIL import ImageFont label_name = '20151127_120643.txt' with open(label_name) as file: items = file.readlines() draw = ImageDraw.Draw(img) for item in items: item = item.split() # convert str to int item[1:] = list(map(int, item[1:])) # draw bbox draw.rectangle([item[1], item[2], item[5], item[6]], outline="red", width=20) # add text about order of the points for j, i in enumerate([1, 3, 5, 7]): j = j + 1 draw.
完整工程 工程目录结构
Code import torch import torch.optim as optim import torch.nn as nn from torch.utils.data import DataLoader from torchvision.datasets import ImageFolder import torchvision.models as models import torchvision.transforms as transforms import numpy as np import copy # --------------------------------------------------------- # 载入预训练的AlexNet模型 model = models.alexnet(pretrained=True) # 修改输出层,2分类 model.classifier[6] = nn.Linear(in_features=4096, out_features=2) # -------------------------数据集---------------------------------------------------- transform = transforms.Compose([transforms.Resize((227,227)), transforms.ToTensor()]) train_dataset = ImageFolder(root='./data/train', transform=transform) val_dataset = ImageFolder(root='./data/val', transform=transform) train_dataloader = DataLoader(dataset=train_dataset, batch_size=4, num_workers=4, shuffle=True) val_dataloader = DataLoader(dataset=val_dataset, batch_size=4, num_workers=4, shuffle=False) # ------------------优化方法,损失函数-------------------------------------------------- optimizer = optim.
vue+django项目部署 部署相关概念项目服务器架构反向代理 前端部署dockerdocker安装(mac)使用常见命令 nginx下载安装nginx镜像 域名解析 后端部署MySQL镜像Redis镜像部署前处理从服务端项目中收集静态文件uwsgi服务器执行django项目容器中配置运行环境静态文件的访问支持 部署相关概念 项目服务器架构 我们希望别人能够访问到我们的项目,包括界面,以及处理客服端发过来请求的API,这就需要我们把项目放到公网上面。
一般的服务器架构如上图:
把vue客户端放到一个服务器中,供用户来访问静态页面。把django服务器端放到另外一个服务器,为用户提供服务。但是会存在一个问题:开发的时候环境一般都是单线程的,而且django大概只支持4-5万的同时访问量(并发量),那么,如果只有一台django服务器,当有好多人来请求服务器的时候,服务器就崩溃了。解决放案就是把服务端分放在多个服务器中,分担高并发压力。把服务端分放在多个服务器上,又会产生一个问题:客服端发送的请求怎么知道它自己该访问哪一个服务器呢?这就需要在客户端搭建一个Nginx服务器来做请求转发,把这个问题交由Nginx来思考,后面会细讲Nginx。把数据库单独存放在一个服务器上。根据实际的生产情况,我们得出结论:大部分项目中的数据库操作,90%为读操作,10%为写操作,且写操作一般是项目内部人员执行。因此,我们可以把数据库分成主库和从库,配置不同的性能,主库负责写,从库负责读,提升数据库性能。但是将数据库分库了,数据库之间怎么保证数据同步呢?这个问题需要下去查查。为了保证项目运行的稳定性,大公司还会有数据库集群操作,也就是当一组数据库服务器挂了,还有一组备用的服务器能够顶上来,使得服务没有中断期。还可以有的划分是:静态文件服务器、Redis数据库服务器等~ 反向代理 代理:客户端不能够直接找到服务器来处理自己的请求,代理就起到帮客户端查找服务器在哪里的作用。正向代理:客户端把请求发送给代理,代理找到服务器并发请求转发服务器端,服务器把结果返回给客户端。这个流程就是正向代理,上左图。由于防火墙的原因,我们并不能直接访问谷歌,那么我们可以借助VPN来实现,这就是一个简单的正向代理的例子。这里你能够发现,正向代理“代理”的是客户端,而且客户端是知道目标的,而目标是不知道客户端是通过VPN访问的。反向代理:客户端只向代理询问服务器在哪里而不把请求页转给代理,代理把服务器的位置告诉客户端后,客户端自己发送请求给服务器。(前面是自己的理解)这个过程就是反向代理,上右图。别人的理解可能会更好一些:当我们在外网访问百度的时候,其实会进行一个转发,代理到内网去,这就是所谓的反向代理,即反向代理“代理”的是服务器端,而且这一个过程对于客户端而言是透明的。 前端部署 如果要让nginx运行起vue项目,需要将项目打包,生成原生的js代码。自动化程序会将打包的文件自动生成到项目的dist文件夹中:
npm run build 上面这个命令是用之前安装的webpack来进行打包的。
存在一个问题,每一次新的部署,我们都需要重新配置环境,安装这个软件、安装那个工具🔧,这样会很繁琐,项目维护起来也不是很方便,所以我们引入docker。它能够在容器中配置环境,就相当于一个操作系统,别人要运行我们的项目时,不需要再安装项目需求的依赖,只需要把我们的这个容器安装好,里面就自带了项目需要的依赖,很是方便。
docker 前面说了docker是拿来干什么用的,这里再说说docker的一些特点吧:
“Build, Ship and Run”(搭建、运输、运行)“Build once,Run anywhere”(一次搭建,到处运行) 还是那句话,别人要运行你的项目的时候,直接安装你的docker就行了。
docker相关的概念如上图,我们在下面做一下讲解:
镜像:还没有运行起来的操作系统文件叫做镜像。每一个镜像中都包含了一个微型操作系统,但只会安装一些运行项目相关的依赖。我们可以从同事手中,或者开源社区获取到自己想要的镜像。自己也可以把自己创建的docker分享给别人。容器:镜像运行的地方就是容器。这个容器我们不能提供给别人,但是我们可以进入这个容器进行一些相关依赖安装。就可以想象成一台电脑,我们能够在电脑上安装python 、c++、npm。在我们安装好相应的依赖之后,需要将当前的容器状态保存成镜像,这样我们又能够提供给别人了。 docker安装(mac) 根据教程安装成功。
使用常见命令 # 启动docker sudo service docker start # 停止docker sudo service docker stop # 重启docker sudo service docker restart # 列出镜像 docker image ls # 拉取镜像 docker image pull library/hello-world # 删除镜像 docker image rm 镜像id/镜像ID # 创建容器,必须先有镜像,才能运行创建容器,如果不指定任何参数,容器开机了马上就回关机 docker run [选项参数] 镜像名 [命令] # 例如:使用ubuntu镜像,创建一个名为ubuntu1 docker pull ubuntu:18.
浮点型变量 浮点型变量分为单精度(float)型,双精度(double)型和长双精度(long double)型,三类。
浮点数精度丢失 比如我们赋值给a=1.23456789e10,加10后,应该得到的值是1.234567891e10
#include<stdio.h> int main() { float a,b; a = 1.23456789e10; b = a + 10; printf("%f",b); return 0; } 但结果却如下图所示
我们称这种现象为精度丢失,因为float能够表示的有效数字为7位,最多只能保证1.234567e10的准确性,想要使结果正确,可以把float改成double。
浮点数的数值范围与有效数字 类型位数数值范围有效数字float3210^-37~10^386~7位double6410^-307~10^30815~16位long double12810^-4931~10^493218~19位 浮点数的判断 直接上代码
#include<stdio.h> int main() { float f; f = 1.456; if (f == 1.456) { printf("f is 1.456\n"); } else { printf("f is not 1.456\n"); } return 0; } 结果当然是“f is not 1.456” Why? 浮点数是不能直接判断相等的!! 我们看调试代码:
f赋的值并不是1.456
所以浮点数不能直接判断相等
可以用减法来判断 f - 1.
本任务要求:使用所学知识编写一个基于控制台的购书系统,实现购书功能,输出所有图书的信息,包括每本书的编号,书名,单价,库存。
顾客购买书时,根据提示输入图书编号来选需要的书,并根据提示输入购买书的数量,
购买完成后,输出顾客的订单信息,包括订单号,订单明细,订单总额。
此案例分为四个类
Book ,Order , Orderitem,Test(注意开头字母大写)
Book类 此类有四个参数,id编号 name姓名 price价格 stock库存。
1.无参构造方法
2.有参构造方法
3.getter and setter方法。
//图书类 public class Book { private int id; private String name; private double price; private int stock; //空参数 public Book() { } public Book(int id, String name, double price, int stock) { this.id = id; this.name = name; this.price = price; this.stock = stock; } //get and set 方法 public int getId() { return id; } public void setId(int id) { this.
spring中cglib动态代理 生活中案例:租客,中介,房东。
房东:假设拥有收租和退租两个权限,此时房东将自己拥有的权限赋予中介(为代理),租客只能通过中介办理租房业务。
在现实生活中租客可以直接和房东办理租房和退租业务,现在交由中介来完成,整个办理租房的业务通过中介完成,这个过程就叫代理
创建maven项目 引入cglib依赖包 <dependencies> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.8.RELEASE</version> </dependency> </dependencies> 一、cglib直接代理类 1.创建代理类对象 /** * cglbi代理类 * @author jkl * */ public class Landlord { public void deliver() { try { System.out.println("告知房东出租成功,房东收钱"); } catch (Exception e) { e.printStackTrace(); System.out.println("出现异常,终止"); } } public void out() { try { System.out.println("告知房东,租客退房"); } catch (Exception e) { e.printStackTrace(); System.out.println("出现异常,终止"); } } } 2.创建MethodInterceptor代理方法 import net.sf.cglib.proxy.MethodInterceptor; import net.
前言:查了好久好久网上的资料C++调用动态链接库,试了好多方法(直接创建DLL、空项目创建的)都多多少少有些问题,最后自己不断摸索着成功了,还是很开心的,接下来把最清晰的步骤分享给大家(C++新人,有什么说的不清楚的还请大佬们见谅)
第一步:创建C++空项目 第二步:创建头文件(.h)以及源文件(.cpp) 第三步:编写头文件(重点) 图片显示部分是模板,名称可以自己起最重要的就是__declspec(dllexport)以及__declspec(dllimport)。一个是导出,一个是导入。
为像我一样懒人们提供代码粘贴
#pragma once #ifndef BHDLL_d #define BHDLL_d //宏定义导出 #ifdef BHDLL__//如果没有定义DLLH 就定义 DLLH __declspec(dllexport) #define BHDLL __declspec(dllexport)//导出 #else #define BHDLL __declspec(dllimport)//导入 #endif // DLLH__//如果没有定义DLLH 就定义 DLLH //编写代码区域 //导出函数 BHDLL int add(int a, int b); BHDLL int sub(int a, int b); //导出类 class BHDLL dllH { public: int mul(int a, int b); int div(int a, int b); }; //以C语言方式导出函数: extern "C" { BHDLL int Cadd(int a, int b); BHDLL int Csub(int a, int b); } #endif 第四步:源文件实现头文件里面的方法 为像我一样懒人们提供代码粘贴
python 线程池map()方法传递多参数list 之前通过threading.thread()进行了助力接口的多线程并发,但是这个针对并发数量较少的时候比较好用,如果并发数量多,除了线程包协程这种处理方式的情况下,我们还可以采用线程池的方法。 线程池的实现通俗讲就是把所有的任务放在了消息队列里,开启多个线程后执行线程,但线程执行结束后不会中断线程任务,会从消息队列内继续获取线程任务进行线程执行,这样线程池就比多线程操作节省了很多创建线程与关闭线程的步骤,节约大部分资源与时间。 线程池并发需要引入模块
import concurrent.futures
ThreadPoolExecutor 内有两种线程池方法 map()与submit()今天先说map()方法
他的语法为
with concurrent.futures.ThreadPoolExecutor() as pool: res = pool.map(craw, uid_list) print(res) map()内craw为方法名,这里方法命不带()
uid_list为方法参数,map()方法内需要传递list数据类型
先看一下整体代码 5000用户并发助力
def test_case_09(self): """5000用户并发助力""" # 通过yaml配置文件封装方法 获取uid_list uid_list = YamlHandler(YamlThePath().number_new).get_uid_list() # add_ticket获取5000账号登陆状态 with concurrent.futures.ThreadPoolExecutor() as pool: pool.map(AccountAccess().add_ticket, uid_list) # 5000账号线程池方法助力用户 with concurrent.futures.ThreadPoolExecutor() as pool: pool.map(PreheatMethod().help, [(uid, self.A, 1) for uid in uid_list]) # 获取用户被助力次数 response = PreheatMethod().init(self.A) print(f"当前用户被助力次数 :{response['data']['userInfo']['helpedCount']}次") 再来看一下两个接口的方法更好的感知一下 首先是获取登陆状态add_ticket
def add_ticket(self, uid): """ 获取单独用户t票 :param uid: 单独用户uid :return: "
Api 请求日志-封装日志自定义注解 自定义日志注解 import java.lang.annotation.*; /** *Description: <功能操作日志注解>. <br> *<p> <声明在被spring管理的类的方法上,会记录下当前的操作日志类型> 比如:@CP_OperateLog(value="注解日志",type=1,key="test") </p> *Makedate:2020年12月30日 上午10:55:27 * @author CHENYB * @version V1.0 */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CP_OperateLog { /** * 用户操作名称 * @return 用户操作名称,默认为空串 */ String value() default ""; /** * 用户操作类型,默认类型为0<br/> * 0 - 其他操作 <br/> * 1 - 查询 <br/> * 2 - 新增 <br/> * 3 - 修改 <br/> * 4 - 删除 * @return 用户操作类型 */ CP_GlobalNamingConstant type() default CP_GlobalNamingConstant.
1.导入的测试方法
选择form-data,key值填写方法对应的参数,选择File,Value处上传文件即可。 2. 导出的测试方法
在导出文件的时候,响应结果是乱码,然后在测试的时候选择下载,下载完成的Excel文件不是乱码 点击send右边箭头,选择发送并下载
导出excel:
报错 :error: rpmdb: BDB0113 Thread/process 18616/139854252218432 failed: BDB1507 Thread died in Berkeley DB library
1.起因 由于要升级openssl,在查看版本时发现以下报错:
error: rpmdb: BDB0113 Thread/process 18616/139854252218432 failed: BDB1507 Thread died in Berkeley DB library error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery error: cannot open Packages index using db5 - (-30973) error: cannot open Packages database in /var/lib/rpm error: rpmdb: BDB0113 Thread/process 18616/139854252218432 failed: BDB1507 Thread died in Berkeley DB library error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery error: cannot open Packages database in /var/lib/rpm 2.
做自媒体的同学们都知道除了视频容易侵权外,还有文字、图片、音乐都会有侵权的风险。
被系统扣分也就罢了,再吃官司赔钱就心塞了。
今天这期内容大周来给你们分享几个可以免费商用的图片素材网站,记得先点赞收藏起来,你一定能用得上。
1、foodiesfeed
特点:加载速度快、美食图片素材、图片数量多
各种高清的美食图片素材,都是可以免费下载的,很多美食领域创作者都会用到这个素材网站,值得收藏。
2、lifeofpix
特点:可以直接下载、无需先注册
建筑、人物、自然风光类图片素材居多,把鼠标拖拽到图片上时有下载按钮。
3、picjumbo
特点:无需先注册、可以免费商用
图片素材类型有商务、人、壁纸、食物等等,超高清的图片素材。
4、stockvault
特点:下载速度慢
有上百种图片类型,可以搜索到自己想要的各种类型图片素材。
5、gratisography
特点:有创意、免费商用
都是一些奇怪怪的图片素材,感兴趣或喜欢这类图片素材的同学们可以收藏。
6、visualhunt
特点:加载速度快、类目多
搜索引擎与图库相结合的图片素材网站,可以根据关键词搜索。
每个网站的优缺点不一样,自行选择收藏。
关注大周,每天都能学到一个能赚钱的自媒体干货技巧。
1.打开远程桌面连接;
2.点击“显示选项”;
3.连接设置中点击“另存为”,默认保存到“文档”文件夹中,默认文件名称:Default.rdp;
4.在“文档”文件夹中找到:Default.rdp,使用记事本打开;
5.修改为下面参数并保存:
screen mode id:i:1
use multimon:i:0
desktopwidth:i:3840
desktopheight:i:2160
session bpp:i:32
6.右击:Default.rdp 连接
文章目录 KMP介绍一、求Next数组前后缀表求最长公共前后缀最长相等前后缀表转Next数组 二、使用Next数组来匹配字符串总结 本文章就专讲kmp,暴力匹配就不讲了(我相信能搜索kmp的,暴力匹配算法应该也都了解过了)
为什么网上那么多讲kmp 我还发文章,很多文章我觉得讲的不是太通俗易懂,大多数我看起来都觉得有些懵逼
KMP介绍 提示:以下信息来源百度
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)
上面讲了kmp需要求匹配字符串的next数组来快速匹配,那我们先来讲解一下如何求next数组
一、求Next数组 求Next数组前我们需要了解字符串的前缀表与后缀表
前后缀表 如字符串“ABCD”的前后缀表
了解完字符串前后缀,接下来我们要开始求最长公共前后缀
求最长公共前后缀 我们以“aabaac”为例
字符串中要没有公共的前后缀就为0
从以上方法就能求出字符串“aabaac”的最长公共前后缀数组为
[0,1,0,1,2,0]
最长相等前后缀表转Next数组 当然变成Next数组前还需要进行简单的处理(其实也就把最长公共前后缀数组右移而已)
在最长公共前后缀前面加上 -1 并去掉最后一位就是next数组了
Next数组的第一位永远是-1,第二位永远是0
注意:Next数组有很多种求法,依据匹配字符串的代码来做选择,我选择的方法next数组第一位是-1,还有另一种方法开头是0,但原理都是相同的所以不必纠结
二、使用Next数组来匹配字符串 为了能较好体现kmp算法:
主串:“aaacaacaaad”
模式串:“aaad”
模式串Next数组:[-1,0,1,2]
在主串和匹配串字符相同的情况下,指针 i 和 j 后移
或者遇到主串和匹配串字符不相同时 但next值为-1时指针 i 和 j 后移
步骤一:
1i、1j、2i、2j代表指针位置及步骤,中间字符相等的地方我就不讲了,就主要讲重点的地方
指针4i和4j的字符不相同,不匹配位置的next值为2(蓝色的a),所以需要将匹配串右移到匹配串索引2的位置
步骤二:
匹配串后移后指针i和j的字符依然还是不相同,不匹配位置的next值为1(蓝色的a),所以需要将匹配串右移到匹配串索引1的位置
步骤三:
匹配串后移后指针i和j的字符依然还是不相同,不匹配位置的next值为0(蓝色的a),所以需要将匹配串右移到匹配串索引0的位置
步骤四:
匹配串后移后指针i和j的字符依然还是不相同,但这时next值为-1,这就需要指针i和j向后移
步骤五:
指针i和j后移后,(中间字符相同的地方就不解说了),指针到3i和3j的字符不相同,next值为1,然后就和之前讲的步骤一样,需要将匹配串右移到匹配串索引1的位置
步骤六:
后面的步骤就不再多叙述,自己看图分析
步骤七:
步骤八:
然后这就匹配完成了
总结 代码后续会补充
非常感谢您能看到这,本人第一次写文章,所以我可能讲的不是很好,如有问题望大家能多多提醒,感谢。下次讲sunday算法
注:如看不懂,可以的话,麻烦您在评论区中发句看不懂,好让我知道我写的烂不烂
下载地址
jquery粒子动画鼠标视差特效,很酷的粒子连线动画特效,鼠标移动的时候会有视差特效。
dd:
Detours是微软开发的一个函数库,可用于捕获系统API。可以从github下载源码并编译。Detours通过更改被拦截的API函数的跳转地址为用户自定义的函数地址来实现拦截。比如我们知道要拦截API函数A,我们需要自定义一个函数B,在实现拦截之前,此时函数A所在的线程正常调用A。开始拦截的时候,Detours库函数将A的入口地址修改为B的函数指针。此前线程对函数A的调用将会被替换为被函数B的调用,当然前提是函数A和函数B的函数签名完全一致。在将函数A的入口地址修改函数B的地址时已经保留了函数A的原始地址,所以函数B的函数形式形如
void* funcB(arg1,arg2,...){
void* retPtr= funcA(arg1,arg2,...)
}
所以我们在函数B中能做的事情就是拦截并修改目标函数参数或者修改原函数的返回值。那么我们如何拦截一个进程的命令行参数呢。在windows系统中,进程是存在父子关系的树状结构。每一个子进程都由它的父进程所创建。一般的 我们都是在资源管理器中点击程序的exe可执行文件来启动进程,那么此时资源管理器进程(explorer.exe) 就是被启动进程的父进程,还有我们熟悉的命令行程序cmd.exe,还有开发者们常用的开发工具如idea,visual studio,eclipse 等等都扮演着父进程的角色。父进程一般通过CreateProcess来创建子程,CreateProcess函数通过命令行参数即可以启动子进程。所以拦截进程的创建和启动就是通过拦截父进程中CreateProcess函数的参数和返回值来实现。我们要实现的函数B需要在一个独立的dll中实现,这个dll可以通过detours工具setdll.exe插入目标父进程的导入表
或者detours工具withdll.exe启动时被目标父进程加载到进程空间,
以下的例子程序通过拦截idea64.exe中的CreateProcess函数 实现打印CreateProcess函数的命令行参数。如果原函数CreateProcess为A,那么MyCreateProcessW则为B。
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include "detours.h"
#pragma comment(lib,"detours.lib")
typedef BOOL(WINAPI* PMyCreateProcessW)(
_In_opt_ LPCWSTR lpApplicationName,
_Inout_opt_ LPWSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCWSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOW lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
PMyCreateProcessW gOldCreateProcessW = NULL;
根据异常退出调用栈中的fault_address猜测异常原因:
1、fault_address=0x0 空指针
2、fault_address=较小的地址:野指针(空指针加偏移地址取数据)
3、fault_address=较大的地址:野指针
三个例子:
1、A类对象A_C将其成员函数A_x注册给B类对象B_C,类对象B_C调用函数A_x导致异常退出
原因: 类对象A_C析构后未解注册其成员函数A_x到类对象B_C,来将函数A_x指针置空。类对象B_C调用函数A_x时指针为野指针导致异常。
经验:
类对象析构时释放周边资源及让周边释放持有的自身资源;析构时指针置空。 2、两个线程同时调同一个类对象A_C,一个线程X析构A_C,一个线程Y用A_C中指针成员变量m导致异常退出
原因: 线程X析构对象A_C后置指针成员变量m为nullptr,线程Y用指针成员变量m未判空导致异常退出。
经验:
使用指针必须判空。 3、类对象A_C通过接口返回结构体对象m指针,读取对象m中成员数据导致退出
原因: 正常情况返回的对象m的指针不为空,当前场景为空,取成员数据为野指针导致异常退出。
经验:
周边领域返回的数据不可信,必须指针判空。
xlsread 的用法 [NUM,TXT,RAW]=XLSREAD(FILE,SHEET,RANGE) FILE:是文件名 SHEET:是工作表名可以是,可以是数字1(代表sheet1),或者真正的名字 RANGE:数据范围从左上角到右下角,不指定范围可以读取所有的数据 NUM:读取到的数值部分 TXT:读取到的数据的文本部分,比如第一行是列名,后面接的数据,TXT保存的就是列名 RAW:完整的原始数据(列名+数值),以cell的格式保存 xlsread实战1 读取文件,不加范围 [NUM,TXT,RAW]=xlsread('results.xlsx','Sheet1'); 点击查看原始数据的组织形式
读取结果 可以看到 RAW是NUM和TXT的结合,因为没有设置读取范围,所以会读取到选择sheet中的所有数据。
xlsread实战2 [NUM,TXT,RAW]=xlsread('results.xlsx','Sheet1','A1:B5'); 读取结果 因为范围设置的是A1:B5,因此一共读取到5行两列数据,第1行为两个文本放在TXT中,后4行为8个数值放置在NUM中。
Xlswrite的用法 XLSWRITE(FILE,ARRAY,SHEET,RANGE) File:指文件名 ARRAY:数据 SHEET:工作表 RANGE:范围或者起始位置(如'A1:B8' or 'A1') xlswrite实战1 xlswrite('test.xlsx',{'时间','地点'},'Sheet3','A1'); xlswrite('test.xlsx',{'时间','地点'},'Sheet3','A1:B1'); 将文本写入到xlswrite,最后的range如果只写一个位置(比如A1位置),就是文本输出开始的位置,如以上两行代码最后的结果是一致的。
输出结果 xlswrite实战2 data = [1 2 3 4 5]'; xlswrite('test.xlsx',{'时间'},'Sheet4','A1'); xlswrite('test.xlsx',data,'Sheet4','A2'); 我们通常的数据写出一般先是一个文本,后面接着是一列数据的形式
输出结果
今天听到同事在说找工作的事情,说年后很容易找工作,大量招聘,然后这段时间是淡季了,比较难找工作,说我们现在年轻,可以学习其他岗位,然后去做计件的工资很高,其实我觉得现在我就是好困的那种,眼睛都睁不开了。不过我觉得工厂还是比较实际的,就算做的不好,也不会直接辞退,问你明天来不来,或者说叫你不要来了,他们自己已经找到工作人员了,感觉让人崩溃。
我目前这个做了有一年了,平时晚上下了班有很多空闲时间,因为现在有很多都是网上的工作,所以兼职也可以直接在网上找找,我目前做的是电脑上的任务,一个月能有个一两千左右,加上正职工资,其实只能说一般吧。
网上现在赚钱的方式很多,如果你不知道就多上网查查,然后选择适合自己的,自己也感兴趣的,坚持去做总会看到效果的,切忌吃着碗里看着锅里,见到什么赚钱都想上去捞一把,这样很容易一事无成。
那什么是商业的底层逻辑呢? 我认为分为六个模块:现金流、利润、规模、远景、品牌和情怀!
初创公司,首先需要的是现金流,其次是利润,现金流是企业的血液,而利润就是脂肪,没有了利润,你还可以撑一段时间,但是没有了现金流,企业里面就会倒闭。 必要的时候,你可以舍弃一些账面利润,来换取更多的现金流,这也是商业模式创新过程中常用的手法。
有了稳定现金流之后,再来追求利润最大化,所以这就需要创业者把更多的时间、精力、思维都放在思考利润上来,核心思路就是一条,放大赚钱的项目,砍掉不赚钱的项目。
当利润稳定之后,我们就要开始追求企业的规模,但是有的时候,规模与利润往往不是成正比的,更多时候,利润与规模呈现反比例关系。 其实创业的本质,不是把企业规模做到最大,而是维持在一个相对合理的规模内,把利润做到极致。
规模形成一个稳定区间之后,我们就要打造企业的远景了,多思考5年后、10年后可能会发生的事情,提前想好一些应对计划。
接着就是打造品牌,其实品牌分为三个维度来打造,一个是企业品牌,一个是产品品牌,一个是个人品牌。三位合一,才能发挥出品牌的最大价值。
最后,就是我们经常讲的情怀,但是往往因情怀创业的人都会输得很惨,商业的底层逻辑是,发现某个特定人群的需求,制定出产品或者服务,去满足他们,但是很多人是基于自己的兴趣和特长来创业,结果发现没有需求,最后没人买单,企业就这样倒闭了。
所以,正确的创业逻辑是先赚钱,再谈情怀,千万不要搞反了!
1、什么是方法的重写?
在继承体系中,子类出现了和父类中一模一样的方法声明,我们就称子类这个方法是重写的方法。
2、方法重写的应用场景
1)当子类需要父类的功能,但父类该功能不能完全满足自己的需求时。
2)子类可以重写父类中的方法。
3、@Override 重写注释
4、方法重写注意事项和要求
什么是方法的重载?
方法名相同,参数列表中的参数顺序、类型、数量不同
重载与方法的返回值无关,存在于父类、子类和同类中
可以抛出不同的异常,可以有不同的修饰符
optimization.runtimeChunk: ‘single’ 一直很难理解,直到我看到了webpack的官方文档中说到的otherwise we could get into trouble described (下面称文章),下面我们就用两个例子把这个trouble复现一下。
Bug重现 文章中说,当两个模块从同一个模块(下面叫公用模块)中import后,公用模块的值,在同一个页面中(同一个runtime中),应该是多少?在文章中component-1和component-2都累加了1,因此输出应该是“1 2”,那么实验如下:
目录结构如下,其中component-1.js,component-2.js和obj.js的代码都是参考文章中,index.js可以忽略 webpack.config.js const path = require('path'); module.exports = { mode: 'development', entry: { comp1: './src/component-1.js',//参考文章中的代码 comp2: './src/component-2.js',//参考文章中的代码 }, output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), }, }; index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Development</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <script defer src="comp1.bundle.js"></script> <script defer src="comp2.bundle.js"></script> </head> <body> </body> </html> 解决方法 运行后你会发现,两次输出的都是1。这时候optimization.runtimeChunk: 'single’就有用了,按照官网手册的方法,你会发现,出现了一个runtime.bundle.js,这个玩意再在index.html中引用,结果就对了。
奇怪的地方 按照官网的方法,把obj.js独立成一个entry,component-1.js和component-2.js都dependOn,也不会出现这个问题。官网这个表述感觉确实很难理解,不过从另外一个角度来看,这个参数可能也没那么重要吧。
目录 竖读题目思路代码 质数下标题目思路代码 攻与防题目思路代码 竖读 题目 输入n行字符串数字(1<=n<=9),字符串数字的长度范围为1-10^5.
请将每一列的数读出来,并从小到大排序后,以空格间隔输出。
示例1:
输入:
3
0123
1234
2345
输出:
12 123 234 245
思路 这比较基础,使用一个string储存字符串数字,然后遍历每一列计算出每一列的结果存到vector容器中
代码 #include<iostream> #include<vector> #include<string> #include<algorithm> using namespace std; bool cmp(int a, int b) {//返回true不交换,false交换 return a < b; } vector<int> solve(int n, string s[]) { vector<int> res; int length = s[0].size(); //字串长度 for (int i = 0; i < length; i++) { int res_t = 0; for (int j = 0; j < n; j++) { res_t = 10 * res_t + (s[j][i] - '0'); } res.
任务:进货信息增加一个属性,采购单据号,要求按采购日期+6位流水号,自动生成该单据号,格式:CGD-yyyyMMdd-XXXXXX。
以下内容,仅为上述需求进行的操作,你们可以根据自己的需求进行生成订单规则的修改。
数据库操作
首先当然是在自己的数据库进行修改,因为要求我们使用生成固定规则订单号,且添加在原有数据中。所以需要自己的原有表中添加一个【订单号】的字段。
考虑到该字段内容形成,我们可以单独创建一个表purchase_serialnum,专门用来生成和存储固定规则的订单号。(记得写一个测试字段,如下图的第一个内容)
字段内容根据自己的需要创建(越简单越好),但是如上图的前三个字段必须要有,方便接下来使用。
两个表中我定义的是主键id自增,方便新增订单时生成订单号的位置是相同的。
如果你在测试的时候两个不同表中产生了主键id自增的序号不一致的问题,可以通过SQL语句来改变。(如NAvicat中运行一下)
ALTER TABLE tableName AUTO_INCREMENT 3; “tableName”指的是表名,“3”指的是你需要改变自增id成哪个数字开始 然后新的表当然就要创建对应的实体类、xml文件,dao层,service层等等,以下内容仅展示部分。
PurchaseSerialnum
@Data // getter/setter用@Data替代,不知道怎么使用的搜索lombok查找依赖和用法 public class PurchaseSerialnum implements Serializable { private Integer serialnumberid; private String serialnumber; private Integer serialcount; private Date cereattime; private String prefix; private static final long serialVersionUID = 1L; } PurchaseSerialnumMapper.xml
<select id="selectMax" resultMap="BaseResultMap"> SELECT * FROM purchase_serialnum WHERE serialNumberId = ( SELECT Max( serialNumberId ) FROM purchase_serialnum) </select> PurchaseSerialnumMapper
PurchaseSerialnum selectMax(); PurchaseSerialnumService
用node.js写的服务器,运行一个node.js文件。
真正的开发中不常用。
库封装好了ajax请求,我们使用axios,因为jQuery中的要执行DOM操作,我们使用vue的时候要尽量避免对DOM进行操作。下面两个库,都是对xhr封装。
windows的内置方法就有一个fetch,可以直接请求。IE浏览器用不了。
vue的插件库,vue.use。
axios 引入axios。
发送一个axios请求。
出现跨域问题。
跨域是因为违背了同源策略。
同源策略:协议名、主机名、端口号必须一致。
cors解决跨域,后端人员配置一些特殊的响应头。配置响应头出现的问题就是任何人都能找你这台服务器要数据。 jsonp解决跨域问题。借助script标签的src属性在请求资源时不受同源策略的限制。 用的比较少,需要前后端的配合,只能解决gget请求的跨域问题。开发中用的比较多的就是配置一个代理服务器。服务器与服务器之间传递数据,不要用ajxj,用最原始的http请求就行。 开启代理服务器:
nginxvue-cli 配置代理服务器:
找代理服务器要数据:
请求的资源如果在代理服务器中本身就存在,就不会去找其余服务器请求。
代理服务的资源存在于public中。
这种配置代理服务器的方法,只能是配置一个代理服务器,也没有办法灵活控制去哪里请求资源。
配置代理服务器的另外一种方式:
请求前缀是什么,就代理请求,转发给请求资源的服务器。
转发给主服务器的时候需要重写路径。
一些介绍:
总结:
vue-resource 首先安装一下插件库。
引入并且使用。
vm中出现$http。
使用方法。promise风格的请求。
这个库的维护频率不是很高,现在使用的比较少。axios的封装比较优秀。vue-resource在vue1.0的使用比较多。
hive执行sql报错
FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient 解决办法:1、初始化mysql数据库
2、注释配置文件$HIVE_HOME/conf/hive-site.xml
<!-- <property> <name>hive.metastore.uris</name> <value>thrift://master:9083</value> <description>Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.</description> </property> --> 初始化数据库
./schematool -dbType mysql -initSchema Error: Duplicate key name 'PCS_STATS_IDX' (state=42000,code=1061) org.apache.hadoop.hive.metastore.HiveMetaException: Schema initialization FAILED! Metastore state would be inconsistent !! Underlying cause: java.io.IOException : Schema script failed, errorcode 2 Use --verbose for detailed stacktrace. *** schemaTool failed *** 删除mysql数据库中的hive库,重新执行,问题解决。
demo-效果图
全部代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>地图搜索与拖拽选址</title> <style> #mapContainer{ position: relative; width: calc(100vw-20px); height: calc(100vh - 30px); background: #fff; z-index: 1; overflow: hidden; } .searchBox{ position: absolute; left: 20px; top: 20px; z-index: 2; } .searchBox #keyword{ height: 30px; line-height: 30px; width: 260px; padding: 0 5px; } .searchResult{ position: absolute; bottom: 50px; left: 30px; z-index: 2; height: 100px; width: 400px; background: #fff; border-radius: 8px; padding: 20px; cursor: default; } .
JS高级 1.类和对象 1.1constructor构造函数(共用属性) constructor()是类的构造函数,用于传递参数,返回实例对象。如果没有显示定义,类内部会自动创建constructor()
类名一般首字母大写
1.2添加方法(共有方法) 方法名()函数不写function多个方法之间不需要逗号分隔 1.3类的继承 子类继承父类的一些属性和方法:class Son extends Father
1.3.1super关键字 用于访问和调用对象父类上的函数,可以调用父类的构造函数和普通函数继承中,实例化子类输出的方法,先看子类有没有这个方法,有先执行子类如果子类没有,去父类查找(就近原则)super必须在子类定义之前调用,即在this前面 1.4注意 先定义类再实例化类里面的共有属性和方法要加this使用this指向:constructor里面的this指向实例对象,方法里面的this指向调用者,实例对象 1.5类的本质 类的本质是函数,可以理解为构造函数的另一种写法
2.构造函数和原型 2.1概述 ES6之前没有类的概念,通过构建函数的特殊函数来定义对象和特征
2.2构造函数 初始化对象,与new一起使用。
创建对象时首字母大写与new一起使用new:
内存中创建新的空对象
this指向新对象
执行构造函数里的代码,添加属性和方法
返回新对象(不需要return) 2.3实例成员 构造函数内部通过this添加的成员,只能通过实例化的对象来访问
2.4静态成员 在构造函数本身上添加的成员,只能通过构造函数来访问
2.5原型prototype 构造函数通过原型分配的函数是所有对象共享的,每个构造函数中都有prototype属性,不需开辟额外的内存空间来存储函数
class.prototype.方法 = function(){} 2.6对象原型_proto_ 对象都有_proto_属性,指向构造函数的原型对象
若修改了原来的原型对象,并且以对象的形式赋值,则需要手动添加constructor:原来的构造函数
2.7构造函数和原型对象的关系 2.8原型链 Star原型对象里的_proto_指向Object.prototype
Object原型对象里的_proto_指向null
2.9成员查找机制 查找对象自身的属性或方法没有则查找原型还没有查找原型对象的原型(Object的原型对象)直到找到Object(null) 2.10原型中this指向 原型对象函数里面的this指向实例对象即调用者
2.11扩展内置对象 通过原型对象,扩展内置对象
比如数组添加求和方法:
Array.prototype.sum = function(){} 数组和字符串内置对象不能给原型对象覆盖操作,即用对象方式赋值,应采取上述操作
2.12继承 ES6之前没有extends继承,通过构造函数+原型函数的方式继承,称为组合继承
2.12.1call() 调用函数并修改函数运行时this的指向
fun.call(thisArg,arg1,arg2,...) thisArg:当前调用函数this的指向对象arg1:其他参数 2.12.2借用构造函数继承父类属性 通过call()把父类型的this指向子类型的this
2.12.3借用构造函数继承父类方法 Son.prototype = new Father();
Son.prototype.constructor = Son;
DataOutputStream extend FilterOutputStream implements DataOutput function: 数据输出流是应用程序以便携式方式将java基本数据类型(包含String类型)写入到输出流,然后应用程序使用数据输入流来读取数据。
需求: 上传日志报文
日志报文格式(字节):
日志标识[1]保留字段[1]日志类型编码[1]日志子类型编码[1]数据包长度[4]日志内容[n]
根据需求使用输出流的包装类DataOutputStream来进行写文件,主要是很方便,都封装好了。
/** * * @param fileName 文件名 * @return */ public File toFile(String fileName) throws IOException { File file = new File(fileName); DataOutputStream dos = new DataOutputStream(new FileOutputStream(file)); dos.writeByte(this.logIdf); dos.writeByte(this.reserve); dos.writeByte(this.logType); dos.writeByte(this.logSubType); dos.writeInt(getLength()); if (this.content == null) { this.content = new JSONObject(); } dos.writeUTF(this.content.toJSONString()); dos.flush(); dos.close(); return file; } 在我本地的测试机上进行测试,发现没有什么问题。(content内容主要记录ssh运维过程中传输的文件名称,操作的指令等等,本地没有搞那么多,测试传了上千个文件),提交测试后就出问题了。错误日志java.io.UTFDataFormatException encoded string too long: 270976 bytes"经过排查日志发现问题就出在了dos.writeUTF(this.content.toJSONString());这一行代码。
源码:
static int writeUTF(String str, DataOutput out) throws IOException { int strlen = str.
一:垃圾回收机制的意义
java 语言中一个显著的特点就是引入了java回收机制,是c++程序员最头疼的内存管理的问题迎刃而解,它使得java程序员在编写程序的时候不在考虑内存管理。由于有个垃圾回收机制,java中的额对象不在有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存;
内存泄露:指该内存空间使用完毕后未回收,在不涉及复杂数据结构的一般情况下,java的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有是也将其称为“对象游离”;
二:垃圾回收机制的算法
java语言规范没有明确的说明JVM 使用哪种垃圾回收算法,但是任何一种垃圾回收算法一般要做两件基本事情:(1)发现无用的信息对象;(2)回收将无用对象占用的内存空间。使该空间可被程序再次使用。
1。引用计数法(Reference Counting Collector)
1.1:算法分析:
引用计数算法是垃圾回收器中的早起策略,在这种方法中,堆中的每个对象实例都有一个引用计数器,点一个对象被创建时,且该对象实例分配给一个变量,该变量计数设置为1 ,当任何其他变量赋值为这个对象的引用时,计数加1 ,(a=b ,则b引用的对象实例计数器+1)但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时,对象实例的引用计数器减1,任何引用计数器为0 的对象实例可以当做垃圾收集。 当一个对象的实例被垃圾收集是,它引用的任何对象实例的引用计数器减1.
一、垃圾回收机制的意义
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。
ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。
二、垃圾回收机制中的算法
Java语言规范没有明确地说明JVM使用哪种垃圾回收算法,但是任何一种垃圾回收算法一般要做2件基本的事情:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。
1.引用计数法(Reference Counting Collector)
1.1算法分析
引用计数是垃圾收集器中的早期策略。在这种方法中,堆中每个对象实例都有一个引用计数。当一个对象被创建时,且将该对象实例分配给一个变量,该变量计数设置为1。当任何其它变量被赋值为这个对象的引用时,计数加1(a = b,则b引用的对象实例的计数器+1),但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时,对象实例的引用计数器减1。任何引用计数器为0的对象实例可以被当作垃圾收集。当一个对象实例被垃圾收集时,它引用的任何对象实例的引用计数器减1。
1.2优缺点
优点:
引用计数收集器可以很快的执行,交织在程序运行中。对程序需要不被长时间打断的实时环境比较有利。
缺点:
无法检测出循环引用。如父对象有一个对子对象的引用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0.
1.3引用计数算法无法解决循环引用问题,例如:
1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
public static void main(String[] args) {
MyObject object1 = new MyObject();
MyObject object2 = new MyObject();
object1.object = object2;
在本指南中,您将学习如何使用库对 ESP32 开发板进行无线 (OTA) 更新。 该库创建了一个网络服务器,允许您将新固件(新 sketch)上传到您的电路板,而无需在 ESP32 和您的计算机之间建立串行连接。
此外,使用此库,您还可以将新文件上传到 ESP32 文件系统 (SPIFFS)。该库非常易于使用,并且与我们经常用于构建 Web 服务器项目的库兼容。
概述 OTA 编程 OTA(空中下载)更新是使用 Wi-Fi 连接而不是串行通信将新固件加载到 ESP32 开发板的过程。在无法物理访问 ESP32 板的情况下,此功能非常有用。
有不同的方式来执行 OTA 更新。在本教程中,我们将介绍如何使用库来做到这一点。在我们看来,这是执行 OTA 更新的最佳和最简单的方法之一。
库文件 OTA Web 更新程序工作原理 库安装 基本示例 插入您的网络凭据,代码应立即生效:
代码分解 访问网络服务器 上传代码到板子后,以115200的波特率打开串口监视器,按下ESP32板载RST按钮。它应该显示 ESP IP 地址如下(你的可能不同):
在本地网络中,打开浏览器并输入 ESP32 IP 地址。您应该可以访问显示一些文本的根 (/) 网页。
上传新固件 OTA(无线)更新 您通过 OTA 上传的每个文件都应为 .bin 格式。您可以使用 Arduino IDE 从您的 sketch 中生成一个 .bin 文件。
打开 sketch 后,您只需转到 Sketch > Export Compiled Binary。 .
docker 默认有4种网络模式,详细可查看我曾经写的 "docker几种网络模式"
docker run 新建并启动容器时,不指定网络,默认是使用桥接模式,容器内部IP是通过DHCP获取,容器网桥名为docker0,docker容器重启后,其容器IP会变化。有没有办法来固定容器内的IP呢?答案是肯定的。可以使用脚本或工具来固定容器内部IP。
一、如何查看容器内部IP?:
方法一:
通过docker inspect查看容器的详细信息来查看,可以使用grep来匹配查询
[root@localhost ~]# docker inspect centos7 | grep -aiE ipaddress "SecondaryIPAddresses": null, "IPAddress": "172.17.0.2", "IPAddress": "172.17.0.2", [root@localhost ~]# docker inspect centos7 | grep -aiE ipaddress | tail -1 "IPAddress": "172.17.0.2", [root@localhost ~]# docker inspect centos7 | grep -aiE ipaddress | tail -1 | grep -aiowE "([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})" 172.17.0.2 [root@localhost ~]# [root@localhost ~]# docker inspect centos7 | grep -aiE ipaddress | tail -1 | grep -aiowE "
5题打了38分:33%,60%,0%,100%,0%,分别做了23 10 30 24 33分钟。
前两题看都没看懂。第三题一元三次方程打了两套公式,结果一个都没过,pow开三次方开不出来。
最后一题写了88行代码,最后半分钟终于写完通过编译,结果超出内存,0%。
//#include<iostream> //#include<algorithm> //#include<vector> //#include<queue> //#include<set> //#include<map> //#include<unordered_set> //using namespace std; // P1 33% //int main() { // int m, n; // cin >> n >> m; // vector<double> a(m); // double ans = n; // for (int i = 0; i < m; i++) { // cin >> a[i]; // double t = ans; //lose // double q = t / (1 - a[i]) - 1; // ans = q; // } // printf("
0. 为什么要读这篇论文 首先,作者本人并不是这个领域的科研工作者,只能说是自动驾驶领域的一个工程师,我更希望我做的每一件事情,读的每一篇文章都在帮我解决一个问题或者一个疑惑。
那么,谈一下为什么要读这篇文章,自动驾驶视觉感知领域算法开发这个领域可谓是日新月异,越来越多的事物可以被感知到,更多的摄像头参与到了感知算法中,从一开始的1V(前视)到5V,再到8V,从1M像素到2M再到现在8M的摄像头,甚至还有双目和RGBD的参与。全方位的视觉感知,直接就加重了自动驾驶硬件的负担,不说AI算力的问题,单单读取这些摄像头的数据,一般的平台直接就挤爆带宽了。如果每个摄像头的对应深度网络都在运行,实时实现检测和分割的任务,虽然没有实际评估过(事实上也要看有多少任务在同时运行),但估计两个Orin,1000TFlops的算力也得吃紧吧。
事实上,现在主流方案基本都是单摄像头多任务网络,多个检测头共用主干网,确实将encoder这部分的计算共享了,省了一大部分计算量。但是多摄像头的任务依然存在,我们不可能将前视的主干网和侧视的主干网共用,采集特征根本不一样。这也是这篇文章的意义所在,将2D转Bird View,直接在鸟瞰视角去做训练,这就有点像倒车影像的演化,从后视加环视,到现在很多车上直接有融合好的车辆360。不知道这篇作者的想法是不是来自于这点。
1. 摘要 和前面提到的类似,作者提出了M2BEV框架,在BEV(Bird Eye View)中执行3D的目标检测和图像分割任务,提高了检出效率。整个框架包括4个主要的设计:(1)高效的BEV Encoder设计减小了特征图的维度; (2)针对3D boxes Anchor的优化,提出了一种动态的策略,可以关注一下和RPN有何区别; (3)A BEV centerness re-weighting that reinforces with larger weights for more distant
predictions。这点目前没有完全理解,可能是权重优化方向的一种设计,增强了一些边缘框的检出率; (4))Large-scale 2D detection pre-training and auxiliary supervision。应该是模型预训练的方法和Loss函数的复合方法上的优化,后面再细致看一下作者做了什么。
2. Introduction 2.1 当前自动驾驶行业的主要任务
(1) 3D Object detection
(2)BEV Segmentation
2.2 本文的目标
目前已经提出的方法不适合360 多任务的感知,作者提出多目摄像头并且不含Lidar的3D目标检测和BEV分割架构。现在看起来主要是Unified BEV Feat可能是区别于一般多任务网络的核心。
2.3 三种当前主流的方案
(1)Monocular 3D object detection: CenterNet、FCOS3D等,分别在每个 camera view预测 3D BBox, 通过后处理,将每个视角的BBox进行融合 。这些步骤是非鲁棒的,很难给后续规控使用;
(2)Pseudo LIDAR: 通过单目或者双目推测深度信息,来重建3D 体素信息,但是这种方法需要依赖于深度标注信息。依目前读者了解,深度标注在行业内还处于探索阶段,量产还没听说过,即时能标注,高额的标注费用也是需要考虑的;
(3)Transformer based method:DETR3D 将3D目标检测投影到多视角2D images下,从而实现了多视角3D 检测。这话稍微有点绕,我理解就是多视角2D信息一起喂到网络里,其实和作者的想法已经非常接近了,但是这个网络没有实现BEV层级的分割任务。下次再读一下 DETR3D这篇文章。
目录 事件起因代码解读:接下来我们来拆解解读这个“我认为比较复杂的sql”: 得到的结果字符串再转换为字符串集合列表:总结 事件起因 在看一个老项目的时候,看到的一个比较神奇的操作,我们平时查询有层级关系的内容时,比如一个部门表或者类别表的时候,常常会使用到树结构,就是在mysql的表中有一列是pid,也就是父亲id,从而形成树结构,这种情况,我们一般在服务端(后端)采用递归遍历的方式来循环访问数据库,从而得到一个树结构的列表,要想访问某个节点下的所有子节点,大致也是这种方式,从要开始找的节点开始向下找,然后递归遍历子节点继续向下找子节点
我遇到了一个什么呢?就是在找一个结点下所有子结点的时候,我看到一个野路子,它的源代码是这样的:(该代码是在mapper层的,通过注解@select的方式写的sql)
首先:要明确我们的目标,我们的目标是:找到树结构中某个id下所有的子节点
@Select("SELECT max(t3.childId)\n" + " FROM (\n" + " SELECT *,\n" + " IF\n" + " (\n" + " find_in_set( t1.pid, @p ) > 0,\n" + " @p := concat( @p, ',', id ),\n" + " 0\n" + " ) AS childId\n" + " FROM\n" + " ( SELECT id, pid FROM sys_category t ORDER BY id ) t1,\n" + " ( SELECT @p := #{parentId}) t2\n"
思想:先找出这些数字中个位出现了多少个9,再找出这些数字中十位上出现了多少个9,将这两项累加起来。
思考误区:是找出0~100这些数中一共出现了多少个9,并不是找出含有9的数的的个数。
出现了9的数字有:9 19 29 39 49 59 69 79 89 99
90 91 92 93 94 95 96 97 98 99
代码:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() { int i = 0; int count = 0; for (i = 0; i <= 100; i++) //产生0~100的数字 { if (9 == i % 10) //计算这些数字中个位上含多少个9 { count++; } if (9 == i / 10) //计算这些数字中十位上含多少个9 { count++; } } printf("
const queryStringObj = () => { let searchParams: any = new URLSearchParams(window.location.search); // 输出键值对 let obj: any = {}; for (var key of searchParams.keys()) { obj[key] = searchParams.get(key); } return obj; };
一、简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。
那么jmeter脚本怎么编写?
jmeter其实不需要自己添加脚本,配置一些东西就可以测试了!!!
二、详细步骤 1、先去apache官网下载jmeter,然后打开进入bin目录,点击jmeter.bat
2、点击之后会看到一个黑色的窗口(这个窗口不能关),还有一个jmeter工作窗口
3、右键测试计划,新建线程组
4、右键线程组,新建一个http请求
5、建好http请求之后,要把必要的参数填写上去(我的服务器都是自己的,根据你自己的填) 6、执行接口调用
7、执行完了怎么看结果呢?要先右键线程组,添加一个查看结果树
8、点击结果树就可以看到结果了
好了 学习也就到此结束了 想了解更多相关知识请关注我吧!下面是小编想对读者大大们写的一封信哦! 记住要认真读哦! 感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接免费拿走:
————————————————
「学习资料 笔记 工具 文档领取」
扫描二维码,
备注“csdn999”
小姐姐邀你一起学习哦~~
和志同道合的测试小伙伴一起讨论测试技术
一定一定一定 要备注暗号:CSDN999
————————————————
以下解决方案搬运自oscar1780,github issue #442 系统环境 ubuntu 18.04 , melodic, opencv4.0(本地编译 仅make 未make install,考虑兼容性问题未安装)
解决办法:
1、编译ros版本,需要将Examples_old文件夹下ROS文件夹复制到Examples文件夹下。将CMakeLists中用到OpenCV4的地方,连接到你的库位置。
2、将路径添加至~/.bashrc,这部分参考官方文档,运行./build.sh ./build_ros.sh
3、提示找不到sophus库,修改CMAKELISTS, include_directories中添加 ${PROJECT_SOURCE_DIR}/…/…/…/Thirdparty/Sophus
4、Sophus::SE3f, cv::MAT,Eigen::Vector3f类型转换报错,应该是不能直接转换,不过可以换个办法,
【2022.01.11】补充:以下解决方法会引入cv中的eigen2cv方法,需要在每个修改文件的顶部包含以下文件头文件: 参考这里
#include <Eigen/Dense> #include <opencv2/core/eigen.hpp> 解决 cv::Mat Tcw = mpSLAM->TrackMonocular(cv_ptr->image,cv_ptr->header.stamp.toSec()); 报错
引入上述两个头文件,然后删除ROS/ORB_SLAM3/src/AR/ros_mono_ar.cc第151行,由下面内容替换 cv::Mat Tcw; Sophus::SE3f Tcw_SE3f = mpSLAM->TrackMonocular(cv_ptr->image,cv_ptr->header.stamp.toSec()); Eigen::Matrix4f Tcw_Matrix = Tcw_SE3f.matrix(); cv::eigen2cv(Tcw_Matrix, Tcw); 解决 vPoints.push_back(pMP->GetWorldPos()); 报错
引入上述两个头文件,然后删除ROS/ORB_SLAM3/src/AR/ViewerAR.cc第409行,由以下内容替换 cv::Mat WorldPos; cv::eigen2cv(pMP->GetWorldPos(), WorldPos); vPoints.push_back(WorldPos); 解决 cv::Mat Xw = pMP->GetWorldPos();报错
引入上述两个头文件,然后删除ROS/ORB_SLAM3/src/AR/ViewerAR.cc第530行,由以下内容替换 cv::Mat Xw; cv::eigen2cv(pMP->GetWorldPos(), Xw); 再编译,没有其他问题的话正常编译通过。
5、回到 workspace目录下面 ,source下环境,rosrun ORB_SLAM3 Stereo_Inertial .
Vue 面向对象编程 面向对象的程序设计实质就是选用一种面向对象程序设计语言(OOPL),采用对象、类及其相关概念所进行的程序设计。
其中面向对象语言是以对象作为基本程序结构单位的程序设计语言,指用于描述的设计是以对象为核心,而对象是程序运行时刻的基本成分。OOPL包括:java、golang、python、c++ 等服务端当下流行的语言。
面向对象的思想中有两个重要概念:类、对象new Vue()所有程序都会在其中执行,挂载到主干html上然后根据代码进行局部刷新,实现(SPA单页面应用),此时只是创建一个空对象用以加载数据,此时里面只是存在一些默认的js方法以及生命周期(比如:DOMContentLoaded、load)beforeCreate(创建前), 初始化一些data数据以及methods数据以及方法created(创建后), 此时已经初步具备模板生成条件,进行生成判断。是将<template>编译到render函数中; vue的$mount 和直接指定el属性 直接在在new一个vue的时候,直接指定对应的id选择器解析:vue 对象的mount()为 手动挂载,在项目中可用于延时挂载。(例如: 在挂载之前要进行一些其他操 作 、判断等),之后要手动挂载上。 new Vue()时,el和mount并没有本质上的不同. beforeMount(载入前), 将生成的HTML挂载到对应的位置(此时还未将编译出的HTML渲染到页面上)【此处创建vm.$el放在内存中(这一步是为了后面数据发生变化准备,将真实DOM和虚拟DOM对比,提高DOM复用效率),并替换el元素】mounted(载入后),将内存中的虚拟DOM转为真实DOM插入页面,此时已完成整个页面的渲染。beforeUpdate(更新前),实时监控data里的数据变化,当页面数据需要更新时,更新之前触发该钩子,此时,vm中的数据时新的,但是页面依然是旧数据,即页面尚未和数据保持同步updated(更新后), 实时监控data里的数据变化,根据上面一部拿到的新数据,重新生成新的虚拟DOM,随后将新DOM与旧的虚拟DOM进行比较,最终完成页面更新,实现了从Model(模板)—>View(页面)的更新(真正的页面和数据保持同步,此时数据是新的,页面也是新的)beforeDestroy(销毁前),页面中所有的data、methods、指令等,都处于可用状态,但是马上要执行销毁过程;一般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等收尾操作;此时已经不能触发页面更新了(停止方法指令与视图直接的关系,但是这些方法任然存在)
10.destroyed(销毁后) ,完全销毁,此时组件以及方法均无法使用
训练出现nan 在使用MMDetection训练模型时,发现打印信息中出现了很多nan。现象是,loss在正常训练下降的过程中,突然变为nan。
梯度裁减 在模型配置中加上grad_clip:
optimizer_config = dict(grad_clip=dict(max_norm=35, norm_type=2)) 降低学习率 如果添加了梯度裁剪依旧出现梯度爆炸的问题。那么可以考虑降低学习率,大约降低为原来的0.1即可。
参考文章 解决模型训练loss nan的问题
mmdetection中出现 loss为 nan的情况
一、JWT工具类 JWT的本质就是一个字符串
它是将用户信息保存到一个Json字符串中,然后进行编码后得到一个JWT token
package com.lin.commonutils; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.util.Date; /** * @author linZT * @date 2022-4-1 14:39 * JWT工具类 */ public class JwtUtils { /** * 两个常量: 过期时间;秘钥 */ public static final long EXPIRE = 1000*60*60*24; public static final String SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO"; /** * 生成token字符串的方法 * @param id * @param nickname * @return */ public static String getJwtToken(String id,String nickname){ String JwtToken = Jwts.
有几点是需要注意的:
1、supervisor 管理的进程必须是前台运行的,也就是说不能以守护进程运行。所以,uwsgi配置文件中不能有 daemonize 的配置。
2、uwsgi 进程在kill时,如果根据常规的kill信号是杀不死的(uwsgi会重启),必须通过 -INT 信号去杀。supervisor默认使用的是 TERM 信号,故需要指定 stopsignal 配置项为 INT。
注意:stopsignal 的可选配置 INT,必须为 supervisor 3.0+ 版本才提供。
文章目录 改动说明bpmp里面给can附加pllaon时钟源pinmux修改方法一方法二方法三结果检验 设备树节点 clocks-init 去掉CAN的低功耗设置设备树节点 mttcan@c310000, mttcan@c320000 里附上 pllaon 时钟配置寄存器 TDCR设置脚本检验 与 CANFD 收发测试 改动说明 之前手中的Xavier一直用老版本的Jetpack, 最近换上较新的 Jetpack 4.6 以后, MTTCAN 配置发生了变化, CAN时钟默认为低功耗设置(没使能PLLAON), CAN工作不正常, 现象如下:
500K波特率有人拿示波器卡出180K或者160Kloopback测试和can1-can2收发都没有问题, 但是接到第三方CAN分析仪就闪红灯报错拿 ip -details -statistics link show can0 也看不出波特率设置的问题TX2 (T186)没有影响, Orin应该也没有这个影响, Xavier, Xavier NX (统称T194)受此影响 归根到底, 实际的时钟/波特率不对了. 可以用 下面的命令检验
#!/bin/sh sudo cat /sys/kernel/debug/bpmp/debug/clk/can1/parent sudo cat /sys/kernel/debug/bpmp/debug/clk/can2/parent 结果:
显示 osc 或者 pll_c 都不正常正常应显示 pll_aon默认 pll_c, 运行 sudo modprobe can, sudo modprobe can_raw, sudo modprobe mttcan 后应变为 pll_aon 需要进行修改的地方(T194平台, 适用于Xavier和Xavier NX):
1. SQL的两个重要标准 SQL92 和SQL99
2. SQL分类 数据定义语言 DDL(Data Definition Languages):对数据库结构的操作
定义了不同的数据库、表、视图、索引等数据库对象,还可以用来增删改数据库和数据表结构
主要的语句关键字:
CREATE:创建数据库、创建数据表、创建视图等
DROP:删除表
ALTER:修改表(eg.给表增加一个字段或删除一个字段)
RENAME:对表进行重命名
TRUNCATE:清空表内容
数据库操作语言 DML (Data Manipulation Language):对数据表记录的操作
用于对增删改查数据库记录,并检查数据完整性
主要的语句关键字:
INSERT:添加一条记录
DELETE:删除一条记录
UPDATE:修改一条记录
SELECT:查询记录
数据控制语言 DCL(Data Control Language),控制对数据表记录操作的操作,事务
用于定义数据库、表、字段、用户的访问权限和安全级别
主要的语句关键字:
GRANT:赋予权限
REVOKE:回收相关权限
COMMIT:提交记录
ROLLBACK:撤销记录
SAVEPOINT:回滚到具体的保存者上
3. SQL语言的规则与规范 3.1 基本规则 SQL语句可以用一行或多行来编写,但为了提高可读性,各语句需分行写,必要时使用缩进每条命令需使用结束标志符:;(\g)(\G)关键字不能用缩写也不能用分行所有小括号、单引号、双引号皆为成对出现所有输入皆为英文半角字符输入模式字符串型和日期时间类型的数据可以使用单引号表示列的别名,尽量使用双引号,而且不建议省略as 3.2 SQL大小写规范(建议遵守) 在Windows环境下大小写不敏感在Linux环境下大小写敏感
数据库名、表名、表的别名、变量名等皆严格区分大小写
关键字、函数名、列名、列的别名,忽略大小写推荐采用统一的书写规范
数据库名、表名、表别名、字段名、字段别名都是小写
SQL关键字、函数名、绑定变量等都大写 3.3 注释 单行注释:#注释或-- 注释 --
多行注释:/* 注释 */
3.4 命名规则 数据库名、表名不超过30个字符,变量名不超过29个字符只包含A-Z,a-z,0-9,共63个字符,不能有空格、保留字、数据库系统或常用方法冲突同一个MySQL软件中,数据库不能同名同一个数据库中,数据表不能重名同一个数据表中,字段名不能重名保持字段名和类型的一致性
1 问题 工作中往往因为一些魔幻操作, 导致HDP集群部署失败, 与其解决一个个奇怪的问题, 不如卸载重装
但是ambari UI页面不支持删除HDP集群, 如何操作呢?
2 分析 既然ambari不支持删除, 那就手动删除 (程序干的活, 无非是把人的行为有序的排列, 并一一执行)
删除HDP集群需要考虑如下几点
停止HDP组件服务清除ambari配置卸载HDP组件rpm包 (根据hdp版本号匹配)删除HDP组件目录 (日志/var/log, 运行/var/run, 配置/etc, 库/var/lib, 安装/usr/hdp) 3 方案 3.1 停止HDP服务 直接使用ambari UI, 停止所有服务
3.2 清除ambari配置 停止ambari-server服务 ambari-server stop
然后重置, ambari-server reset, 清除DB中的集群信息
3.3 卸载HDP组件包 yum -y remove *_2_6_4_0_91* hdp-select
HDP版本号根据实际情况选择
# yum list installed |grep HDP-2.6-repo-1 |head 0.8.0.2.6.4.0-91 @HDP-2.6-repo-1 bigtop-jsvc.x86_64 1.0.15-91 @HDP-2.6-repo-1 hadoop_2_6_4_0_91.x86_64 2.7.3.2.6.4.0-91 @HDP-2.6-repo-1 hadoop_2_6_4_0_91-client.x86_64 2.7.3.2.6.4.0-91 @HDP-2.6-repo-1 hadoop_2_6_4_0_91-hdfs.x86_64 2.7.3.2.6.4.0-91 @HDP-2.6-repo-1 hadoop_2_6_4_0_91-libhdfs.
qResource.pid.coalesce("").as("pid") 效果等于 isnull(pid,"");
在学习谷粒商城,使用人人开源项目时,需要将项目依赖进行下载并部署运行:
可能会遇到依赖下载失败等问题,大部分卡住的地方都是node-sass下载失败,在此记录以下自己的版本以及遇到的问题。
版本信息 Node.jsnpm
npm是下载node.js时自带的,一般不会发生版本问题,除非更换了node.js版本并没有完全卸载npm
其中node-sass和node-js版本需要对应上,出现版本不一致问题时查看官网版本并对应下载即可(https://www.npmjs.com/package/node-sass)
部署步骤 下载Node.js 配置npm 淘宝镜像源 node.js 下载地址https://nodejs.org/en/ 下载完毕之后,打开cmd,使用以下命令配置镜像源 npm config set registry http://registry.npm.taobao.org 下载cnpm
视频里是使用npm install直接下载安装的,我在实际操作过程中遇到了很多问题,查看人人开源github上推荐使用cnpm下载(地址:https://github.com/renrenio/renren-fast-vue/wiki/Getting-started)
下载cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org 手动指定node-sass安装镜像源 npm config set sass_binary _site=https://npm.taobao.org/mirrors/node-sass 使用cnpm下载依赖 cnpm install 运行项目 cnpm run dev 运行成功
目录
1. 死锁的概述
2. 产生死锁的4个必要条件
3.处理死锁问题的方法
4. 预防死锁
破坏互斥条件
破坏请求和保持条件
破环不可剥夺条件
破坏环路等待条件
5. 避免死锁
安全状态
6. 银行家算法
7. 死锁的检测和解除
死锁定理
8. 哲学家进餐问题
1. 死锁的概述 2. 产生死锁的4个必要条件 必要条件是指死锁一定具备的条件,但具备该条件的不一定是死锁。
互斥条件
请求保持条件
不可剥夺条件
环路等待条件
3.处理死锁问题的方法 鸵鸟方法
预防死锁
避免死锁
检测死锁
解除死锁
检测死锁即事先不需要做任何限制性措施
4. 预防死锁 预防死锁需要破坏死锁的4个必要条件中的一个或几个
破坏互斥条件 破坏请求和保持条件 破环不可剥夺条件 破坏环路等待条件 预防死锁的代价较高,计算机不采用。
5. 避免死锁 安全状态 死锁是不安全状态的一个子集
6. 银行家算法 银行家算法是最具代表性的避免死锁的算法
即:
先将请求矩阵和需求矩阵和可用矩阵分别进行比较
再进行资源试分配
再进行安全性算法 注意试分配向量的构建
最后需要写出安全序列
安全算法最后所有都是true才正确,即不会发生死锁。
7. 死锁的检测和解除 资源分配图的概念
有环路不一定有死锁
右图P2P4可以注入资源
死锁定理 去掉边时注意归还资源
死锁的解除 目录
#!/bin/bash #kafka集群地址: ip/主机名:9092 KAFKA_CLUSTER=10.10.2.234:9092 #kafka bin目录 KAFKA_HOME_BIN=/opt/kafka_2.12-2.2.2/bin #分区数量 PARTITIONS=5 #副本数量 REPLICATIONFACTOR=2 #脚本路径 SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" #参数判断不能小于1 if [ $# -lt 1 ]; then echo -e "\033[31mAt least two parameters \033[0mare required" sh /${SCRIPT_DIR}/kafka --help exit fi #打印传入的参数 #echo "============Args: $1 $2 =================" #输入错误参数,报错且返回--help内容 errorFun(){ echo -e "\033[31mInput Args Error!!!!\033[0m" sh /${SCRIPT_DIR}/kafka --help } case $1 in #脚本用法--help --help) echo " Usage: kafka [OPTIONS] SUBCOMMAND [SUBCOMMAND OPTIONS] OPTIONS is none or any of: -l or list <-t> <-g> list all topics/groups -c or create <topicName> [partitions] [replication-factor] create default topic or custom topic -d or desc [-t <topicName>] [-g <groupName>] describe all topics/topic/group -del or delete <-t <topicName>> <-g <groupName>> delete topic/group -p or producer <topicName> producer data to topic -con or consumer -e==earliest -l==latest <topicName> <groupName> consumer data from earliest or latest -r or reset <topicName> <groupName> <to-offset> reset all partitions offset to earliest,reset all partitions <topicName:partitionNum> <groupName> <to-offset> offset to optional position,reset one of partitions offset to optional position "
SNMP sysUpTime(OID 1.3.6.1.2.1.1.3.0) 时间戳信息解析遇到的问题 提示:sysUpTime: SNMP OID 1.3.6.1.2.1.1.3.0 计算出来的启动时间,与设备显示的不一致 SNMP V2C Trap 时间戳详细解析
最近计划通过SNMP Trap 获取设备的事件信息,发现Trap时候,设备会发生
OID = 1.3.6.1.2.1.1.3.0 的字段信息。
查资料,发现该OID表示MIB中的sysUpTime。
网络上查询该OID的定义解析:
RFC1213 defines sysUpTime as a 32-bit counter in 1/100 second. From the RFC’s definition of sysUpTime:
“The time (in hundredths of a second) since the network management portion of the system was last re-initialized.”
即是:该字段的值是32-bit 的计数器, 每1个单位,表示1秒的百分之一,即是0.01秒。 该计数器的值,是从设备启动后开始计数。
但是通过Trap收到的华为S9xxx设备发来的 sysUpTime ,与设备时间开机时间无法对上。
抓取到的 OID = 1.3.6.1.2.1.1.3.0 , timeticks-value=4294967296