C语言库函数strncpy,strncat,strncmp函数的模拟实现

strncpy,strncat,strncmp函数的模拟实现 #include<stdio.h> void my_strncpy(char* arr1,const char* arr2,int n) { for(int i = 0;i<n;i++) { *arr1++ = *arr2++; } *arr1 = '\0';; } int main() { char arr1[] = "abcdef*"; char arr2[] = "abef"; my_strncpy(arr1,arr2,3); printf("%s",arr1); return 0; } (解析) 1.strncpy函数较strcpy函数多了一个大小的变量n,即我能指定拷贝几个字符,我自己说了算 2.变化就是加了一个循环控制n次,每一次拷贝一个字符,然后地址加一,不再将’\0’作为拷贝结束的标志 3.因为拷贝未涉及‘\0’,所以最后加上一个‘\0’为宜,避免拷贝完‘\0’也被替换 #include<stdio.h> void my_strncat(char* arr1,const char* arr2,int n) { while(*arr1) { arr1++; } for(int i = 0;i<n;i++) { *arr1++ = *arr2++; } *arr1 = '\0'; } int main() { char arr1[30] = "

JVM与操作系统

为什么要在程序和操作系统中间添加一个JVM? Java是一门抽象程度特别高的语言,提供了自动内存管理等一系列的特性。这些特性直接在操作系统上实现是不太可能的,所以就需要JVM进行一番转换。 从图中可以看到,有了JVM这个抽象层之后,Java就可以实现跨平台了。JVM只需要保证能够正确执行.class文件,就可以运行在诸如Linux、Windows、MacOS等平台上了。 而Java跨平台的意义在于一次编译,处处运行,能够做到这一点JVM功不可没。比如我们在Maven仓库下载同一版本的jar包就可以到处运行,不需要在每个平台上再编译一次。 现在的一些JVM的扩展语言,比如Clojure、JRuby、Groovy等,编译到最后都是.class文件,Java语言的维护者,只需要控制好JVM这个解析器,就可以将这些扩展语言无缝的运行在JVM之上了。 应用程序、JVM、操作系统之间的关系 JVM上承开发语言,下接操作系统,它的中间接口就是字节码。 

Mybatis是什么?

MyBatis是一款优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。 php入门到就业线上直播课:进入学习 Apipost = Postman + Swagger + Mock + Jmeter 超好用的API调试工具:点击使用 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。 mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。 mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。 MyBatis的主要设计目的就是让我们对执行SQL语句时对输入输出的数据管理更加方便,所以方便地写出SQL和方便地获取SQL的执行结果才是MyBatis的核心竞争力。 Mybatis的功能架构分为三层: 1、API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。 2、数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。 3、基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

vue中选择框设置可编辑可选择状态

<el-form-item label="被叫号码" required> <el-select v-model.trim="callOutForm.calloutNo" filterable style="margin-right: 15%;width:80%;" clearable @blur="selectBlur" @clear="selectClear" @change="selectChange" > <el-option v-for="item in callerNolist1" :key="item.dictValue" :label="item.dictValue" :value="item.dictValue" /> </el-select> </el-form-item> // 实现select选择框可下拉单选,也可输入赋值 selectBlur(e) { // 意见类型 if (e.target.value !== "") { console.log(e.target.value); this.callOutForm.calloutNo = e.target.value; this.$forceUpdate(); // 强制更新 } }, selectClear() { this.callOutForm.calloutNo = ""; this.$forceUpdate(); }, selectChange(val) { this.callOutForm.calloutNo = val; this.$forceUpdate(); },

C# 弹出小窗口并将窗口参数返回给主窗口

在上一章(C# 按Button弹出新的窗体 Show()方法 和 ShowDialog()方法)的基础上,我们实现窗口之间参数的传递,界面如下 先启动Form1,点button1,弹出Form2,在Form2窗口,点Send 铵键,就把67890传回Form1并textbox里显示出来,如何实现呢? 1 先建好Form1和Form2界面,至于如何建立,可以参考章节:C# 按Button弹出新的窗体 Show()方法 和 ShowDialog()方法 , 这里不再详述。 2 主窗口代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace 窗口之间参数传递 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } Form2 input_macform2; private void button1_Click(object sender, EventArgs e) { if (checkBox1.CheckState == CheckState.Checked) { input_macform2 = new Form2(); input_macform2.TaskEvent += new TaskDelegate(form2_TaskEvent); input_macform2.

玩转汇编——通用数据处理指令(一)

玩转汇编——通用数据处理指令(一) 一、数据传送指令(一)通用传送指令1.传送指令MOV2.交换指令XCHG (二)堆栈操作指令1.进栈指令PUSH2.出栈指令POP3.堆栈的应用 (三)其他传送指令1.地址传送指令2.换码指令3.与IO交互的输入输出指令 一、数据传送指令 (一)通用传送指令 1.传送指令MOV ①源操作数与目的操作数类型必须一致 ②两个操作数其中之一必须要有明确的类型,两者都无法指定类型时,要显示指定(eg. mov byte ptr [bx],255 即byte ptr 说明是字节操作 ) ③不允许两个操作数都是主存单元 ④对专用寄存器可进行操作的指令有限,功能不强,使用时要注意。(例如,立即数不能直接传送段寄存器DS,要通过AX间接传送给DS) 2.交换指令XCHG 交换指令XCHG用来将8位或16位源操作数和目的操作数内容交换,可以在通用寄存器与通用寄存器或存储器之间对换数据。 合法格式:〈reg通用寄存器 mem存储器〉 xchg reg,reg/mem xchg reg/mem,reg 交换指令实现位置互换,无所谓源操作数与目的操作数的位置前后,注意操作数不能是立即数,也不支持存储器与存储器之间数据对换。 在8086处理器中,空操作指令(助记符NOP)NOP与xchg ax,ax等价。空指令有两个作用:(1)该指令在主存中占用一字节空间,可用来临时占用代码空间,以便后续填入需要的指令代码;执行空指令花费时间,可实现短时间延时。 (二)堆栈操作指令 堆栈是一个按照“先进后出FIFO”存取原则组织的存储区域。堆栈具有两种基本操作:数据压入堆栈(进栈指令PUSH),数据弹出堆栈(出栈指令POP)。 8086处理器的堆栈建立在主存区域中,SS段寄存器指向段基地址,堆栈段的范围由堆栈指针寄存器SP的初值确定,这个位置就是堆栈底部(栈底处于高地址,栈顶处于低地址,栈顶即为数据入口)。数据进入堆栈,SP逐渐减小(SP-2H);数据依次弹出堆栈,SP逐渐增大(SP+2H)。 8086处理器的堆栈只能以字为单位操作。 1.进栈指令PUSH 由于目的位置就是栈顶,由SP确定,PUSH指令只表达源操作数。(SP自减) 格式为:push r16/m16/seg <r16 表示16位通用寄存器内容,m16表示16位存储操作数,seg表示段寄存器内容> PUSH操作步骤: ①SP←SP-2 ②SS:[SP]←r16/m16/seg 进栈字量数据时,SP向低地址移动2字节单元指向栈顶,即减2(准备了两个字节的存储单元);然后数据以“低对低,高对高”的小端方式放到栈顶。 2.出栈指令POP 由于源操作数在栈顶,由SP确定,POP指令只表达目的操作数。(SP自增) 格式为:pop r16/m16/seg POP操作步骤: ①r16/m16/seg←SS:[SP] ②SP←SP+2 出栈字量数据时,首先数据以“低对低,高对高”的小端方式原则从栈顶传送目的位置;然后SP向高地址移动2字节单元,即加2。 3.堆栈的应用 (三)其他传送指令 1.地址传送指令 存储器操作数具有地址属性,地址传送指令获取存储器操作数的地址 LEA r16,mem ;r16←mem的有效地址EA(不需类型一致) LEA指令类似于地址操作符OFFSET的作用 LEA指令在指令执行时计算出偏移地址 OFFSET操作符在汇编阶段取得变量的偏移地址 OFFSET无需在执行时计算、指令执行速度更快 LEA指令能获取汇编阶段无法确定的偏移地址 2.换码指令 数据表是常见的数据结构,编程中经常需要获得数据表中某个特定的数据项,处理器为此专门设计了换码指令。 XLAT指令功能:AL←[BX+AL] 使用XLAT指令前,将BX指定的缓冲区中,AL指定的位移处的一个字节数据,取出赋给AL(由于XLAT指令隐含使用BX和AL,所以其助记符后无须写出操作数,默认该缓冲区在DS数据段)。 换码指令执行前:

静态HTML网页设计作品 DIV布局家乡介绍网页模板代码---(太原 10页带本地存储登录注册 js表单校验)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材,DIV+CSS 布局制作,HTML+CSS网页设计期末课程大作业 | 家乡旅游景点 | 家乡民生变化 | 介绍自己的家乡 | 我的家乡 | 家乡主题 | HTML期末大学生网页设计作业 HTML:结构 CSS:样式 在操作方面上运用了html5和css3, 采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识 JavaScript:做与用户的交互行为 文章目录 前端学习路线网页基本结构网页演示HTML结构代码 学的反而越迷茫学习更多 前端学习路线 (1)html文件:其中index.html是首页、其他html为二级页面; (2)css文件:css全部页面样式,文字滚动, 图片放大等; (3)js文件:js实现动态轮播特效, 表单提交, 点击事件等等(网页中运用到js代码) 网页基本结构 (1)首页:进入网页中看到的第一个页面(LOGO、公司名称、导航、banner、新闻、相关信息、底部信息、banner一般是5个 (2)二级页面:从首页点击进入之后的页面叫做二级页面 (3)三级页面:从二级页面点击进入的页面 网页html:网页是构成网站的基本元素,是承载各种网站应用的平台。通俗地说,网站就是由网页组成的 首页网站:首页是一个网站的入口网页,故往往会被编辑得易于了解该网站多数作为首页的文件名是index加上扩展名 导航菜单:是指位于页面顶部或者侧边区域的,也称之为导航栏,它起着链接站点或者软件内的各个页面的作用. 网页页脚:是网页中每个页面的底部的区域。常用于显示附加信息。如作者、备案号等。 网页演示 HTML结构代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ padding: 0; margin: 0; box-sizing: border-box; font-family: "微软雅黑"; } .content{ width: 1000px; background: #fde8cb; margin: auto; padding: 0 50px; position: relative; } .

ES6 模块化

一、回顾: node.js 中如何实现模块化 node.js 遵循了 CommonJS 的模块化规范。其中: 导入其它模块使用 require() 方法 模块对外共享成员使用 module.exports 对象 模块化的好处: 大家都遵守同样的模块化规范写代码,降低了沟通的成本,极大方便了各个模块之间的相互调用,利人利己。 二、前端模块化规范的分类 在 ES6 模块化规范诞生之前, JavaScript 社区已经尝试并提出了 AMD 、CMD 、CommonJS 等模块化规范。 但是,这些由社区提出的模块化标准,还是存在一定的差异性与局限性 、并不是浏览器与服务器通用的模块化 标准,例如: AMD 和 CMD 适用于浏览器端的 Javascript 模块化 CommonJS 适用于服务器端的 Javascript 模块化 太多的模块化规范给开发者增加了学习的难度与开发的成本。因此, 大一统的 ES6 模块化规范诞生了! 三、什么是 ES6 模块化规范 ES6 模块化规范是浏览器端与服务器端通用的模块化开发规范。它的出现极大的降低了前端开发者的模块化学习成本,开发者不需再额外学习 AMD 、CMD 或 CommonJS 等模块化规范。 ES6 模块化规范中定义: 每个 js 文件都是一个独立的模块 导入其它模块成员使用 import 关键字 向外共享模块成员使用 export 关键字 四、在 node.js 中体验 ES6 模块化 node.js 中默认仅支持 CommonJS 模块化规范,若想基于 node.

枚举与联合体

枚举类型的定义 枚举类型的语法形式: enum 枚举名称 { 枚举元素1; 枚举元素2; ...... }; 枚举类型的定义: //用枚举举例星期 enum Day//枚举的名称 { Mon, Tues, Wed, // 枚举星期的所有可能 Thur, Fri, Sat, Sun }; 以上定义的 enum Day 是枚举类型{ }中的内容是枚举类型的可能取值,也叫枚举常量这些可能取值最开始都是默认从0开始,一次递增1当然在定义的时候也可以赋初值后面的枚举常量是依次递增的,也可以一个一个赋值 枚举的优点 1.代码的简洁性、增加代码的可读性和可维护性 2.枚举 enum 和 define 对标 3.如果不使用枚举,用 #define定义来为每个可能定义一个别名 4.定义可能性比较多,比如:月份那代码就比较多且臃肿,如果使用枚举就会很简洁,而且增加代码的可读性和可维护性 5.还有就是以枚举类型定义具有一定的意义 可以使用到一些程序中 enum sex { MALE; FEMALE; SECRET }; int main() { enum sex a; // 定义枚举变量 a = MALE; printf("%d",a); return 0; } 在一些程序中枚举较define的优势和#define定义的标识符比较枚举有类型检查,更加严谨防止命名污染便于调试使用方便,一次可以定义多个常量 枚举的使用 遍历枚举类型 在C语言中枚举类型是被当做 int 或者 unsigned int 类型来处理的

Apollo学习(超详细)

Apollo 文章目录 Apollo1. 学习地址2. 概览1. 什么是配置2. 什么是配置中心 3. Apollo简介1. 主流配置中心1.1. 功能特性对比1.2 总结 2. Apollo简介3. Apollo特性 4. Apollo快速入门1. 执行流程2. 安装Apollo2.1 运行时环境2.2 下载配置2.3 创建数据库2.4 启动Apollo 5. 代码实现1. 发布配置2. 应用读取配置1. 新建Maven工程2. 编写测试类GetConfigTest3. 测试4. 修改配置5. 热发布 6. Apollo应用1. Apollo工作原理1. 各模块职责2. 分步执行流程 2. 核心概念3. 项目管理1. 基础设置2. 创建项目3. 删除项目 4. 配置管理1. 添加发布配置项2. 修改配置3. 删除配置4. 添加Namespace 1. 学习地址 地址 2. 概览 1. 什么是配置 应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数据库连接参数、启动参数等。 配置主要有以下几个特点: 配置是独立于程序的只读变量 配置首先是独立于程序的,同一份程序在不同的配置下会有不同的行为其次,配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置 配置伴随应用的整个生命周期 配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。比如:启动时需要读取服务的端口号、系统在运行过程中需要读取定时策略执行定时任务等。 配置可以有多种加载方式 常见的有程序内部硬编码,配置文件,环境变量,启动参数,基于数据库等 配置需要治理 权限控制:由于配置能改变程序的行为,不正确的配置甚至能引起灾难,所以对配置的修改必须有比较完善的权限控制不同环境、集群配置管理:同一份程序在不同的环境(开发,测试,生产)、不同的集群(如不同的数据中心)经常需要有不同的配置,所以需要有完善的环境、集群配置管理 2. 什么是配置中心 传统单体应用存在一些潜在缺陷,如随着规模的扩大,部署效率降低,团队协作效率差,系统可靠性变差,维护困难,新功能上线周期长等,所以迫切需要一种新的架构去解决这些问题,而微服务( microservices )架构正是当下一种流行的解法。

Linux之查看进程ps -ef、进程的前后台切换fg、挂起后的激活bg、标准输入/输出/错误三者的重定向、管道

注意: 全称含义举例fgforeground前景、前台foreground process 前台进程bgbackground背景、后台background process 后台进程 fg、bg后面跟的都是后台进程的序号,不是PID进程号 fg 后台进程的序号——后台进程拉到前台 、将后台的进程调(读法:四声)到前台——也就是说,改变的只是进程所处的环境,即:从后台变成前台 bg 后台进程的序号——把后台挂起(即:Stopped、暂停)的进程,变成在后台继续执行、激活被挂起的进程、把后台Stopped状态的进程变成Running状态——也就是说,bg命令只是用来改变进程的状态,而进程所处的环境依然是在后台。 当然,也可以使用fg把它放到前台。 jobs——查看后台进程的状态 后台进程的几种状态:Stopped(挂起)、Running(运行中)、Killed(杀死)、Done(完成) ctrl+c——强制中断程序的执行,强制中断任务,即:程序会退出 ctrl+z——中断程序的执行,但不会退出,而是在后台被挂起,即:不会退出,而是处于stopped状态。 一、查看进程 ps ——查看当前用户,当前这一个终端上的进程,即:在哪个终端上敲ps,就只能看见那一个终端上的进程。 ps -ef——查看系统上所有的进程 其中,-e——显示所有进程;-f——全格式,所有的格式,即:显示全部的列(字段) 参数说明: [root@localhost~]#ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 18:00 ? 00:00:01 /sbin/init root 2 0 0 18:00 ? 00:00:00 [kthreadd] root 3 0 2 18:00 ? 00:00:00 [migration/0] UID——启动该进程的用户,即:谁启动了这个进程。 PID——进程号,进程的一个代号,是根据每个进程在系统中启动的时间顺序,系统自动编排的。 PPID——父进程的进程号 C——CPU的使用率,形式是百分数(%) STIME——进程启动时的系统时间 TTY——进程启动时的终端设备,如果显示?表示该进程不是由终端发起 TIME——进程的执行时间 CMD——进程的名称或对应的路径或命令 常见的组合命令: ps -ef | grep 进程名称

Kotlin 特殊字符处理

1、kotlin 版本 fun convertUploadContact(receiverIds: String?): String { val list = ArrayList<UploadContact>() if (!TextUtils.isEmpty(receiverIds)) { val sArr = receiverIds!!.split("$") for (ss in sArr) { if(!ss.equals("")) list.add(UploadContact(ss)) } } return toJSONString(list) } 2、 Java版 public String convertUploadContact(String receiverIds) { ArrayList<UploadContact> list = new ArrayList<>(); if (!TextUtils.isEmpty(receiverIds)){ String[] sArr=receiverIds.split("\\$"); for (String ss : sArr) { list.add(new UploadContact(ss)); } } return ToolUtils.toJSONString(list); }

【C进阶】之联合体与共用体和枚举

联合体/共用体 —> union 声明联合体的语法格式 typedef union 联合体名 { 数据类型 成员名1; 数据类型 成员名2; … } 联合体别名_t; 此时可以使用“union 联合体名”或者“联合体别名_t”定义联合体类型的变量。 什么是联合体 联合体属于构造类型,联合体中可以包含不同的数据类型的成员,联合体中的所有的成员共用同一块内存空间, 联合体类型的大小和联合体中最大的成员的大小一致。 定义联合体类型的变量 联合体别名_t 普通联合体变量名; 联合体别名_t * 联合体指针变量名; 联合体中的成员的初始化(一般只对某个成员初始化,并使用) 普通联合体变量名.成员变量名 = 初始值; 联合体指针变量名->成员变量名 = 初始值; 访问联合体中的成员 普通联合体变量名.成员变量名; // 普通的联合体类型的变量使用“.”访问联合体中的成员 联合体指针变量名->成员变量名; // 联合体指针类型的变量使用“->”访问联合体中的成员 #include <stdio.h> #include <stdlib.h> // 1. 声明联合体类型 typedef union Integer { unsigned int a; unsigned short b; unsigned char c; }Integer_t; int main(int argc, const char *argv[]) { /*your code*/ // 1.

MIMO雷达等效发射波束形成的理解及为什么相控阵雷达不存在这一说法

从相控阵雷达接收波束形成的式子入手: 对于相控阵目标处的合成信号是 s ( t ) ∑ k = 1 M e − j ( k − 1 ) ϕ s\left( t \right)\sum\limits_{k=1}^{M}{{{e}^{-j\left( k-1 \right)\phi }}} s(t)k=1∑M​e−j(k−1)ϕ 经过匹配滤波只剩下导向矢量的加和 ∑ k = 1 M e − j ( k − 1 ) ϕ \sum\limits_{k=1}^{M}{{{e}^{-j\left( k-1 \right)\phi }}} k=1∑M​e−j(k−1)ϕ了; 而对于MIMO雷达而言,目标处的合成信号是 ∑ k = 1 M s m ( t ) e − j ( k − 1 ) ϕ \sum\limits_{k=1}^{M}{{s_m\left( t \right){e}^{-j\left( k-1 \right)\phi }}} k=1∑M​sm​(t)e−j(k−1)ϕ

netstat详解

netstat命令是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。 语法: netstat [选项] 参数: -a或--all:显示所有连线中的Socket; -A<网络类型>或--<网络类型>:列出该网络类型连线中的相关地址; -c或--continuous:持续列出网络状态; -C或--cache:显示路由器配置的快取信息; -e或--extend:显示网络其他相关信息; -F或--fib:显示FIB; -g或--groups:显示多重广播功能群组组员名单; -h或--help:在线帮助; -i或--interfaces:显示网络界面信息表单; -l或--listening:显示监控中的服务器的Socket; -M或--masquerade:显示伪装的网络连线; -n或--numeric:直接使用ip地址,而不通过域名服务器; -N或--netlink或--symbolic:显示网络硬件外围设备的符号连接名称; -o或--timers:显示计时器; -p或--programs:显示正在使用Socket的程序识别码和程序名称; -r或--route:显示Routing Table; -s或--statistice:显示网络工作信息统计表; -t或--tcp:显示TCP传输协议的连线状况; -u或--udp:显示UDP传输协议的连线状况; -v或--verbose:显示指令执行过程; -V或--version:显示版本信息; -w或--raw:显示RAW传输协议的连线状况; -x或--unix:此参数的效果和指定"-A unix"参数相同; --ip或--inet:此参数的效果和指定"-A inet"参数相同。 使用实例: 实例1:列出所有端口 命令: netstat -a # 列出所有端口 netstat -at # 列出所有TCP端口 netstat -au # 列出所有UDP端口 netstat -ax # 列出所有unix端口 netstat -atnlp # 直接使用ip地址列出所有处理监听状态的TCP端口,且加上程序名 输出: 说明: 下面分析每一项的含义 Proto:协议名(tcp协议还是udp协议); recv-Q:网络接收队列 表示收到的数据已经在本地接收缓冲,但是还有多少没有被进程取走,recv()如果接收队列Recv-Q一直处于阻塞状态,可能是遭受了拒绝服务 denial-of-service 攻击; send-Q:网路发送队列 对方没有收到的数据或者说没有Ack的,还是本地缓冲区. 如果发送队列Send-Q不能很快的清零,可能是有应用向外发送数据包过快,或者是对方接收数据包不够快; 这两个值通常应该为0,如果不为0可能是有问题的。packets在两个队列里都不应该有堆积状态。可接受短暂的非0情况。 Local Address 解释

干货|Webhook配置钉钉/飞书机器人告警

马嘉炜 | Zabbix开源社区签约专家 SRE运维工程师,六年Zabbix监控系统使用经验。在Zabbix架构设计及性能优化领域有丰富的经验,擅长监控模板制作及Zabbix API的二次开发。 官方使用手册《Zabbix标准模板指南》译者 简介 自 Zabbix 4.4.4 版本开始,Zabbix 的报警媒介类型加入了Webhook的支持。 Webhook 类型可用于使用自定义 JavaScript 代码进行 HTTP 调用,可以很方便的和外部系统进行集成,例如钉钉机器人、飞书机器人、企业微信等。 也可以集成第三方的系统来实现更加高级的功能,例如当主机自动注册到 Zabbix 中时,通过 Webhook 类型调用 API,将资产信息同步到 CMDB 系统,或者报警发生时,调用自动化平台的 API 来实现故障自愈的能力。 Webhook VS 自定义脚本 配置钉钉机器人告警 一、创建报警媒介 打开 Web 界面,并导航到管理 -> 报警媒介类型,点击右上角创建媒介类型 配置报警媒介类型 配置参考如下: 名称:DingTalk 类型:Webhook 参数: | 名称 | 值 | 说明 | | —- | —- | —- | | HTTPProxy | | Http代理地址 | | Message | {ALERT.MESSAGE} | 告警消息内容 |

cache三种地址映像

为了把信息存放到Cache中,必须应用某种函数把主存地址映像到Cache,称作地址映像,即把存放在主存中的信息按照某种规则装入Cache。 cache与主存之间的地址映像方式有三种 1. 直接映像 每个主存块只能存放固定位置 在Cache中的位置 = 主存块号 % Cache总块数 优点:实现简单。对于任意一个地址,只需对比一个“标记”,速度最快 缺点:在其他地方有空闲Cache块,但8号主存块不能使用。 直接映射的地址结构: 标记位cache行号块内地址 2. 全相联映像 主存块可存放在Cache中的任意位置 优点:Cache存储空间利用充分,命中率高。 缺点:成本高,查找“标记”最慢,有可能需要对比所有行的标记。 全相联映射的地址结构: 主存块号块内地址 例题:假设某个计算机的主存地址空间大小为256MB,按字节编址,其数据Cache有8个Cache行,行长为64B。 256MB = 2^28B,所以主存地址共有28位。 其中,Cache行长为64B = 2^6B, 所以块内地址占6位 主存块号地址占据28-6 = 22位。 3. 组相联映像 组间直接映像,组内全相联映像,是直接映像和全相联映像的折中方案。 组间直接映像,组内全相联映像。 所属分组= 主存块号 % 分组数 r路组相联映像:r个Cache行为一组 标记位cache组号块内地址 例题:假设某个计算机的主存地址空间大小为256MB,采用2路组相联,按字节编址,其数据Cache有8个Cache块,块长为64B。 256MB = 2^28B,所以主存地址共有28位。 其中,Cache行长为64B = 2^6B,又因为是2路组相联一共有8个cache块所以一共有4组4=2^2所以组号为2位 所以块内地址占6位,组号为2位,主存块号地址占据28-6-2= 20位。

vue 后端post请求返回二进制文件流 本地进行下载

参考代码如下 function exportData(res) { let url = window.URL.createObjectURL(new Blob([res], { type: '.xlsx' })); let a= document.createElement('a'); a.style.display = 'none'; a.href = url; a.setAttribute('download', `数据统计报表.xlsx`); document.body.appendChild(a); a.click(); url = window.URL.revokeObjectURL(url); document.body.removeChild(a) } //导出文件 export async function microApptaskExport(param) { axios.defaults.headers["Authorization"] = `Bearer 用户token`; axios.defaults.headers['Content-type']='application/json;'; const res = await axios.post( "请求地址", param, { responseType: "blob", } ); if (res) { exportData(res); } }

CAT学习 (超详细)

文章目录 0.学习目标1.CAT入门1.1 什么是调用链监控1.1.1 架构的演进历史1.1.2 调用链监控的需求1.1.3 调用链监控的原理 1.2 什么是CATPinPoint**SkyWalking**Zipkin 1.3 CAT报表介绍 2.CAT基础2.1 下载与安装2.1.1 github源码下载2.1.2 模块介绍2.1.3 服务端安装2.1.3.1 linux源码安装2.1.3.2 windows安装 2.2 客户端集成2.2.1 简单案例添加 Maven 添加依赖启动 cat 客户端前的准备工作初始化编写代码运行SpringBoot 2.2.2 API介绍2.2.2.1 Transaction基本用法扩展API 2.2.2.2 EventCat.logEventCat.logError 2.2.2.3 Metric 2.2.3 CAT监控界面介绍2.2.3.1 DashBoard2.2.3.2 Transaction小时报表历史报表 2.2.3.3 Event第一级分类(Type)统计界面第二级分类(Name)统计界面 2.2.3.4 Problem2.2.3.5 HeartBeatJVM相关指标系统指标 2.2.3.6 Business基线基线生成算法:如何开启基线:注意事项 2.2.3.7 State 3.CAT高级3.1框架集成3.1.1 dubbo3.1.1.1 制作cat-dubbo插件3.1.1.2 服务提供方3.1.1.3 服务消费方3.1.1.4 测试 3.1.2 mybatis3.1.2.1 创建spring boot和mybatis的集成项目3.1.2.2 集成cat-mybatis插件:3.1.2.3 测试 3.1.3 日志框架3.1.3.1 搭建环境3.1.3.2 集成cat3.1.3.3 测试 3.1.4 Spring Boot3.1.4.1 搭建环境3.1.4.2 测试 3.1.5 Spring AOP3.1.5.1 搭建环境3.

Vivado 2018.3 安装步骤及 license 获取

本文的主要内容是介绍 Vivado 2018.3 版本的安装步骤及其 license 的获取与加载。 首先下载安装包,将其在没有中文的路径下解压。注意在解压前最好关闭电脑的杀毒软件,防止某些文件被拦截或者删除! 解压完成后打开文件夹,在最底部双击安装应用程序,如下图所示。 在欢迎界面点击 Next,如下图。 勾选三个 I Agree,然后点击 Next。 在版本选择这里勾选第三项 Vivado HL System Edition,因为该版本是最全的,然后点击 Next。 可以看到,如果默认安装的话,占用的磁盘空间有35.68GB,还是很大的。 这里可以取消勾选几项暂时用不到的(根据自己的需求),如下图,磁盘占用要求就下降了不少。 接下来选择软件安装路径, 建议选择除C盘以外的其他盘符,注意这个路径不要出现中文且不带特殊符号,我这里安装在D盘下。 下图是安装总结界面,看一下没有问题就点击Install。 接下来等待其安装就行,这个安装的时间长短跟电脑的性能也有关系。 注意这个过程中电脑要断开USB下载器,如果有连接的话,要拔下来。在安装的过程中可能会弹出下面的对话框,点击取消即可。 也会弹出和Matlab相关的对话框,点击OK,我电脑此时还没安装Matlab,因此点击后会显示找不到,自动进入后续步骤。如果你的电脑装了Matlab,也先不要选择。 如下图,到这里 Vivado 就安装成功了。 但是还有一个许可管理对话框,没有license的话只能免费使用30天。 license的获取可以参考文章 vivado2018.3安装注册指南。 下载该license后将其解压保存到某一个文件夹下,然后点击 Load License,选择 Copy License。 找到刚才下载license的存放路径,选择即可,如下图所示,license就安装成功了! 点击View License Status查看一下license的状态,显示是Bought的话就表示我们的license起作用了! 到这里 Vivado 的安装就彻底结束了,接下来就可以打开软件使用了! 以上就是Vivado 2018.3 安装步骤及 license 获取的全部内容了! 参考视频: Vivado软件的安装 参考文章: vivado2018.3安装注册指南