管理运气-奥卡姆剃刀法则

本周学习了赌神运气管理思维,赌神思维的要求非常简单,就是根据已知胜率、赔率的组合,评估全局“风险收益比”,制定严格简单的纪律降低风险,保护全局总成本。 赌神思维非常符合吴军老师讲的奥卡姆剃刀法则、最大熵原理。 一、奥卡姆剃刀法则又被称为“简约之法则”:简洁的往往是正确的,越是复杂,越容易犯错。 西方历代大学问家,都将奥卡姆剃刀法则作为自己治学的行为准则。世界本身的规律在形式上并不复杂,从牛顿力学,到爱因斯坦的相对论,到今天物理学的标准模型,在历史上各个时代,最高深的物理学理论,从形式上并不复杂。 在数学上叫寻找到一组基函数,如傅里叶变换,正弦或者余弦函数就是基函数。在任何领域,都有这种成为支撑点的关键信息。掌握和利用这些支撑点,就如同用剃刀剔除树的枝叶,把多余的枝枝蔓蔓,使我们困惑的信息去掉。 二、最大熵原理的实质就是,当我们需要对一个随机事件的概率分布进行预测时,在已知部分知识的前提下,对未知的情况不要做任何主观假设。在这种情况下,概率分布最均匀,预测的风险最小。因为这时概率分布的信息熵最大,所以人们称这种模型叫“最大熵模型”。我们常说,不要把所有的鸡蛋放在一个篮子里,就要保留各种可能性。 最大熵模型的优势是:保证结果能覆盖到当前已知可行性,不做任何主观猜测,这样的模型最光滑,不会遇到黑天鹅事件,当我们遇到矛盾的先决条件时,最大熵模型会自动选择两个条件的中间点,保证信息的损失最小。 赌神思维的重要法则也是遵守简单的赔率意识,通过概率的复利设计全局策略,严守纪律,触发点及时离桌,避免黑天鹅,避免主观干扰被无差别绞杀。

git的安装与配置步骤详情

1、按顺序安装【1、2是git和小乌龟的安装包,3是汉化软件】 2、配置git用户名: git config --global user.name “zxc” git config --global user.email “123@126.com” 3、配置ssh密钥 命令行:ssh-keygen -t rsa -C “你的邮箱” 【我是用的上面的邮箱】 ssh-keygen -t rsa -C “123@126.com” 4、将ssh密钥在码云里面进行绑定 注意:如果配置ssh密钥成功,则在一下的文件夹中会显示以下三个文件。 如果只有两个则大概会出现–Are you sure you want to continue connecting (yes/no)? yes,此时回复yes即可 5、打id_rsa文件,全部复制里面的东西【可用记事本格式打开】 去码云里面进行粘贴 7、创建一个仓库,.git文件夹可能会被隐藏掉,记得勾选显示隐藏的文件夹 使用命令 git init --》表示初始化一个仓库【此时会创建一个.git文件夹】 8、将本地库与远程库连接 使用命令 git remote add origin 【码云上面远程库的ssh】,git@gitee.com为码云的地址 git remote add origin git@gitee.com:xxxx/test.git 9、前面若都没问题,则到此步你的git和码云就应配置好了,你可以创建一个文件提交到码云上面去尝试一下,记得要先同步码云上面的东西,在提交你本地库的东西 注意:以上所产生的文件有可能会被隐藏,所以记得勾选显示隐藏的东西,这里展示的是用命令行来创建仓库,也可以用小乌龟来跟码云连接,(关于小乌龟的配置在我的另一篇文章里)

C++调用DLL学习笔记——动态调用

C++调用DLL 编译DLL时会生成两个文件,一个是lib, 一个是dll. 注意,此处生成的lib文件和静态库的lib文件不是一个东西。 调用DLL有两种方式:隐式加载、显式加载。 一、隐式加载方式 隐式加载方式下,需要3个文件,分别是dll文件、lib文件以及对应的头文件。例paneldata.dll、paneldata.lib、paneldata.h,将上述文件放入调用程序代码所在目录。 调用代码非常简单,程序中只需要增加两行代码,以下举例说明: #include<iostream> #include "paneldata.h" //引入头文件 #pragma comment(lib,"paneldata.lib") //把lib文件包括进来 int main(){ int result = paneldata_func1(3.14); //像调用本地函数一样调用外部函数 cout<< result <<endl; return 0; } 二、显式加载方式 显式加载方式下,调用dll文件只需要为调用者提供一个.dll文件,以及要调用的函数(或类)的名称和参数,将dll文件放入调用程序代码所在目录。 调用有以下步骤: 1、typedef一个与被调用函数类型一致的函数指针。 typedef int (*Dllfunc)(double) //假设被调用函数返回值为int, 参数类型为double 在这段代码中,Dllfunc的类型被定义为: “一个指向返回值为int 且 参数类型为double的函数的指针”。 划重点: typedef 绝不是像 typedef int integer 这么简单——把类型名换个别名。为了深入理解以上代码,建议对此知识点另外深入学习。 2、获得dll文件的句柄。因为是动态调用,dll和可执行文件一起发布,要调用dll,必须先获得它的句柄,要用到一个函数: HMODULE hDLL = LoadLibrary(dllname); //HMODULE 是windows句柄类型,为了使用它,头文件中需包括windows.h 3、定义一个函数指针,用于指向dll中被调用的函数地址,以实现函数功能。 DLLFunc dllfunc; dllfunc = (DLLFunc)GetProcAddress(hDLL, "paneldata_func1"); 现在就可以像使用paneldata_func1()一样来使用dllfunc()了。 最后,别忘了释放dll句柄: FreeLibrary(hDLL); 完整代码如下: #include "windows.h" typedef int (*Dllfunc)(double); int main(){ const wchar_t* dllname = L"

Redis的作用和原理

Redis的作用和原理 本文章基于淘淘商城电商项目实现过程中的反思,包括以下几部分: 内容管理为什么用redis缓存替代持久化数据库?缓存的作用?Redis实现了什么?为什么Redis缓存速度这么快? 1、内容管理为什么用redis缓存替代持久化数据库? 这涉及到持久化数据库的缺点,如下: (1)存储在部署数据库的硬盘上 平时我们使用的关系型数据库有MySql,Oracle以及SqlServer等,通常通过数据驱动来链接数据库进行增删改查。 那么我们日常使用的数据库都存在哪里?以MySql为例。如图所示: (2)访问速度 服务器的读写效率是网站运行速度的重要条件,当然还有服务器的宽带,但是这些可以通过硬件的升级更新等办法来解决。 服务器处理数据的速度,也与网站速度息息相关,而数据查询、数据处理等和数据库处理速度有关。所以,提高数据库处理数据的能力很重要。 其实,sql语句优化可以提高处理效率。但是如果网站的访问量非常大的时候,我们的数据库压力就变大了。数据库的连接池、处理数据的能力就会面临很大的挑战。此时就要使用高并发处理、负载均衡和分布式数据库了。 2、缓存的作用 (1)定义 缓存就是在内存中存储的数据备份,当数据没有发生本质变化的时候,我们避免数据的查询操作直接连接数据库,而是去内存中读取数据,这样就大大降低了数据库的读写次数,而且从内存中读数据的速度要比从数据库查询要快很多。 (2)缓存的形式 页面缓存(smarty静态化技术):页面缓存经常用在CMS(content manage system)内存管理系统里面。 数据缓存:经常会用在页面的具体数据里面。 3、Redis实现 Redis是Remote Dictionary Server(远程数据服务)的缩写,由意大利人antirez(Salvatore Sanfilippo)开发的一款内存高速缓存数据库,该软件使用C语言编写,它的数据模型为key-value。 它支持丰富的数据结构(类型),比如String、List、Hash、Set、Sorted Set。 可持久化(一边运行,一边把数据往硬盘中备份一份,防止断电等情况导致数据丢失,等断电情况恢复之后,Redis再把硬盘中的数据恢复到内存中),保证了数据的安全。 4、为什么Redis缓存速度这么快 首先介绍下硬盘数据库(例如mysql)和Redis的工作模式 (1)硬盘数据库的工作模式: 需要先从数据读取数据到内存,内存中的数据保存到硬盘,我们更改硬盘的数据后再保存到数据库。这里的步骤较多,而且还占用我们的硬盘容量。 (2)内存数据库的工作模式: 这种方式相比硬盘数据库的方式少了内存到硬盘这一步,速度回快很多,而且不占用我们的硬盘容量。我们用的Redis就是基于这种方式的。 以上用比较容易理解的方式解释Redis的工作原理以及速度快的原因,下面深入探索一下Redis为什么这么快: 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;使用多路I/O复用模型,非阻塞IO;使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

Cesium学习(一)An error occurred while rendering

基于Cesium1.68进行学习。 在Firefox、chrome中运行下面文件都会遇到问题。 <!DOCTYPE html> <html lang="en"> <head> <!-- Use correct character set. --> <meta charset="utf-8"> <!-- Tell IE to use the latest, best version. --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Make the application on mobile take up the full browser screen and disable user scaling. --> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>Hello World!</title> <script src="../Build/Cesium/Cesium.js"></script> <style> @import url(../Build/Cesium/Widgets/widgets.css); html, body, #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> <div id="

ZigBee入门-CC2530-实验(八)-ADC采集-串口通信-代码

ADC采集是MCU感知外界的唯一途径,将外界的模拟信号转换成MCU可识别的数字信号,进而实现感知,控制。咱们zigbee网络中,终端节点的角色就是用来采集各种模拟量,例如:光照、温湿度、可燃气体浓度、等等,然后将采集的数据通过天线发送给协调器,或路由器,进行下一步的数据处理。 /*本次实验实现: 光照采集模块: 根据不同的光照引起光敏电阻阻值的变化, 用ADC采集电压值, 然后将电压值通过串行口给上位机, 上位机在串口调试助手上显示数值*/ // 话不多说~直接上代码 #include <ioCC2530.h> #define uchar unsigned char //宏定义uchar为unsigned char #define uint unsigned int //宏定义uint为unsigned int #define LED P1_0 //宏定义LED为P1_0脚 uint ADC_value=0; //定义ADC转换值 float ADC_result=0; //定义ADC最终值 char ADC_data[6]=" 0.0V "; //定义串口数组 void Init_LED(); //声明LED 初始化函数 void Init_ADC(); //声明ADC初始化函数 void Init_UART0(); //声明串口0初始化函数 void UR0_SendString(char *str,char len);//声明字符串发送函数 void LED_RUN(); //声明LED闪烁函数 void Delay(uint ms); //声明延时函数 /*======================主程序入口==================*/ void main(void) { Init_LED(); //LED 初始化 Init_ADC(); //ADC初始化 Init_UART0(); //串口0初始化 while(1) //死循环 { if(ADCIF) //是否转换完毕 { ADCIF = 0; //采样标志位清零 //读取adc数值 ADC_value = ADCH; //读取高8位 ADC_value <<= 8; //将ADCH移到高位 ADC_value |= ADCL; //读取低8位 ADC_value >>= 3; //去掉空位 // 0 表示 0V ,3.

STM32开发,使用F103C8T6驱动3.2寸SPI口LCD屏

STM32开发,使用F103C8T6驱动3.2寸SPI口LCD屏 1 概述1.1 最小系统板资源概述1.2 实现功能 2 硬件介绍2.1 最小系统板硬件介绍2.2 LCD屏原理图2.3 连接关系 3 程序实现3.1 代码架构3.2移植工作3.3 SPI部分代码讲解 4 实验结果5 迁移到RBT6开发板5.1 单板连接 6 STM32F407的LCD程序的移植6.1 程序地址 1 概述 部分实验代码已经上传。另外最小系统板和SPI触摸屏均购买于某宝,总成本42元包邮。 1.1 最小系统板资源概述 开发板:STM32F103C8T6最小系统板 CUBEMX版本:1.3.0 MDK版本:5.27 主控芯片型号:STM32F103C8T6 LCD屏幕参数:3.2寸LCD,SPI口,带触摸功能。 最小系统板如下 SPI触摸屏如下 1.2 实现功能 购买的屏幕提供了驱动程序,但是没有C8T6的型号,需要进行移植,在最小系统板上实现触摸屏显示功能。 2 硬件介绍 2.1 最小系统板硬件介绍 最小系统板,除了一个PC13作为用户按键灯外全部GPIO口进行了引出,另外最小系统板不带EEPROM。无法移植屏幕触摸功能。 2.2 LCD屏原理图 LCD屏集成触摸检测,集成一个SD卡插座,这里我们都用不到。 2.3 连接关系 使用杜邦线进行连接,连接关系如下 LCD模块STM32单片机VCCDC5V/3.3V //电源GNDGND //电源地SDI(MOSI)PB15 //液晶屏SPI总线数据写信号SDO(MISO)PB14 //液晶屏SPI总线数据读信号,如果不需要读,可以不接线LEDPB9 //液晶屏背光控制信号,如果不需要控制,接5V或3.3VSCKPB13 //液晶屏SPI总线时钟信号DC/RSPB10 //液晶屏数据/命令控制信号RSTPB12 //液晶屏复位控制信号CSPB11 //液晶屏片选控制信号 3 程序实现 3.1 代码架构 在原程序的基础上,进行删减工作,程序架构如下。 3.2移植工作 1,删除hd.s文件增加md.s文件,,删除触摸相关部分代码,如IIC等。删除了touch相关的代码(最小系统板没有IIC,不支持)。 2,点击Keil的魔术棒,选择器件类型为STM32F103C8。 3,在全局宏定义define中,hd改为md。 4,修改GPIO口的定义 将购买SPI屏幕附赠的Demo程序里的GPIO口修改为实际单板的GPIO口。 3.3 SPI部分代码讲解 SPI2初始化,需要特别注意的是,SPI2是在APB1上,但是其使用的GPIO口是在APB2上,均需要使能其对应时钟。分频系数为2,时钟频率为36MHz/2=18MHz。使用SPI2的步骤为:

Websocket实现断网重连

Websocket实现断网重连 代码如下: 定义的变量如下: var lockReconnect = false;//避免重复连接 var wsUrl = "ws://localhost:8080/websocket/111"; // websocket链接 var ws;// websocket对象 首先判断是否支持websocket if ("WebSocket" in window) { .... }else{ alert("您的浏览器不支持websocket 请更换浏览器后重试!"); } 创建一个websocket对象 function createWebSocket(){ try { ws = new WebSocket(wsUrl); websocketInit();//对websocket对象进行初始化 } catch (e) { console.log('创建异常 执行重连。。'); websocketReconnect(wsUrl);//调用重连方法 } } createWebSocket(); // 创建websocket 创建了一个websocketInit方法 对websocket进行初始化 function websocketInit () { // 建立 websocket 连接成功触发事件 ws.onopen = function (evt) { onOpen(evt);//连接成功后执行的方法 }; // 断开 web socket 连接成功触发事件 ws.

Windows 不能在 本地计算机 启动 SQL Server (MSSQLSERVER)。有关更多信息,查阅系统事件日志。如果这是非 Microsoft 服务,请与服务厂商联系,并参考特定服务错误代

问题: 前几天生产工控机上启动SQL Server 的时候出现“Windows 不能在 本地计算机 启动 SQL Server (MSSQLSERVER)。有关更多信息,查阅系统事件日志。如果这是非 Microsoft 服务,请与服务厂商联系,并参考特定服务错误代码 3417” 解决方案 网上提供了很多解决方案,有的说将服务的账号改成本地账号、sql server 安装目录把“压缩以释放空间”选项勾选去掉都没解决问题,最后通过将另一个正常启动的数据库的master库的mdf和ldf文件拷贝覆盖掉就正常了,这证实了master数据库坏了。数据库安装路径根据自己数据库的版本和系统定。

3.jquery的选择器语法

一、什么是选择器语法 就是对DOM对象进行定位的条件,比如根据ID定位,根据标签类型名…jquery中只有三种选择器 二、基本选择器 1、定位条件 可以根据ID编号,根据标签类型名,根据Class名(和CSS一样都是三种) 2、选择器的使用(第四种几乎不用) $("#idname") 代替document.getElementById(“idname”),根据ID编号定位对应的DOM对象。让DOM对象保存到一个数组中并返回。返回的这个数组就是jquery对象 $(".classname") 代替document.getElementsByClassName(“classname”)将使用了指定的样式选择器的dom对象保存到同一个数组中,并返回。返回的这个数组就是jquery对象 $(“标签名”) 代替document.getElementsByTagName(“标签名”)将所有指定的标签类型的DOM对象保存到同一个数组中,并返回。返回的这个数组就是jquery对象 $(" * ") 通配符,用来定位浏览器中所有的DOM对象保存到同一个数组中并返回 $(“条件1,条件2”) 组合选择器,只要DOM对象满足其中的一种条件,就会被定位并保存到数组中 3、jquery选择器实例 准备代码示例: /*CSS部分代码*/ div{ background: gray; width:200px; height:100px; } <!--html部分代码--> <body> <!--定义被选择对象--> <div id="id1" class = "class1"></div><br /> <div class="class1"></div><br /> <div></div><br /> <span>我是span标签</span><br /> <!--定义按钮--> <input type="button" id="btn1" value="选择id为id1的元素" onclick = "func1()"/> <input type="button" id="btn2" value="选择class为class1的元素" onclick="func2()" /> <input type="button" id="btn3" value="选择所有div元素" onclick="func3()"/> <input type="button" id="btn4" value="选择所有元素" onclick="func4()"/> <input type="button" id="

什么是死锁,怎样有效的避免死锁,银行家算法

死锁的四个必要条件: 互斥条件:一个资源只能被一个线程占用 请求与保持条件:一个线程因请求资源被阻塞时,对获得的资源保持不放 不剥夺条件:线程已经获得的资源,没有使用完,不能强行剥夺 循环等待条件:若干进程形成的首尾相连的等待状态 避免死锁就是要让这四个必要条件不成立: 1.避免线程在阻塞状态的时候继续占用资源,或者让线程请求下一个资源的时候释放当前资源 2.资源可以按照优先级有序分配,避免线程永久占据资源 3.允许高优先级的线程抢占资源,但是在优先级相同时是无效的 4.破坏循环等待条件,对资源的请求只允许升序。 5.实际应用中不能完全的避免死锁,因此有检测死锁和解除死锁的方法,使用的就是银行家算法的安全性检测 如果某个资源的分配导致后面的线程不能成功finish,则回收之前尝试分配的资源。 可以用一个map来实现死锁的检测: 线程A:获得1锁,申请2锁 线程B:获得2锁,申请3锁 线程C:获得3锁,申请1锁 当后面的线程请求前面的线程已经获得的锁的时候,可以检测到一条锁的闭环,出现死锁 银行家算法是怎么实现的 进程向系统申请的资源数,小于当前可用资源+其他线程占用资源的总和。所有进程能建立一个安全序列的时候,认为可以将资源分配给当前进程,否则该进程要等待。 int m,n;//m类资源,n个线程 int[] avaliable=new int[m]; //表示每类资源的可用数量 int[][] allocation=new int[n][m]; //表示已分配给每个进程的资源数量 int[][] Max=new int[n][m]; //表示每个进程最大需求 int[][] need=new int[n][m]; //表示每个进程仍需获得的资源数 Scanner sc=new Scanner(System.in); int[] request=new int[m]; outer: for(int i=0;i<n;i++){ //输入每个进程的request //先分配资源,然后进行安全检查,如果安全,则继续分配,如果不安全,则资源恢复,进程等待 for(int j=0;j<m;j++){ request[j]=sc.nextInt(); if(request[j]>Max[i][j])break outer; //说明出错 //尝试分配资源 available[i][j]-=request[j]; allocation[i][j]+=request[j]; need[i][j]-=request[j]; } //进行安全性检查 //获取finish和work初值 boolean[] finish=new boolean[n];//n个进程是否都能成功finish int[] work=new int[m]; for(int w=0;w<m;w++)work[w]=available[w]; int count=0; for(int u=0;u<n;u++){ for(int v=0;v<m;v++){ if(finish[u]==false && need[u][j]<=work[u][j]){count++;} } if(count==m){ for(int s=0;s<n;s++){ work[s]+=allocation[u][s];//假设所有分配出去的资源都能限时回收 } finish[u]=true; } } for(int c=0;c<n;c++){ if(!

23中设计模式的理解

一般做软件开发都需要知道23种设计模式 这面这张图概括的很好 创建型模式有5种: 单例模式,全局只实例化一个对象。spring里面自动注入的bean默认是单例的。同步容器比如concurrentHashMap的put等方法,使用的是unsafe类的一个对象,unsafe类就符合单例模式。 工厂方法模式:一个工厂提供返回类的实例的方法,使用这个工厂,可以自己决定要实例化哪个类。Executors类专门生产一些线程池。一个具体工厂生产一种产品。 抽象工厂模式:一个抽象工厂可以有很多的具体实现工厂,还要有一个生产工厂的类,生产出不同的具体工厂,具体工厂可以生产不同的实例。 建造者模式:创建一个builder构造类,一步步使用简单的对象来构造一个复杂的对象。比如生成一顿饭,构造一种食物添加到饭对象里,构造一种饮料添加到饭这个对象。 原型模式,通过复制(clone)原有的对象创建新的对象。 结构型模式有7种: 适配器模式:一个适配器,针对不同的参数调用不同的类的接口,比如一个多媒体播放器,有很多的具体实现类,如果传入vlc文件,就会调用vlc播放器,如果传入MP4,就会调用mp4播放器。 桥接模式:通过桥接接口,把抽象和实现分离开,桥接接口的不同实现类,调用同样的抽象方法,是独立变化的。 过滤器模式:创建一个接口,定义一种过滤方法,如果实现这种过滤方法,就可以对某个类的不同实例进行过滤。 组合模式:相似的一组对象,可以看作单个对象,对这个对象定义行为,单个对象和组合对象都具有这些行为。比如老板可以维护一个list,里面可以装干部,干部也可以维护一个list,里面可以装普通员工。不管是老板还是干部,他们都能使用维护list的方法。 装饰模式:用抽象接口和抽象类在原有的基础上添加细小的功能,不需要继承其他类。 外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。 代理对象:通过一个代理类实现对某个类的访问,而不是直接访问。 享元模式:减少创建对象的数量。属于一定参数,创建一个对象,如果针对该参数的对象已经存在了,就不会创建新的对象。 行为型模式有11种: 命令模式:一个接口,比如定义一个execute方法,实现这个接口的类,可以通过execute执行某种命令。 解释器模式:定义一些解释规则,使用解释器按照规则,解释执行语句。 访问者模式:操作方法可以随着访问者的不同而改变。在元素类型不变,但是需要经常定义新行为的场景。需要操作的类都需要接受访问者,一个访问者接口定义了针对不同操作对象的不同实现方法,一个实现类实现了这些方法。当需要添加新的行为的时候,只需要在访问者接口添加新的方法并实现即可,无需改变原有的类。 观察者模式:一个对象、多个观察者的情况,当对象的属性改变后,会通知观察者进行属性的更新。 模板模式:经常使用的,变化不大的一套步骤封装成一个模板,(宏操作、脚本录制等) 策略模式:提供了访问系统的多种方法,称为策略。由客户端在某种场景下,选择某种策略。比如说 ConcurrentHashMap提供了三种写入方式,add、offer、put,如果添加不成功,直接报异常可以使用add;如果需要判断添加是否成功的返回值,可以使用offer,如果添加不成功,要使线程阻塞的话,可以使用put方法。取决于使用者的选择。 状态模式:考虑什么样的状态对应什么样的行为。比如说,一个线程本来是阻塞的,后来跳出中断,由参数来判断该线程是cancel引起的中断还是由signal引起的中断,cancel引起的中断,需要线程自我中断,而signal引起的中断需要先去申请锁,申请不到锁再去中断。 备忘录模式:保存对象的历史状态。(git里面就会保存对象的历史状态,每一次提交的版本有哪些变化,都有记录) 中介者模式:一个中介类,用来实现对象之间的通信。 迭代器模式:比如说不用关心容器中对象的迭代方式,只需要关心对对象的操作方法就可以。比如Iterator以及简化的for循环。 责任链模式:击鼓传花的模式,多个对象都可以接收请求,形成一条链,如果没有对象处理这个请求,就会沿着链传送,直到有对象处理这种请求。对象组成一条链,发送者将请求发给链的第一个接收者,请求可以沿着链传递。比如异常处理的时候,可以自己try catch,也可以throw异常,让外层的程序捕获并处理,可以一直往外抛到最外层。

涡旋光及其部分干涉图样MATLAB模拟

基于MATLAB的LG涡旋光束图像及其部分干涉图样模拟 摘要:涡旋光作为近年来的前沿的领域被人们广泛研究。涡旋光具有螺旋波前结构,其中心暗斑很小。涡旋光在信息传输,光学操控等多个领域有较好的应用前景。涡旋光的传输和干涉特性则是研究的重点内容。本文将以典型的拉盖尔-高斯涡旋光为例实现涡旋光传播和干涉的部分MATLAB模拟。 目录 基于MATLAB的LG涡旋光束图像及其部分干涉图样模拟平面涡旋光的模拟理论公式代码实现及结果 涡旋光的传播模拟理论公式代码实现及结果 涡旋光和球面波干涉模拟理论公式代码实现及结果 涡旋光和平面波干涉模拟理论公式代码实现及结果 涡旋光的杨氏双缝干涉模拟理论公式代码实现及结果 涡旋光在马赫-曾德尔干涉仪中的离轴干涉理论公式代码实现及结果 平面涡旋光的模拟 理论公式 让激光束同过螺旋相位板产生LG涡旋光束,则在LG光束刚刚出螺旋相位板时,即在z=0处的横截面的光电场表达式为: 其中l是拓扑荷数,sigma为光斑展宽。 代码实现及结果 [X,Y]=meshgrid(-1:0.01:1,-1:0.01:1); [fai,rho]=cart2pol(X,Y); E=@(l,rho,fai)100*(rho./0.5).^l.*exp(-1*rho.^2/((0.5)^2)).*exp(1i*l.*fai);%l(小写L)是拓扑荷数 top_num_1=abs(E(5,rho,fai)); pcolor(X,Y,top_num_1) colorbar 涡旋光的传播模拟 理论公式 代码实现及结果 x=linspace(-3,3,200); y=linspace(-3,3,200); [X,Y]=meshgrid(x,y); [theta,R]=cart2pol(X,Y); r=0.5; k=5000; z1=0; z2=100; z3=500; z4=1500;%设置4个不同的传播距离 r_=@(z)sqrt(r^2+(4*z^2)/k^2*r^2); E=@(rho,z,theta,l)-1i^(l+1).*(r_(z)/r).^abs(l).*exp(1i.*k.*z+(1i.*2.*z.*rho.^2)./k.*r.^2.*r_(z).^2).*10.*(rho.^2./r_(z)).^abs(l).*exp(-rho.^2./r_(z).^2).*exp(1i.*abs(l).*theta); E1=E(R,z1,theta,2); E2=E(R,z2,theta,2); E3=E(R,z3,theta,2); E4=E(R,z4,theta,2);%分别算出4个传播距离对应的光强的分布 z=100 z=1000; 涡旋光和球面波干涉模拟 理论公式 球面波表达式: 干涉光强表达式: 代码实现及结果 x=linspace(-8,8,200); y=linspace(-8,8,200); [X,Y]=meshgrid(x,y); [theta,R]=cart2pol(X,Y); %涡旋光与球面波干涉 E=@(theta,L,x,y)2*5*(1+cos(L.*theta+10.*(x.^2+y.^2))); E1=E(theta,0.7,X,Y);%0.7为拓扑荷数,改变拓扑荷数会使图形中的明暗条纹分布发生极大的改变 pcolor(X,Y,E1) colorbar 拓扑荷数为0.7: 拓扑荷数为:1 涡旋光和平面波干涉模拟 理论公式 代码实现及结果 x=linspace(-8,8,200); y=linspace(-8,8,200); [X,Y]=meshgrid(x,y); [theta,R]=cart2pol(X,Y); %涡旋光与平面波干涉 F=@(theta,L,x)2*cos(L.*theta-10.*x.*0.5); F1=F(theta,5,X);%5为拓扑荷数,改变拓扑荷数会使图形中的明暗条纹分布发生极大的改变 pcolor(X,Y,F1) colorbar 涡旋光的杨氏双缝干涉模拟 理论公式 代码实现及结果 x=linspace(-8,8,200); y=linspace(-8,8,200); [X,Y]=meshgrid(x,y); [theta,R]=cart2pol(X,Y); a=0.

5G 网络架构(核心网)总结

1.网络组成与设计原则 1.1 组成 主要包括:接入网、承载网、核心网和空口 接入网是“窗口”,负责把数据收上来;承载网是“卡车”,负责把数据送来送去;核心网呢,就是“管理中枢”,负责管理这些数据,对数据进行分拣,然后告诉它,该去何方。 本文主要对5G核心网架构进行总结整理。 1.2 5G网络架构设计的原则 四个原则: 灵活:不同业务要求(超高可靠、超低时延)、以用户为中心的组网(个人、企业、M2M),更快的功能引入高效:更低的数据传输成本,易于扩展;简化状态、信令智能:资源自动分配和调整,网络自配置,自优化开放:网元突破软硬件耦合的限制;网络能力向第三方开放打造新的生态环境,创新盈利点 四维架构 (4D-Architecture) 转发分离化 (Seperated):基站的C/U分离、网关的控制转发分离网络虚拟化(Virtualized):小区逻辑虚拟化,网元功能虚拟化功能模块化(Modularized):网元功能原子/模块化,按需组合部署分布化(Distributed):支持分布式的网元部署,内容分布更靠近用户 2. 5G核心网架构 2.1 架构介绍 相比于2/3/4G,5G核心网架构的网络逻辑结构彻底改变了。2018年,我国提出了**SBA(Service Based Architecture,基于服务的架构)**的概念,将网络功能定义为多个相对独立可被灵活调用的服务模块。5G网络采用开放的服务化架构(SBA),NF(Network Function,网络功能)以服务的方式呈现,任何其他NF或者业务应用都可以通过标准规范的接口访问该NF提供的服务SBA架构下。 (1) 非漫游时的5G系统架构参考模型(基于业务,SAB): 采用的是基于业务接口(service-based)的表现形式,也叫SBA架构。图中的Nxxx就是基于业务的接口SBI(servec based interface),采用HTTP/TCP协议。 服务化架构是在控制面采用API能力开放形式 进行信令的传输,在传统的信令流程中,很多的消息在不同的流程中都会出现,将相同或相似的消息提取出来以API能力调用的形式封装起来,供其它网元进行访问,服务化架构将摒弃隧道建立的模式,倾向于采用HTTP协议完成信令交互。 (2)非漫游下5G系统的架构模式(基于参考点): 采用参考节点的表现形式,这是最基本的架构。 5G网络架构借鉴IT系统服务化和微服务化架构的成功经验,通过模块化实现网络功能间的解耦和整合,解耦后的网络功能可独立扩容、独立演进、按需部署;控制面所有NF之间的交互采用服务化接口,同一种服务可以被多种NF调用,降低NF之间接口定义的耦合度,最终实现整网功能的按需定制,灵活支持不同的业务场景和需求。 2.2 5G核心网网元介绍 (1)AMF(Access and Mobility Management Function,接入和移动管理功能)是接入和移动性管理功能实体,AMF可以类比于4G的MME。AMF的主要功能有: RAN信令接口(N2)的终结点,NAS(N1)信令(MM消息)的终结点;负责NAS消息的加密和完整性保护,负责注册、接入、移动性管理、鉴权、短信等功能;此外在和EPS网络交互时还负责Eps Bearer Id的分配。 (2)SMF(Session Management Function,会话管理功能)是会话管理功能实体。SMF的主要功能有: NAS消息的SM消息的终结点;会话(session)的建立、修改、释放;UE IP的分配管理;DHCP功能;ARP代理或IPv6邻居请求代理(Ethernet PDU场景下);为一个会话选择和控制UPF;计费数据的收集以及支持计费接口;决定一个会话的SSC模式;下行数据指示。 (3)UPF(User Plane Function,用户面管理功能)是用户面功能实体,其类似于4G下的GW(SGW+PGW)。最主要的功能是负责数据包的路由转发、Qos流映射。 用于RAT内/RAT间移动性的锚点(适用时)。外部 PDU 与数据网络互连的会话点。分组路由和转发(例如,支持上行链路分类器以将业务流路由到数据网络的实例,支持分支点以支持多宿主PDU会话)。数据包检查(例如,基于服务数据流模板的应用流程检测以及从SMF接收的可选PFD)。用户平面部分策略规则实施,例如门控,重定向,流量转向)。合法拦截(UP收集)。流量使用报告。用户平面的QoS处理,例如UL/DL速率实施,DL中的反射QoS标记。上行链路流量验证(SDF到QoS流量映射)。上行链路和下行链路中的传输级分组标记。下行数据包缓冲和下行数据通知触发。将一个或多个“结束标记”发送和转发到源NG-RAN节点。 注意:并非所有UPF功能都需要在网络切片的用户平面功能的实例中得到支持。 (4)PCF(Policy Control Function,策略控制功能)为策略控制功能实体。支持统一的策略框架并管理网络行为,向网络实体提供策略规则,访问统一数据仓库(UDR)的订阅信息,PCF只能访问和其相同PLMN的NDR。 (5)NEF(Network Exposure Function,网络业务呈现功能)是网络呈现功能实体。NEF的主要功能有: 3GPP的网元都是通过NEF将其能力呈现给其它网元的;NEF将相关信息存储到NDR中、也可以从NDR获取相关的信息,NEF只能访问和其相同PLMN的NDR;NEF提供相应的安全保障来保证外部应用到3gpp网络的安全;3GPP内部和外部相关信息的转换,例如AF-Service-Identifier和5G核心网内部的DNN、S-NSSAI等的转换,尤其是网络和用户敏感信息一定要对外部网元隐藏;NEF可以通过访问NDR获取到其它网元的相关信息,NEF只能访问和其相同PLMN的UDR。 (6)NRF(NF Repository Function,NF贮存功能)是网络贮存功能实体。NRF的主要功能有: 支持业务发现功能,也就是接收网元发过来的NF-Discovery-Request,然后提供发现的网元信息给请求方;维护可用网元实例的特征和其支持的业务能力;一个网元的特征参数主要有:网元实例ID、网元类型、PLMN、网络分片的相关ID(如S-NSSAI、NSI ID)、网元的IP或者域名、网元的能力信息、支持的业务能力名字等。 (7)UDM(Unified Data Manager,统一数据管理)的主要功能有:

Windows Server2019系统和WSUS搭建

文档:Windows Server2019系统和WSUS搭建.pdf 链接:http://note.youdao.com/noteshare?id=4eac7e9f4bf678f5aacdfd14a931f591 连接脚本提取: 链接:https://pan.baidu.com/s/1qcwoYvIkb3VcNmmBDVs78w 提取码:p7ny 复制这段内容后打开百度网盘手机App,操作更方便哦 链接:https://pan.baidu.com/s/1-iGc68WYZGUDVCs5klH08g 提取码:cx4o 复制这段内容后打开百度网盘手机App,操作更方便哦

org.apache.dubbo.common.bytecode.NoSuchMethodException xxx

在使用dubbo的时候,有时会出现如上错误: com.alibaba.dubbo.common.bytecode.NoSuchMethodException: cause: Method [xxxxxxxxx] not found. 解决方案: 1: 看这个dubbo的provider或consumer是不是没配置,或者配置错了 2:provider和consumer是不是重复配置了 (一般是这个错!!!)

盘点那些优秀的C/C++开源框架,程序员必备!

C++流行了那么多年,相应的框架和库函数非常多。 STL:C++标准模板库,是一个具有工业强度的,高效的C++程序库。该库提供一些非常实用的容器和算法。 Boost:C++准标准库,由C++标准委员会库工作组成员发起的,开源跨平台,作为标准库的后备,是C++标准化进程的开发引擎之一。 MFC:微软基础类库,以C++类的形式封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。 Qt:由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。也可用于开发非GUI程序,比如控制台工具和服务器。 ASL:由Adobe提供,经过同行的评审和可移植的C++源代码库。 Folly:由Facebook开发,为了实用性和效率而设计的开源C++库,类似 stl 和 boost 功能的底层库。 JUCE:包罗万象的C++类库,用于开发跨平台软件库。 Dlib:非常牛逼的C++人脸识别框架。 Loki:由Andrei编写的一个与《C++设计新思维》一书配套发行的C++代码库。它不仅把C++模板的功能发挥到了极致,而且把类似设计模式这样思想层面的东西通过库来提供。 Neu:C++11框架,编程语言集,用于创建人工智能应用程序的多用途软件系统。 Opus:一个完全开放的,免版税的,高度通用的音频编解码器。 bzip2:一个完全免费,免费专利和高质量的数据压缩。 Bolt :针对GPU进行优化的C++模板库。 Bcrypt :一个跨平台的文件加密工具,加密文件可以移植到所有可支持的操作系统和处理器中。 SQLite:一个完全嵌入式的,功能齐全的关系数据库,只有几百KB,可以正确包含到你的项目中。 Catch:一个很时尚的,C++原生的框架,只包含头文件,用于单元测试,测试驱动开发和行为驱动开发。 Cocos2d-x :一个跨平台框架,用于构建2D游戏,互动图书,演示和其他图形应用程序。 GTK+: 用于创建图形用户界面的跨平台工具包。 Cairo:支持多种输出设备的2D图形库。 OpenCV:开源计算机视觉库。 WebSocket++ :基于C++/Boost Aiso的websocket 客户端/服务器库。

JAVA高级面试题汇总及答案

JAVA高级面试题汇总及答案 1.hashaMap原理源码2.synchronize关键字1.6之后的优化,(偏向轻量级锁,重量级锁)3.双亲委派是什么4.类加载过程中可以动态改字节码吗?5.如何定位线上问题,CPU100%6.redis线程模型,分布式锁,除了redis还有哪些可以用来分布式锁7.了解springboot吗?springboot自动装配是如何实现的?8.RPC框架用过哪些?谈一下内部实现原理。9.设计一个线程安全的队列,有哪些点需要去考虑10.spring ioc原理,bean初始化过程,bean的生命周期11.lock源码,aqs源码12.服务器如何去内部扩容,内部原理知不知道13.jsonp原理是什么?14.ibatis如何防止注入,#$的区别15.gc roots哪些可以作为root16.redis槽个数,扩容之后如何迁移,redis事物是怎么实现的,watch命令干吗用的17.谈谈mysql索引,(从文件结构,数据结构,应用层面去谈)datatime 和timestamp区别,间隙锁解决了什么问题18.springcloud全家桶中有个zuul为什么还要再做一个springgateway19.maven依赖的范围,如何解决循环依赖的20.设计一个流(控)程组件21.activemq,rabbitmq,kafka等消息中间件,如何去选型,依据是什么?22.spring如何解决bean的循环依赖23.redis集群简单描述一下,(槽,crc16算法)24.redis存储一个比如学生信息,1000万条,如何预估存储容量25.mysql主从同步原理,mysql有那些锁,update时什么时候用到行锁,什么时候用到表锁26.mysql索引原理,住建索引和普通索引的区别,(估计还要说个联合索引)27.kafka集群锁谈一下,如果一个consumer挂了会有什么后果?28.java隐式锁,显示锁,有什么区别,内部原理,aqs过程画一下。29.cap理论,zk,redis分别符合哪些,zk如何做到一致性的30.http协议简单说下,如何解决跨域访问问题,如何解决xss问题,如果在代码中调用http如何鉴权31.数据库SQL索引,索引失效条件,联合索引使用,聚集索引32.常用集合包括但不限于hashmap concurrentHashMap LinkedHashMap TreeMap数据结构,并发集合CopyOnWriteArrayList ConcurrentSkipListMap这些集合的内部结构33.多线程相关的,线程池ThreadPoolExecutor 工作机制,ThreadLocal , synchronized ,ReentrantLock ,volatile 使用场景和内部实现机制34.动态代理的两种jdk cglib各自的实现方式和原理,自动生成的类结构是什么样的35.spring 容器启动顺序,扩展点BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor,BeanPostProcessor 初始化顺序和使用场景,spring aop ,mvc的核心servlet 加载顺序,IOC相互依赖如何解决,(BeanFactoryAware方式获取bean ,打破,或者无参构造),spring事务如何实现, 哪些情况可能会失效,spring的缓存框架36.常用的设计模式,工厂,代理,模板方法,策略,装饰,观察者37.jvm内存结构,垃圾回收算法,垃圾回收器(特别是CMS)的工作机制38.classLoader 双亲委派机制 提高部分39.总结做的项目的技术选型依据,设计思路40.RPC框架设计,数据传输,序列化协议,注册中心(服务发现),熔断,限流降级,负载均衡,幂等41.MQ(最好是能够知道kafaka,rocketMq中的一种)42.临时设计一种场景,比如整点抢红包,秒杀,综合使用上面的一些43.高并发这个应用各个层次的处理, 补:缓存的使用和防缓存穿透措施 高并发应用各个层次的应对措施,数据库层面的乐观锁,应用层面的44.深入理解IO原理,bio,nio,aio相关原理特性以及应用场景45.深入理解cas原理,对cas应用场景有深刻理解46.深入理解java.concurrent包中各个常用类,对自旋锁,重入锁,读写锁的深入理解对sync相关的偏向锁,轻量级锁和锁升级相关场景深入理解47.深入理解volatile关键字以及缓存一致性协议,对使用场景有深入理解48.深入理解current包中,阻塞和非阻塞队列熟悉应用场景和特性49.熟悉线程池相关类,对线程池使用和拒绝策略比较熟悉50.熟悉java集合相关类对jdk1.8集合升级特性有一定了解51.深入理解,引用计数,标记清除,编辑整理相关GC算法特性以及应用场景52.深入理解jvm classloader类加载机制52.深入理解java反射机制和性能调优53.深入理解jvm栈与堆的结构,以及线程出栈入栈的相关原理,对jvm中逃逸分析、栈上替换、方法内联有深入理解54.深入理解jit动态编译原理,对解释执行、编译执行有深刻理解55.熟悉jvm调优,分代收集等56.深入理解tomcat启动原理以及相关的调优,对tomcat类加载机制有深入理解57.深入理解rpc动态代理+zk+netty相关中间件原理和应用场景,对消息队列acticvemq、rabbitmq、kafka有一定的了解58.熟悉redis使用,对高并发下的秒杀,分布式锁,防重等业务场景有深入理解,对缓存一致性,缓存击穿,缓存雪崩有深入理解59.熟悉nginux相关限流算法、规则、负载均衡原理及应用场景、对流行降级策略降级框架有一定的了解60.熟悉mybatis持久框架61.熟悉mycat适用、mysql主从、读写分离有深入理解。对mycat+mysql的分库分表有深入理解62.熟悉zookeep特性,以及在整个架构中的应用场景。对zk脑列、故障修复有一定的了解 1.hashaMap原理源码 2.synchronize关键字1.6之后的优化,(偏向轻量级锁,重量级锁) synchronized是Java提供的一个并发控制的关键字,作用于对象上。主要有两种用法,分别是同步方法(访问对象和clss对象)和同步代码块(需要加入对象),保证了代码的原子性和可见性以及有序性,但是不会处理重排序以及代码优化的过程,但是在一个线程中执行肯定是有序的,因此是有序的。 原理:借用对象markword中的标记以及monitor监控器生成monitorEnter以及monitorExit指令以及对应的计数器。 在jdk1.6之前,synchronized是非常重量级的,因为它会无时无刻进行锁住对象,而不考虑到程序实际的竞争情况,大多数程序在都是进行交替执行,也就是说不存在资源的竞争,如果没有竞争,但是加锁,加锁和解锁是非常耗费性能的,(重量级)因为线程之间的切换以及线程从内核态到用户态的时间是耗费性能的。 在jdk1.6之后,sun公司对synchronized进行了大幅度的优化,现在采用偏向锁+(轻量级锁+cas)+重量级,之间通过锁碰撞进行切换。 3.双亲委派是什么 什么是类加载器? 类加载器是jre的一部分,负责动态将类添加到Java虚拟机。 类加载分类 1、启动类加载器 bootstrap classloader :加载jre/lib/rt.jar 2、扩展类加载器 extension classloader :加载jre/lib/ext/*.jar 3、应用程序类加载器 application classloader:加载classpath上指定的类库 双亲委派机制 双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。每个类加载器都是如此,只有在父类加载器在自己的搜索范围内找不到指定类时,子类加载器才会尝试自己去加载。 双亲委派模型工作工程: 1.当Application ClassLoader 收到一个类加载请求时,他首先不会自己去尝试加载这个类,而是将这个请求委派给父类加载器Extension ClassLoader去完成。 2.当Extension ClassLoader收到一个类加载请求时,他首先也不会自己去尝试加载这个类,而是将请求委派给父类加载器Bootstrap ClassLoader去完成。 3.如果Bootstrap ClassLoader加载失败(在<JAVA_HOME>\lib中未找到所需类),就会让Extension ClassLoader尝试加载。 4.如果Extension ClassLoader也加载失败,就会使用Application ClassLoader加载。 5.如果Application ClassLoader也加载失败,就会使用自定义加载器去尝试加载。 6.如果均加载失败,就会抛出ClassNotFoundException异常。 4.类加载过程中可以动态改字节码吗? 是可以的,在动态代理中CGLIB动态代理采用的就是ASM字节码处理框架,动态修改字节码。

【python】之tkinter模块之多组实验

Tkinter基本方法参考我之前文档tkinter基本语法部分 实验一: 按钮实验: 实验代码: from tkinter import* def show(event): s=event.keysym lb.config(text=s) root=Tk() root.title("按键实验") root.geometry('400x400') lb=Label(root,text='请按键',font=('黑体',48)) lb.bind('<Key>',show) #将标签绑定键盘 lb.focus_set() lb.pack() root.mainloop() 将标签绑定键盘任意键,触发事件并获取焦点,并将按键字显示在标签上 实验二: 时间显示 代码: import tkinter import time def gettime(): day = time.strftime("%Y:%m:%d %A ") timestr = time.strftime("%H:%M:%S") op.configure(text = day) lb.configure(text=timestr) root.after(1000,gettime) root = tkinter.Tk() root.title('时间显示') lb = tkinter.Label(root,text='',fg='blue',font=("",80)) op = tkinter.Label(root,text='',fg='Yellow',font=("微软雅黑",80)) op.pack() lb.pack() gettime() root.mainloop() 使用窗体Tk做一个基本的时钟,用于显示当前的时间,所以要用到窗体的tkinter,以及时间日期的time 实验三: 光标位置实验: 实验代码 from tkinter import * def show(event) : s = '光标位于x=%s,y=%s'%(str(event.

PAT-A1103 Integer Factorization

The K−P factorization of a positive integer N is to write N as the sum of the P-th power of K positive integers. You are supposed to write a program to find the K−P factorization of N for any positive integers N, K and P. Input Specification: Each input file contains one test case which gives in a line the three positive integers N (≤400), K (≤N) and P (1<P≤7).

5G 应用及应用场景总结

1.概述 5G技术演进方式与前几代移动通信截然不同。首先,2G/3G/4G时代是技术领先应用,先有移动通信技术不断发展,待成熟之后再推广到不同应用, 其应用主要侧重于“改变生活”。5G却恰恰相反,是应用牵引技术。先要确定应用的需求和场景,包括 “生活”和“社会”两方面内容,然后再去探索发现相对应的具体技术,例如:5G 新空口(New Radio, NR)设计标准就是来源于全新应用场景,其中包括: 新波形、新调制方式、新帧结构、新多址技术、新编码 技术和大规模多天线技术等一系列新无线空口技 术。未来移动通信技术演进(6G及以后)也会按照这种“应用引领、技术跟随”的方式出现。 5G网络是广带化、泛在化、智能化、融合化、绿色节能的网络。根据5G白皮书中的技术愿景,5G网络将满足人们超高流量密度、超高连接数密度、超高移动性的需求,为用户提供高清视频、虚拟现实、增强现实、云桌面、在线游戏等极致业务体验。5G将渗透到物联网领域,与工业设施、医疗仪器、交通工具等深度融合,全面实现“万物互联”。 2. 5G性能指标(5G之花) 面向2020年及未来,5G将解决多样化应用场景下差异化性能指标带来的挑战,不同应用场景面临的性能挑战有所不同,用户体验速率、流量密度、时延、能效和连接数都可能成为不同场景的挑战性指标。 5G在速率、容量、覆盖、时延、安全、用户体验等方面的飞跃,将为人类开启全新的发展时代。而我国为迎接5G的到来,提出“5G之花”,如下图所示,性能和效率需求共同定义了5G的关键能力,犹如一株绽放的鲜花。红花与绿叶相辅相成,其中花瓣代表了5G的六大性能指标,体现了5G满足未来多样化业务与场景需求的能力,而花瓣顶点代表了相应指标的最大值;绿叶则代表三个效率指标,是实现5G可持续发展的基本保障。 其中包含的5G性能指标如下: (1)移动性移动性历代移动通信系统重要的性能指标,指在满足一定系统性能的前提下,通信双方最大相对移动速度。5G移动通信系统需要支持飞机、高速公路、城市地铁等超高速移动场景,同时也需要支持数据采集、工业控制低速移动或非移动场景。因此,5G移动通信系统的设计需要支持更广泛的移动性。 (2)时延时延采用OTT或RTT来衡量,前者是指发送端到接收端接收数据之间的间隔,后者是指发送端到发送端数据从发送到确认的时间间隔。在4G时代,网络架构扁平化设计大大提升了系统时延性能。在5G时代,车辆通信、工业控制、增强现实等业务应用场景,对时延提出了更高的要求,最低空口时延要求达到了1ms。在网络架构设计中,时延与网络拓扑结构、网络负荷、业务模型、传输资源等因素密切相关。 (3)用户感知速率5G时代将构建以用户为中心的移动生态信息系统,首次将用户感知速率作为网络性能指标。用户感知速率是指单位时间内用户获得MAC层用户面数据传送量。实际网络应用中,用户感知速率受到众多因素的影响,包括网络覆盖环境、网络负荷、用户规模和分布范围、用户位置、业务应用等因素,一般采用期望平均值和统计方法进行评估分析。 (4)峰值速率峰值速率是指用户可以获得的最大业务速率,相比4G网络,5G移动通信系统将进一步提升峰值速率,可以达到数十Gbps。 (5)连接数密度在5G时代存在大量物联网应用需求,网络要求具备超千亿设备连接能力。连接数密度是指单位面积内可以支持的在线设备总和,是衡量5G移动网络对海量规模终端设备的支持能力的重要指标,一般不低于十万/平方公里。 (6)流量密度流量密度是单位面积内的总流量数,是衡量移动网络在一定区域范围内数据传输能力。在5G时代需要支持一定局部区域的超高数据传输,网络架构应该支持每平方公里能提供数十Tbps的流量。在实际网络中,流量密度与多个因素相关,包括网络拓扑结构、用户分布、业务模型等因素。 (7)能源效率能源效率是指每消耗单位能量可以传送的数据量。在移动通信系统中,能源消耗主要指基站和移动终端的发送功率,以及整个移动通信系统设备所消耗的功率。在5G移动通信系统架构设计中,为了降低功率消耗,采取了一系列新型接入技术,如低功率基站、D2D技术、流量均衡技术、移动中继等。 3. ITU三大应用场景 国际电信联盟 ITU 召开的 ITU-RWP5D 第 22 次会议上确定了未来的5G具有以下三大主要的应用场景: 1)增强型移动宽带(enhanced mobile broad band, eMBB) 2)大规模机器类型通信(massive machine type communications,mMTC) 3)超可靠和低延迟通信(ultra-reliable and low latency communications,URLLC) 具体包括:Gbps移动宽带数据接入、智慧家庭、智能建筑、语音通话、智慧城市、三维立体视频、超高清晰度视频、云工作、云娱乐、增强现实、行业自动化、紧急任务应用、自动驾驶汽车等。 3.1 增强型移动宽带eMBB 增强型移动宽带是指在现有移动宽带业务场景的基础上,对用户体验等性能的进一步提升,以人为中心的应用情景,集中表现为超高的传输数据速率,广覆盖下的移动性保证。主要包括车站、体育场等超密集区域的巨大数据流量的热点高容量场景。该类场景下性能需求包括1 Gbit/s用户体验速率、数十Gbit/s峰值速率和数十Tbit/(s·平方公里)的流量密度。此外,eMBB还包括需要保证用户在高移动性情况下的业务连续性的连续广域覆盖场景,挑战在于随时随地为用户提供100 Mbit/s以上的用户体验速率,保证业务的连续性与网络的基本服务能力。5G在这方面带来的最直观的感受就是网速的大幅提升,即便是观看4K高清视频,峰值速率也能够达到10Gbps。增强型移动宽带eMBB场景应用有增强现实(AR)、虚拟现实(VR),以及4K、8K超高清视频等多种高速率应用。 3.2 大规模机器类型通信mMTC 海量终端连接场景则主要针对诸如MTC(Machine Type Communication)设备以及传感器等设备大量连接和业务特征差异化的场景。5G低功耗、大连接和低时延高可靠场景主要面向物联网业务,作为5G新拓展出的场景,重点解决传统移动通信无法很好支持地物联网及垂直行业应用的问题。主要应用于机器间通信,以传感器为主,包括智慧城市、物流管理、智能农业、远程监测、旅游管理、智慧家庭、智慧社区、共享设备、穿戴设备、环境监测、森林防火等以传感和数据采集为目标的应用场景,满足接入设备数量巨大且功耗极低的需求,预期达到100万/平方公里的连接数密度的性能指标,具有小数据包、低功耗、海量连接等特点。 3.3 超可靠和低延迟通信URLLC 超可靠和低延迟通信URLLC特点是高可靠、低时延、极高的可用性。在此情景下,连接时延要达到1ms级别,而且要支持高速移动(500km/h)情况下的高可靠性(99.999%)连接。URLLC在无人驾驶业务方面拥有很大潜力。主要面向对时延和可靠性具有极高指标需求的应用,例如车联网、工业控制等低时延高可靠场景,需要网络为用户提供毫秒级的端到端时延和接近100%的业务可靠性保证,这与4G网络百毫秒级的端到端时延和业务中断时间相距甚远,要求5G网络针对更高的可靠性与更低的时延要求提出关键的使能技术。此外,这对于安全防护行业也十分重要。 高可靠和低时延通信场景应用主要有三个类别:第一种是能够节省时间、提高效率、节约资源;第二种有可能是能够让人们远离危险,安全运营;第三种有可能是让生活更加丰富多彩。它包括以下各类场景及应用:人工智能、自动驾驶、交通控制、远程施工、远程培训、远程医疗、同声传译、工业自动化等,均有低时延要求。 4. IMT-2020四个主要技术场景 4.1 四大技术场景介绍 后来,IMT-2020(5G)从移动互联网和物联网主要应用场景、业务需求及挑战出发,将5G主要应用场景纳出为:连续广域覆盖、热点高容量、低功耗大连接和低时延高可靠四个主要技术场景,与ITU的三大应用场景基本一致。 (1)连续广域覆盖场景,是移动通信最基本的覆盖方式,以保证用户的移动性和业务连续性为目标,为用户提供无缝的高速业务体验。该场景的主要挑战在于随时随地(包括小区边缘、高速移动等恶劣环境)为用户提供100Mbps以上的用户体验速率。 (2)热点高容量场景,主要面向局部热点区域,为用户提供极高的数据传输速率,满足网络极高的流量密度需求。1Gbps用户体验速率、数10Gbps峰值速率和数10Tbps/km2的流量密度需求是该场景面临的主要挑战。 (3)低功耗大连接场景,主要面向智慧城市、环境监测、智能农业、森林防火等以传感和数据采集为目标的应用场景,具有小数据包、低功耗、海量连接等特点。这类终端分布范围广、数量众多,不仅要求网络具备超千亿连接的支持能力,满足100万/km2连接数密度指标要求,而且还要保证终端的超低功耗和超低成本。

A Gameof Thrones(66)

37.BRAN(2) The direwolves stopped, turned their heads. Grey Wind loped back to Robb. Summer stayed where he was, his eyes on Bran and the man beside him. He growled. His muzzle was wet and red, but his eyes burned. Osha used the butt end of her spear to lever herself back to her feet. Blood leaked from a wound on the upper arm where Robb had cut her. Bran could see sweat trickling down the big man’s face.

JDK、JRE、JVM的联系与区别

1.JDK、JRE、JVM的关系 a.JDK Java开发的核心(java development kit) JDK是Java开发工具包,是整个Java开发的核心,包括了Java运行环境JRE、Java工具(javac.exe,java.exe,jar.exe 等)和Java基础类库。 b.JRE Java的运行环境( java runtime environment) JRE是Java的运行环境,包含JVM标准实现及Java核心类库。并不是一个开发环境,所以没有包含任何开发工具;↑↑↑ 所有的Java 程序都要在JRE下才能运行。普通用户只需要运行已开发好的java程序,安装JRE即可。 c.JVM Java跨平台核心(java virtual machine) JVM是Java虚拟机,是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。 Java语言有一个非常重要的特点(跨平台性↑↑↑)JVM是关键,一般改机语言如果要在不同的平台上运行,需要编译成不同的系统目标代码, 而Java语言(一次编译,处处运行),Java语言比较特殊,Java代码(.java) → 编译字节码(.class ),当然.class字节码也不是可执行的, 必须使用 Java 解释器来解释执行。Java语言的特殊性就是(Java 语言既不是纯粹的编译型语言,也不是纯粹的解释性语言。) Java 程序的执行过程必须经过先编译、后解释两个步骤,如下图所示: 1.由 Java 编译器对 Java 源程序文件( *.java )进行编译,生成与平台无关的字节码文件( *.class ); 2.由 JVM 对字节码文件( *.class )进行解释执行。JVM 是可运行 Java 字节码文件的虚拟计算机。 Java 编译器只需要面向虚拟机,生成虚拟机能理解的代码.class,然后由虚拟机来解释执行。在一些虚拟机的实现中,还会将虚拟机代码转换成特定系统的机器码执行, 从而实现跨平台。相同的字节码程序需要在不同的平台上运行,这几乎是“不可能的”,只有通过中间的转换器材可以实现,JVM 就是这个转换器 ; 2.JDK、JRE、JVM的联系与区别(JDK>JRE>JVM) 联系: 1.JVM不能单独搞定class的执行,解释class的时候JVM需要调用解释所需要的类库lib。 2.在JDK下面的的jre目录里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库, 而jvm和lib和起来就称为jre。JVM+lib=JRE。也就是(jre→bin+jre→lib)==JRE总体来说就是(如下图) 我们利用JDK(调用JAVA API)开发了属于我们自己的Java程序后,通过JDK中的编译程序(javac)将我们的文本java(.java)文件编译成Java字节码(.class), 在JRE上运行这些Java字节码,JVM解析这些字节码,映射到CPU指令集或OS的系统调用。 区别: JDK和JRE区别:在bin文件夹下会发现,JDK有javac.exe而JRE里面没有,javac指令是用来将java文件编译成class文件的,这是开发者需要的,而用户 (只需要运行的人)是不需要的。JDK还有jar.exe, javadoc.exe等等用于开发的可执行指令文件。这也证实了一个是开发环境(JDK),一个是运行环境(JRE);JRE和JVM区别:JVM并不代表就可以执行class了,JVM执行.class还需要JRE下的lib类库的支持,尤其是rt.jar。

Batch Normalization(BN)超详细解析

单层视角 神经网络可以看成是上图形式,对于中间的某一层,其前面的层可以看成是对输入的处理,后面的层可以看成是损失函数。一次反向传播过程会同时更新所有层的权重W1,W2,…,WL,前面层权重的更新会改变当前层输入的分布,而跟据反向传播的计算方式,我们知道,对Wk的更新是在假定其输入不变的情况下进行的。如果假定第k层的输入节点只有2个,对第k层的某个输出节点而言,相当于一个线性模型y=w1x1+w2x2+b,如下图所示, 假定当前输入x1和x2的分布如图中圆点所示,本次更新的方向是将直线H1更新成H2,本以为切分得不错,但是当前面层的权重更新完毕,当前层输入的分布换成了另外一番样子,直线相对输入分布的位置可能变成了H3,下一次更新又要根据新的分布重新调整。直线调整了位置,输入分布又在发生变化,直线再调整位置,就像是直线和分布之间的“追逐游戏”。对于浅层模型,比如SVM,输入特征的分布是固定的,即使拆分成不同的batch,每个batch的统计特性也是相近的,因此只需调整直线位置来适应输入分布,显然要容易得多。而深层模型,每层输入的分布和权重在同时变化,训练相对困难。 多层视角 上面是从网络中单拿出一层分析,下面看一下多层的情况。在反向传播过程中,每层权重的更新是在假定其他权重不变的情况下,向损失函数降低的方向调整自己。问题在于,在一次反向传播过程中,所有的权重会同时更新,导致层间配合“缺乏默契”,每层都在进行上节所说的“追逐游戏”,而且层数越多,相互配合越困难,文中把这个现象称之为 Internal Covariate Shift,示意图如下。为了避免过于震荡,学习率不得不设置得足够小,足够小就意味着学习缓慢。 为此,希望对每层输入的分布有所控制,于是就有了Batch Normalization,其出发点是对每层的输入做Normalization,只有一个数据是谈不上Normalization的,所以是对一个batch的数据进行Normalization。 Batch Normalization原理 Batch Normalization,简称BatchNorm或BN,翻译为“批归一化”,是神经网络中一种特殊的层,如今已是各种流行网络的标配。在原paper中,BN被建议插入在(每个)ReLU激活层前面,如下所示, 如果batch size为m,则在前向传播过程中,网络中每个节点都有m个输出,所谓的Batch Normalization,就是对该层每个节点的这m个输出进行归一化再输出. 我们在图像预处理过程中通常会对图像进行标准化处理,这样能够加速网络的收敛,如下图所示,对于Conv1来说输入的就是满足某一分布的特征矩阵,但对于Conv2而言输入的feature map就不一定满足某一分布规律了**(注意这里所说满足某一分布规律并不是指某一个feature map的数据要满足分布规律,理论上是指整个训练样本集所对应feature map的数据要满足分布规律)**。而我们Batch Normalization的目的就是使我们的feature map满足均值为0,方差为1的分布规律。 下面是从原论文中截取的原话,注意标黄的部分: “对于一个拥有d维的输入x,我们将对它的每一个维度进行标准化处理。” 假设我们输入的x是RGB三通道的彩色图像,那么这里的d就是输入图像的channels即d=3,,其中就代表我们的R通道所对应的特征矩阵,依此类推。标准化处理也就是分别对我们的R通道,G通道,B通道进行处理。上面的公式不用看,原文提供了更加详细的计算公式: 其操作可以分成2步, Standardization:首先对m个x进行 Standardization,得到 zero mean unit variance的分布x^。scale and shift:然后再对x^进行scale and shift,缩放并平移到新的分布y,具有新的均值β方差γ。 假设BN层有d个输入节点,则x可构成d×m大小的矩阵X,BN层相当于通过行操作将其映射为另一个d×m大小的矩阵Y,如下所示, 将2个过程写在一个公式里如下 其中,x(b)i表示输入当前batch的b-th样本时该层i-th输入节点的值,xi为[x(1)i,x(2)i,…,x(m)i]构成的行向量,长度为batch size m,μ和σ为该行的均值和标准差,ϵ为防止除零引入的极小量(可忽略),γ和β为该行的scale和shift参数,可知 μ和σ为当前行的统计量,不可学习。γ和β为待学习的scale和shift参数,用于控制yi的方差和均值BN层中,xi和xj之间不存在信息交流(i≠j) 可见,无论xi原本的均值和方差是多少,通过BatchNorm后其均值和方差分别变为待学习的β和γ。 Batch Normalization的反向传播 对于目前的神经网络计算框架,一个层要想加入到网络中,要保证其是可微的,即可以求梯度。BatchNorm的梯度该如何求取? 反向传播求梯度只需抓住一个关键点,如果一个变量对另一个变量有影响,那么他们之间就存在偏导数,找到直接相关的变量,再配合链式法则,公式就很容易写出了。 根据反向传播的顺序,首先求取损失ℓ对BN层输出yi的偏导∂ℓ / ∂yi,然后是对可学习参数的偏导∂ℓ / ∂γ和∂ℓ / ∂β,用于对参数进行更新,想继续回传的话还需要求对输入 x偏导,于是引出对变量μ、σ2和x^的偏导,根据链式法则再求这些变量对x的偏导。 Batch Normalization的预测阶段 在预测阶段,所有参数的取值是固定的,对BN层而言,意味着μ、σ、γ、β都是固定值。 γ和β比较好理解,随着训练结束,两者最终收敛,预测阶段使用训练结束时的值即可。 对于μ和σ,在训练阶段,它们为当前mini batch的统计量,随着输入batch的不同,μ和σ一直在变化。在预测阶段,输入数据可能只有1条,该使用哪个μ和σ,或者说,每个BN层的μ和σ该如何取值?可以采用训练收敛最后几批mini batch的 μ和σ的期望,作为预测阶段的μ和σ,如下所示, 因为Standardization和scale and shift均为线性变换,在预测阶段所有参数均固定的情况下,参数可以合并成y=kx+b的形式,如上图中行号11所示。 Batch Normalization的作用 使用Batch Normalization,可以获得如下好处,

数据结构与算法--线索化二叉树

数据结构与算法--线索化二叉树 前言1. 线索化二叉树初探2. 线索化二叉树实现 前言 前一篇简单的对二叉树进行初探,简单的了解了一下二叉树的一些概念,和二叉树的 顺序存储 和 链式存储 以及二叉树的一些简单操作,和二叉树的几种遍历方式。这一篇,我们在对二叉树进行了解,假如这个二叉树有很多的叶子节点,那么叶子节点的左孩子和右孩子的指针空间是否会浪费呢? 1. 线索化二叉树初探 如开篇提到的,假如,一个二叉树有很多的叶子节点,如下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o6VpMNw2-1588153397713)(https://user-gold-cdn.xitu.io/2020/4/29/171c512d6d915000?w=1038&h=375&f=png&s=43818)] 那么,上图中,标记 '^'的左孩子指针域和右孩子指针域中则为NULL,那么对于这些空间来说就是空间浪费。 那么,当节点的左孩子的指针域为空的时候,可以将这个指向遍历(以中序遍历为例)时的前一个节点,称之为前驱; 当节点的右孩子的指针域为空的时候,可以将这个指向遍历(以中序遍历为例)时的后一个节点,称之为后继,如下图(以中序遍历为例): [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5RqP6vVK-1588153397731)(https://user-gold-cdn.xitu.io/2020/4/29/171c51c37ef17ef4?w=1059&h=349&f=png&s=54901)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L7NJMRfO-1588153397741)(https://user-gold-cdn.xitu.io/2020/4/29/171c52b460797d51?w=1069&h=350&f=png&s=63529)] 我们称这种二叉树为线索化二叉树, 优点: 节省空间,遍历的时候查找方便 那么怎么区分节点的左孩子指针指向的是左子树还是前驱呢? 那么我们可以对二叉树节点的结构进行优化,增加两个标识,来指示具体指向的是左右子树还是前驱后继,如下示意图: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rvo1eRxL-1588153397751)(https://user-gold-cdn.xitu.io/2020/4/29/171c52b7f414fb7f?w=840&h=88&f=png&s=8092)] // Link==0表示指向左右孩子指针 // Thread==1表示指向前驱或后继的线索 typedef enum {Link, Thread} PointerTag; // 线索二叉树节点 typedef struct BiThrNode{ //数据 CElemType data; //左右孩子指针 struct BiThrNode *lchild,*rchild; //左右标记 PointerTag LTag; PointerTag RTag; }BiThrNode,*BiThrTree; 2. 线索化二叉树实现 下面以中序遍历为例,线索二叉树的线索化和遍历 线索二叉树的线索化 首先,声明定义一些变量,并定义一个方法, #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSW 0 #define MAXSIZE 100 // 存储空间初始分配量 typedef int Status; // 函数类型 typedef char CElemType; CElemType Nill = '#'; // 字符型以空格标识空 #pragma mark -二叉树的构造 int indexs = 1; typedef char String[24]; /* 0号单元存放串的长度 */ String str; // 字符传构造字符数组 Status StrAssign(String T, char *chars) { int i; if (strlen(chars) > MAXSIZE) { return ERROR; }else { T[0] = strlen(chars); for (i = 1; i <= T[0]; i++) { T[i] = *(chars+i-1); } return OK; } } // 打印值 Status visit(CElemType e) { printf("

ResNet——CNN经典网络模型详解(pytorch实现)

1、前言 ResNet(Residual Neural Network)由微软研究院的Kaiming He等四名华人提出,通过使用ResNet Unit成功训练出了152层的神经网络,并在ILSVRC2015比赛中取得冠军,在top5上的错误率为3.57%,同时参数量比VGGNet低,效果非常突出。ResNet的结构可以极快的加速神经网络的训练,模型的准确率也有比较大的提升。同时ResNet的推广性非常好,甚至可以直接用到InceptionNet网络中。 下图是ResNet34层模型的结构简图。 2、ResNet详解 在ResNet网络中有如下几个亮点: 提出residual结构(残差结构),并搭建超深的网络结构(突破1000层)使用Batch Normalization加速训练(丢弃dropout) 在ResNet网络提出之前,传统的卷积神经网络都是通过将一系列卷积层与下采样层进行堆叠得到的。但是当堆叠到一定网络深度时,就会出现两个问题。 梯度消失或梯度爆炸。退化问题(degradation problem)。 在ResNet论文中说通过数据的预处理以及在网络中使用BN(Batch Normalization)层能够解决梯度消失或者梯度爆炸问题。如果不了解BN层可参考这个链接 。但是对于退化问题(随着网络层数的加深,效果还会变差,如下图所示)并没有很好的解决办法。 所以ResNet论文提出了residual结构(残差结构)来减轻退化问题。下图是使用residual结构的卷积网络,可以看到随着网络的不断加深,效果并没有变差,反而变的更好了。 残差结构(residual) 残差指的是什么? 其中ResNet提出了两种mapping:一种是identity mapping,指的就是下图中”弯弯的曲线”,另一种residual mapping,指的就是除了”弯弯的曲线“那部分,所以最后的输出是 y=F(x)+x identity mapping 顾名思义,就是指本身,也就是公式中的x,而residual mapping指的是“差”,也就是y−x,所以残差指的就是F(x)部分。 下图是论文中给出的两种残差结构。左边的残差结构是针对层数较少网络,例如ResNet18层和ResNet34层网络。右边是针对网络层数较多的网络,例如ResNet101,ResNet152等。为什么深层网络要使用右侧的残差结构呢。因为,右侧的残差结构能够减少网络参数与运算量。同样输入一个channel为256的特征矩阵,如果使用左侧的残差结构需要大约1170648个参数,但如果使用右侧的残差结构只需要69632个参数。明显搭建深层网络时,使用右侧的残差结构更合适。 我们先对左侧的残差结构(针对ResNet18/34)进行一个分析。 如下图所示,该残差结构的主分支是由两层3x3的卷积层组成,而残差结构右侧的连接线是shortcut分支也称捷径分支(注意为了让主分支上的输出矩阵能够与我们捷径分支上的输出矩阵进行相加,必须保证这两个输出特征矩阵有相同的shape)。如果刚刚仔细观察了ResNet34网络结构图的同学,应该能够发现图中会有一些虚线的残差结构。在原论文中作者只是简单说了这些虚线残差结构有降维的作用,并在捷径分支上通过1x1的卷积核进行降维处理。而下图右侧给出了详细的虚线残差结构,注意下每个卷积层的步距stride,以及捷径分支上的卷积核的个数(与主分支上的卷积核个数相同)。 接着我们再来分析下针对ResNet50/101/152的残差结构,如下图所示。在该残差结构当中,主分支使用了三个卷积层,第一个是1x1的卷积层用来压缩channel维度,第二个是3x3的卷积层,第三个是1x1的卷积层用来还原channel维度(注意主分支上第一层卷积层和第二次卷积层所使用的卷积核个数是相同的,第三次是第一层的4倍)。该残差结构所对应的虚线残差结构如下图右侧所示,同样在捷径分支上有一层1x1的卷积层,它的卷积核个数与主分支上的第三层卷积层卷积核个数相同,注意每个卷积层的步距。 为什么残差学习相对更容易,从直观上看残差学习需要学习的内容少,因为残差一般会比较小,学习难度小点。不过我们可以从数学的角度来分析这个问题,首先残差单元可以表示为: 其中 XL和 XL+1分别表示的是第L个残差单元的输入和输出,注意每个残差单元一般包含多层结构。 F是残差函数,表示学习到的残差,而 h(XL)=XL表示恒等映射, F是ReLU激活函数。基于上式,我们求得从浅层 l到深层 L 的学习特征为: 式子的第一个因子表示的损失函数到达L的梯度,小括号中的1表明短路机制可以无损地传播梯度,而另外一项残差梯度则需要经过带有weights的层,梯度不是直接传递过来的。残差梯度不会那么巧全为-1,而且就算其比较小,有1的存在也不会导致梯度消失。所以残差学习会更容易。要注意上面的推导并不是严格的证明。 下面这幅图是原论文给出的不同深度的ResNet网络结构配置,注意表中的残差结构给出了主分支上卷积核的大小与卷积核个数,表中的xN表示将该残差结构重复N次。那到底哪些残差结构是虚线残差结构呢。 对于我们ResNet18/34/50/101/152,表中conv3_x, conv4_x, conv5_x所对应的一系列残差结构的第一层残差结构都是虚线残差结构。因为这一系列残差结构的第一层都有调整输入特征矩阵shape的使命(将特征矩阵的高和宽缩减为原来的一半,将深度channel调整成下一层残差结构所需要的channel)。为了方便理解,下面给出了ResNet34的网络结构图,图中简单标注了一些信息。 对于我们ResNet50/101/152,其实在conv2_x所对应的一系列残差结构的第一层也是虚线残差结构。因为它需要调整输入特征矩阵的channel,根据表格可知通过3x3的max pool之后输出的特征矩阵shape应该是[56, 56, 64],但我们conv2_x所对应的一系列残差结构中的实线残差结构它们期望的输入特征矩阵shape是[56, 56, 256](因为这样才能保证输入输出特征矩阵shape相同,才能将捷径分支的输出与主分支的输出进行相加)。所以第一层残差结构需要将shape从[56, 56, 64] --> [56, 56, 256]。注意,这里只调整channel维度,高和宽不变(而conv3_x, conv4_x, conv5_x所对应的一系列残差结构的第一层虚线残差结构不仅要调整channel还要将高和宽缩减为原来的一半)。 代码 注: 本次训练集下载在AlexNet博客有详细解说:https://blog.csdn.net/weixin_44023658/article/details/105798326使用迁移学习方法实现收录在我的这篇blog中: 迁移学习 TransferLearning—通俗易懂地介绍(pytorch实例) #model.py import torch.nn as nn import torch #18/34 class BasicBlock(nn.

【unity】完全新手入门教程----创建项目到控制方块移动

百度新手教程,都是卖课广告,故做一个超简单的入门操作。 文章不会多做解析,只注重手把手创建一个能动的东西。最后的效果是用键盘控制方块几个方向移动一下。 一、下载安装 安装VS,个人使用的是vs2015.3.ent_chs.iso unity使用的是:UnitySetup64-2018.2.1f1.exe百度下载安装后,下载安装破解UniPatcher2018_v1.exe 二、创建项目 打开软件,点击新建: 设置好路径、项目名字等信息: 三、基础说明 1.控制说明 鼠标滚轮大小可以控制工作台缩放 按一下快捷键切换当前控制的功能,从左至右为QWERT,功能为 Q:调整视图 W:移动工具 E:旋转工具 R:缩放工具 T:选择工具 控制画面 按住键盘Alt键,然后鼠标左键拖拽画面,可以随意变换画面视角 和scene右上角的控制类似作用 如果你的设计识图角度不喜欢,点击Q然后鼠标拖拽,或者使用Alt+鼠标左键拖拽 2.摄像机 视图中的摄像机图标: 选中摄像机时,右下方有个摄像机当前拍摄出来的效果预览。 按一下w,然后鼠标点击摄像机,摄像机对象有三条红绿蓝的箭头线条,分别对应xyz轴的移动,单击箭头拖拽体验改变摄像机的位置。 按一下E,然后鼠标选中围绕的立体圈随意一条线,尝试拖拽表示改变摄像机的镜头方向。 3.光源 如图表示阳光方向为指向右下方 同理摄像机 按一下w,然后鼠标点击光源,光源对象有三条红绿蓝的箭头线条,分别对应xyz轴的移动,单击箭头拖拽体验改变光源的位置。 按一下E,然后鼠标选中围绕的立体圈随意一条线,尝试拖拽表示改变光源的照射方向。 四、开启项目 1.创建物体 鼠标右键空白处创建两个方块命名为Player和Floor,玩家和地板。 (或者创建一个方块后,下面第2部调整位置后再复制一个) 2.变形和位置 快捷键W,同理上面摄像机,三个箭头表示移动位置,将它们放在摄像机前面。 将Floor下移到Player的下面(靠近灰色地板方向拉)。 快捷键R,选中Floor三个箭头变成小方块,拉伸大小,使它变成一个地板形状 鼠标滚轮大小控制,点击Q然后鼠标拖拽,或者使用Alt+鼠标左键拖拽,使你的工作台展示如下: 3.导入资源 菜单栏的Assets---Import New Assets 导入之后会在下面Assets栏有一个资源图片,然后鼠标拖拽图片到Floor上绑定地板资源。 4.运行预览 点击头部的运行按钮,箭头 再次点击关闭运行回到编辑视图 5.物理效果 选中Player,菜单栏Compoent---Physics---Rigidbody,添加了一个重力物理效果,再次点击运行会发现它可以自由下落了 6.创建脚本 鼠标右键空白处创建Script文件夹 然后选中文件夹右键,创建C#脚本命名:PlayerMove用来做控制物体移动 7.代码控制 双击脚本文件,打开VS2015 打开后脚本已经存在两个方法 修改代码如下: using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMove : MonoBehaviour { // 定义移动速度 public float MoveSpeed = 2f; // Use this for initialization void Start () { } // Update is called once per frame void Update () { // 点击w或者上箭头键,前移动 if (Input.

基于docker-compose的hadoop集群搭建

非docker的版本可以参见之前的文章 docker-compose.yml 这个配置文件是根据bde2020文件略作调整,去掉了tag信息(可以拉取latest)和volume信息,另外也去掉了restart配置 version: "3" services: namenode: image: bde2020/hadoop-namenode container_name: namenode ports: - 9870:9870 - 9000:9000 environment: - CLUSTER_NAME=Qbit env_file: - ./hadoop.env datanode: image: bde2020/hadoop-datanode container_name: datanode environment: SERVICE_PRECONDITION: "namenode:9870" env_file: - ./hadoop.env resourcemanager: image: bde2020/hadoop-resourcemanager container_name: resourcemanager environment: SERVICE_PRECONDITION: "namenode:9000 namenode:9870 datanode:9864" env_file: - ./hadoop.env nodemanager1: image: bde2020/hadoop-nodemanager container_name: nodemanager environment: SERVICE_PRECONDITION: "namenode:9000 namenode:9870 datanode:9864 resourcemanager:8088" env_file: - ./hadoop.env historyserver: image: bde2020/hadoop-historyserver container_name: historyserver environment: SERVICE_PRECONDITION: "namenode:9000 namenode:9870 datanode:9864 resourcemanager:8088"

Java中clone方法详解

Java中clone方法详解 一、clone简介二、Java中对象的创建:new与clone创建对象的区别 三、复制对象or复制引用:第一个例子(复制引用):第二个例子(复制对象): 四、深拷贝 浅拷贝原理浅拷贝深拷贝 一、clone简介 clone 就是复制 , 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。 二、Java中对象的创建: 使用new操作符创建一个对象使用clone方法复制一个对象 new与clone创建对象的区别 new操作符的本意是分配内存。程序执行到new操作符时, 首先去看new操作符后面的类型,根据类型分配内存,再调用构造函数,填充对象的各个域,这一步就叫对象的初始化。初始化完毕后,可以把他的引用(地址)发布到外部,在外部就可以通过引用操纵这个对象。 clone在第一步是和new相似的,都是分配内存,调用clone方法时,分配的内存和源对象一样,然后再使用源对象中对应的各个域,填充新对象的域。同样可以可以把这个新对象的引用发布到外部 。 三、复制对象or复制引用: 第一个例子(复制引用): 由上图得打印的地址值是相同的,既然地址相同,那么肯定是同一个对象。p和p1只是引用而已,他们都指向了一个相同的对象Person(23, “zhangsan”) 。 这种现象叫做“引用的复制” 内存分析: 第二个例子(复制对象): 内存分析: 四、深拷贝 浅拷贝 Person中有两个成员变量,分别是name和age, name是String类型, age是int类型 public class Person implements Cloneable{ private int age; private String name; public Person(int age,String name){ this.age = age; this.name = name; } public Person(){} public int getAge(){ return age; } public String getName(){ return name; } protected Object clone()throws CloneNotSupportedException{ return (Person)super.

Spring源码分析-从源码看BeanFactory和FactoryBean的区别

导语 在使用Spring 中最为核心的操作就是Bean的创建以及使用。下面就来带着大家一起来分析一下关于Spring的Bean的加载相关的知识 文章目录 BeanFactory getBean方法原理分析1、转换对应的BeanName2、尝试从缓存中加载单例3、Bean的实例化4、原型模式依赖检查5、检查ParentBeanFactory6、将XML配置文件中的对象关系进行转换7、依赖查找8、根据不同的作用域创建9、类型转换 FactoryBean的使用原理分析 总结 熟悉Spring的人都知道,对于容器的操作,都是从一个BeanFactory的接口而来。而在使用Bean的时候调用的就是getBean方法来获取到需要的Bean对象。如下图所示,getBean()方法在一下的一些类里面被实现了这里值得关注的有两个类AbstractBeanFactory 和StaticListableBeanFactory 两个类,这两个类直接或者间接的实现的getBean()的方法,下面就来进入到AbstractBeanFactory 的getBean方法中进行分析。 根据框架源码的一贯习惯,真正执行操作的并不是这个getBean()的方法,而是其中的以do开头的方法。那么就进入到其中看看都有那些操作? BeanFactory getBean方法 原理分析 进入到AbstractBeanFactory 类中会看到根据Bean的名称获取Bean对象的操作是通过了如下的一层封装。其中确实是有一个doGetBean()的方法。下面就来看看这个doGetBean方法。 @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } 在这个方法中传入了四个参数 name:Bean的name;requiredType:需要的Bean是什么类型的,args: 传入的其他参数列表typeCheckOnly :是否进行类型检查 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException 对于上面的这些参数,先不做过多的介绍,在具体调用到这些参数的时候就会知道它们具体的操作是什么了。 1、转换对应的BeanName 进入该方法之后,对于对应的BeanName进行了提取,也许有人会问,在使用的时候我们传入的不就是我们定义的Bean Name么,直接进行查找不就可以了么,为什么还要进行多余的提取操作呢?这里,对于Bane Name的提取其实是为了解决一个问题,在我们使用的时候并不是所有的Bean都进行Name的设计,在很多的场景下,我们只是对我们能操作的Bean或者是需要的地方进行的name 的配置,但是在很多的场景下都是没有以类名小写直接作为BeanName 存在。为了统一 默认的BeanName和自定义的BeanName所以进行了一个BeanName的提取操作。根据传入的BeanName来确定一个可用的BeanName。 //提取对应的beanName final String beanName = transformedBeanName(name); Object bean; 2、尝试从缓存中加载单例 接下来会进行从缓存中检查对应实例的操作,在创建单实例Bean的时候回存在依赖注入的操作,如果已经存在了对应的Bean实例就会出现循环注入的错误。Spring 的原则就是在创建Bean的时候不等到Bean创建完成就将BeanFactory进行曝光,也将BeanFactory加入到对应的缓存中,从而告诉其他调用,有对应的BeanFactory来创建该对象,如果需要进行创建的话直接可以从缓存中进行获取到该BeanFactory进行创建对象。代码如下。

Spring Boot 分布式事务 Seata 入门

1. 概述 在《芋道 Seata 极简入门》文章中,我们对 Seata 进行了简单的了解,并完成了 Seata 的部署。而本文,我们将纯 Spring Boot 应用接入 Seata 来实现分布式事务。 Seata 是阿里开源的一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。 2. AT 模式 + 多数据源 示例代码对应仓库:lab-52-multiple-datasource 。 在 Spring Boot 单体项目中,如果使用了多个数据源,我们就需要考虑多个数据源的一致性,面临分布式事务的问题。本小节,我们将使用 Seata 的 AT 模式,解决该问题。 友情提示:对 Seata 的 AT 模式不了解的胖友,可以阅读《Seata 文档 —— AT 模式》文档。 我们以用户购买商品的业务逻辑,来作为具体示例,一共会有三个模块的 Service,分别对应不同的数据库。整体如下图所示: 下面,我们来新建 lab-52-multiple-datasource 项目,最终结构如下图: 2.1 初始化数据库 使用 data.sql 脚本,创建 seata_order、seata_storage、seata_amount 三个库。脚本内容如下: # Order DROP DATABASE IF EXISTS seata_order; CREATE DATABASE seata_order; CREATE TABLE seata_order.orders ( id INT(11) NOT NULL AUTO_INCREMENT, user_id INT(11) DEFAULT NULL, product_id INT(11) DEFAULT NULL, pay_amount DECIMAL(10, 0) DEFAULT NULL, add_time DATETIME DEFAULT CURRENT_TIMESTAMP, last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; CREATE TABLE seata_order.

html中的details与summary

details的效果就像我们经常见到的“手风琴”样式,可以自由的折叠和展开,看几个例子。details可以使用在body元素内的任何地方。 1.details单独使用 <details> <p>菜单项1</p> <p>菜单项2</p> <p>菜单项3</p> </details> 效果如图,默认是折叠的: 2.怎么让details默认是打开的呢,加上open属性即可? <details open> <p>菜单项1</p> <p>菜单项2</p> <p>菜单项3</p> </details> 效果图: 3.details黑色的小三角右边的文字默认就是“详细信息”,怎么更改呢?这时候就需要使用到summary标签了: <details open> <summary>全部功能</summary> <p>菜单项1</p> <p>菜单项2</p> <p>菜单项3</p> </details> 如下: 4.另外,比如我一个菜单下面还有子菜单,怎么实现呢?不用担心,details还支持嵌套使用: <details open> <summary>全部功能</summary> <p>菜单项1</p> <p>菜单项2</p> <details open> <summary>用户管理</summary> <p>用户查询</p> <p>用户赋权</p> <p>用户组别管理</p> </details> </details> 结果如图: <details open> <summary>全部功能</summary> <p>菜单项1</p> <p>菜单项2</p> <details open> <summary>用户管理</summary> <p>用户查询</p> <p>用户赋权</p> <p>用户组别管理</p> </details> </details> 好了,这两个标签都懂了吧。

ZigBee入门-CC2530-实验(五)-串口通信控制LED代码

:在我们学习任何一款单片机的时候,串口外设毫无疑问是我们验证实验,理解配置,学习单片机的最直观体现。 :在我们开发实战中,通过串口通信给下位机发送命令,然后去执行命令这是很常见的操作。 /***************************************************************** *实验说明: *CC2530向上位机PC发送一个字符串,串口助手中显示; *上位机PC向CC2530通过串口助手发送一个数据命令; *然后CC2530先接收,然后判断并执行相应的命令; *****************************************************************/ #include <ioCC2530.h> #define uint unsigned int #define uchar unsigned char #define LED1 P1_0 //定义P1_0为LED1的控制引脚 #define LED2 P1_1 //定义P1_1为LED2的控制引脚 void Init_LED(); //声明LED初始化函数 void Init_Uart0(); //声明串口0初始化函数 void Init_Cfg_32M(); //声明初始化32M时钟初始化函数 void UR0SendByte(unsigned char Byte);//声明发送一个字节初始化函数 void UR0SendString(unsigned char *str);//声明发送字符串初始化函数 void Execute_CMD(); //声明执行上位机命令初始化函数 char RxBuf; //定义接收缓冲区 char Rx_flag; //定义串口接收标志位 /*====================主函数入口====================*/ void main() { Init_LED(); //初始化LED端口 Init_Uart0(); //初始化串口0 Init_Cfg_32M(); //初始化32M晶振 UR0SendString(" Hello ZigBee!\r\n"); while(1) { if(Rx_flag == 1) //是否接收到上位机指令 { Execute_CMD(); //判断并执行上位机指令 } } } /*===================LED初始化函数==================*/ void Init_LED() { P1SEL &= ~0x03; //将P1_0和P1_1设置为通用I/O端口功能 P1DIR |= 0x03; //将P1_0和P1_1的端口设置为输出 LED1 = 0; //关闭LED1灯 LED2 = 0; //关闭LED2灯 } /*==================32M晶振初始化函数===============*/ void Init_Cfg_32M() { CLKCONCMD &= ~0x40; //系统时钟源选择:外部32MHz 。 while(!

java中面向对象(OOP)基础概念

本文连接:https://blog.csdn.net/MDWJJ/article/details/105820938 什么是对象 1.软件系统中的事物个体也称为业务实体,一切皆对象 2.每个对象包含一组数据和相关的操作方法 类:将对象的公共属性和行为抽取到定义类中,可以作为模板复用创建对象 实例化:利用类创建对象的过程称为实例化 构造器:用于封装对象属性实例化过程,创建对象时调用 语法: 1.在类中声明,方法名与类名一致 2.不能有返回值,不能使用void 3.可以有参数,用来实例化对象 4.使用new运算调用构造器,创建对象 5.如果类不定义构造器,Java编译器会自动提默认供构造器;如果类定构造器,Java编译器就不会提供默认构造器 6.构造器重载用于实现:对象有多种数据初始化方式 引用 1.也称为引用变量,Java中除了基本类型变量其他都是引用类型变量 2.用于操作对象的“句柄handle” 3.应用变量中存储了对象的首地址,利用收地址间接操作内存对象 4.简单说:引用用于操作对象 5.Java自动维护引用的地址,对外不可见,屏蔽了平台差异(跨平台) 面向对象的3个重要概念 1.封装:将数据以及算法尽可能隐藏到类的内部,只暴露必要的操作方法和数据 2.继承:复用,利用父类复用子类中公共属性和方法,将子类公共属性很方法“泛化”到父类中(画图子类箭头指向父类)。泛化:将子类的公共属性和方法抽取到父类的过程称为泛化。 3.多态:父类型变量引用的子类型个体是多种多样的,使用子类型方法的时候其功能也是多种多样的 重载 1.在类中(包含父类)定义的方法名一样参数(个数、顺序)不同的方法 2.一般这些的方法封装的算法(方法体)都不相同 3.只是为了表示设计的优雅而将方法名定义为一样 4.调用方法时候,根据方法名和参数列表 识别调用哪个方法。 如果参数不相同,Java会尝试自动转换类型 方法签名 方法名+参数类型列表 = 方法签名 this 引用 this 引用当前的这个对象 1.this 用于区别方法(构造器)中的局部变量和实例变量 2.当方法中局部变量和实例变量同名的时候,可以使用this.实例变量与局部变量加以区分 3.当实例变量名和局部变量名没有冲突,可以省略this 局部变量:方法的参数是局部变量 this()用于调用当前类的其他构造器 1.其目的是为了将构造器的逻辑进行复用 (a) 多个构造器使用一个初始化逻辑 2.this()只能在构造器使用 3.this()写在构造器的第一行 继承 子类可以继承(获得)父类中的属性和方法。子类无需声明就可以获得父类中的属性和方法。 利用“泛化”实现继承! 泛化:将对象相同的属性进行抽象同一的过程称为泛化 继承语法: 1.使用extends实现继承 2.被继承者是父类(超类super class)中的属性和方法被子类继承 3.继承者是子类 4.Java是单继承语言 5.如果没有父类,则自动继承于Object 类型 重写: 1.在子类中修改从父类中继承的方法 在子类中定义一个与父类型具有相同“方法签名(方法名+参数类型列表)”的方法 2.能够继承的方法才能重写 语法:子类定义一与父类“一样”的方法 a)方法名一样; b)参数一样

一文带你搞懂Spring MVC和servlet(面试必备)

一、Spring MVC与Jsp/Servlet比较1、传统的 Jsp/Servlet 技术体系弊端2、Spring Web MVC 特点3、Spring MVC工作流程 二、idea创建servlet项目1、搭建过程2、servlet的工作流程3、servlet的生命周期 三、idea创建Spring MVC项目1、搭建过程2、Spring MVC接口解释接口解释DispatcherServlet 一、Spring MVC与Jsp/Servlet比较 1、传统的 Jsp/Servlet 技术体系弊端 Servlet: 是用java编写的服务端应用程序。 作用:主要用于交互式的浏览和修改数据,生成web内容,这个过程为:客户端发送请求到服务器 -> 服务器将请求信息发送至Servlet–>Servlet生成相应内容并将其传给服务器-> 服务器将响应返回给客户端。在传统的 Jsp/Servlet 技术体系中,如果要开发接口,一个接口对应一个 Servlet,每个请求都去在web.xml中配置一个servlet节点。会导致我们开发出许多 Servlet,使用 SpringMVC可以有效的简化这一步骤。 2、Spring Web MVC 特点 Spring Web MVC 是一种基于 Java 的实现了 Web MVC 设计模式的请求驱动类型的轻量级 Web 框架,即使用了 MVC 架构模式的思想,将 web 层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,SpringWeb MVC 也是要简化我们日常 Web 开发的。Spring Web MVC 也是服务到工作者模式的实现,但进行可优化。前端控制器是DispatcherServlet;应用控制器可以拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver)进行视图管理;页面控制器/动作/处理器为 Controller 接口(仅包含 ModelAndView handleRequest(request, response) 方法,也有人称作 Handler)的实现(也可以是任何的 POJO类);支持本地化(Locale)解析、主题(Theme)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。 3、Spring MVC工作流程 1、用户发送请求至前端控制器DispatcherServlet。 2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

深入浅出Disruptor的使用和原理

1. Disruptor简介 Disruptor git地址:https://github.com/LMAX-Exchange/disruptorDisruptor定义:线程间的高性能消息框架Disruptor核心思想:把多线程并发写的线程安全问题转化为线程本地写,即:不需要做同步 2. Disruptor优点 Disruptor非常轻量,整个框架最新版3.4.2也才70多个类,但性能却非常强悍,得益于其优秀的设计和对计算机底层原理的运用单线程每秒能处理超600W的数据(Disruptor能在1秒内将600W数据发送给消费者,其实600W是Disruptor刚发布时硬件的水平了,现在在个人PC上也能轻松突破2000W)基于事件驱动模型,不用消费者主动拉取消息比JDK的ArrayBlockingQueue性能高一个数量级 3. 为什么这么快! 无锁序号栅栏缓存行填充,消除伪共享内存预分配环形队列RingBuffer 4. Disruptor核心概念 RingBuffer:环形队列,基于数组的内存级别缓存,是创建sequencer(序号)与定义WaitStrategy(拒绝策略)的入口Disruptor:对RingBuffer的封装,持有RingBuffer、消费者线程池Executor、消费之集合ConsumerRepsitory等引用Sequence:对RingBuffer中的元素进行序号标记,通过顺序递增的方式来管理进行交换的数据(事件/Event),一个Sequence可以跟踪标识某个事件的处理进度,同时还能消除伪共享Sequencer:Sequencer里面包含了Sequence,是Disruptor的核心,Sequencer有两个实现类:SingleProducerSequencer(单生产者实现)、MultiProducerSequencer(多生产者实现),Sequencer主要作用是实现生产者和消费者之间快速、正确传递数据的并发算法SequenceBarrier:消费者屏障,用于控制RingBuffer的Producer和Consumer之间的平衡关系,并且决定了Consumer是否还有可处理的事件的逻辑WaitStrategy:消费者等待策略,决定了消费者如何等待生产者将Event生产进Disruptor,WaitStrategy有多种实现策略,分别是: 1. BlockingWaitStrategy:阻塞方式,效率较低,但对cpu消耗小,内部使用的是典型的锁和条件变量机制(java的ReentrantLock),来处理线程的唤醒,这个策略是disruptor等待策略中最慢的一种,但是是最保守使用消耗cpu的一种用法,并且在不同的部署环境下最能保持性能一致。 但是,随着我们可以根据部署的服务环境优化出额外的性能 2. BusySpinWaitStrategy:自旋方式,无锁,BusySpinWaitStrategy是性能最高的等待策略,但是受部署环境的制约依赖也越强。 仅当event处理线程数少于物理核心数的时候才应该采用这种等待策略。 例如,超线程不可开启。 3. LiteBlockingWaitStrategy:BlockingWaitStrategy的变体版本,目前感觉不建议使用 4. LiteTimeoutBlockingWaitStrategy:LiteBlockingWaitStrategy的超时版本 5. PhasedBackoffWaitStrategy:自旋 + yield + 自定义策略,当吞吐量和低延迟不如CPU资源重要,CPU资源紧缺,可以使用此策略 6. SleepingWaitStrategy:自旋休眠方式(无锁),性能和BlockingWaitStrategy差不多,但是这个对生产者线程影响最小,它使用一个简单的loop繁忙等待循环,但是在循环体中间它调用了LockSupport.parkNanos(1)。 一般情况在linux系统这样会使得线程停顿大约60微秒。不过这样做的好处是,生产者线程不需要额外的累加计数器,也不需要产生条件变量信号量开销。 负面影响是,在生产者线程与消费者线程之间传递event数据的延迟变高。所以SleepingWaitStrategy适合在不需要低延迟, 但需要很低的生产者线程影响的情形。一个典型的案例是异步日志记录功能。 7. TimeoutBlockingWaitStrategy:BlockingWaitStrategy的超时阻塞方式 8. YieldingWaitStrategy:自旋线程切换竞争方式(Thread.yield()),最快的方式,适用于低延时的系统,在要求极高性能且事件处理线数小于CPU逻辑核心数的场景中推荐使用此策略,它会充分使用压榨cpu来达到降低延迟的目标。 通过不断的循环等待sequence去递增到合适的值。 在循环体内,调用Thread.yield()来允许其他的排队线程执行。 这是一种在需要极高性能并且event handler线程数少于cpu逻辑内核数的时候推荐使用的策略。 例如,你开启了超线程。(译者注:超线程是intel研发的一种cpu技术,可以使得一个核心提供两个逻辑线程,比如4核心超线程后有8个线程) ✨✨✨✨✨这里说一下YieldingWaitStrategy使用要小心,不是特别要求性能的情况下,要谨慎使用,否则会引起服务起cpu飙升的情况,因为他的内部实现是在线程做100次递减然后Thread.yield(),可能会压榨cpu性能来换取速度,所以如果要使用要满足上面的描述Evnet:从生产者到消费者过程中所处理的数据单元,Event由使用者自定义EventHandler:由用户自定义实现,就是我们写消费者逻辑的地方,代表了Disruptor中的一个消费者的接口EventProcessor:这是个事件处理器接口,实现了Runnable,处理主要事件循环,处理Event,拥有消费者的Sequence,这个接口有2个重要实现: WorkProcessor:多线程处理实现,在多生产者多消费者模式下,确保每个sequence只被一个processor消费,在同一个WorkPool中,确保多个WorkProcessor不会消费同样的sequence BatchEventProcessor:单线程批量处理实现,包含了Event loop有效的实现,并回调到了一个EventHandler接口的实现对象,这接口实际上是通过重写run方法,轮询获取数据对象,并把数据经过等待策略交给消费者去处理 5. Disruptor基本使用方式 maven依赖: <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.2</version> </dependency> ----------------------------------------------------华丽的分割线------------------------------------------------------ 5.1 Disruptor单生产单消费简单模式举例: import lombok.Data; /** * 消息对象 */ @Data public class TestEvent { private Long data; } import com.

常见用法——js中如何动态生成元素的几种方法总结(简单直观!)

我们一般在渲染页面时会根据给定的数据来动态的渲染页面。在学习完原生js以及jQuery后,总结如下几种动态生成元素的方法。 接下来我会直接用实例来总结方法!相关知识点可查阅文档。 1.首先是利用原生js的节点操作 一般我们可以利用原生js的节点操作使用createElement()方法来创建元素(节点),然后利用innerHTML属性来设置元素的内容,最后使用appendChild()方法来添加元素(节点)。 appendChild()方法:将元素添加到父元素里面的最后面 insertBefore(生成的元素,指定元素):将动态生成的元素插入到指定元素的前面 栗子: 使用字符串的形式(更简单) 我们可以直接使用字符串的形式,把标签里面的内容顺便写好。这样就不需要使用innerHTML属性了!最后利用insertAdjacentHTML()方法来追加给父元素。 栗子: var li='<li>123</li>'; ul.insertAdjacentHTML(beforeend , li); 使用说明: 使用jQuery实现 1).生成元素 2)添加元素(分:外部添加和内部添加) 内部添加:append() 和prepend() 前一个放到父元素里面的最后面 ,后一个是放到父元素里面的最前面 外部添加: 栗子: // 1. 创建元素 var li = $("<li>我是后来创建的li</li>"); // 2. 添加元素 //1) 内部添加 // $("ul").append(li); // 内部添加并且放到内容的最后面 $("ul").prepend(li); // 内部添加并且放到内容的最前面 最后用一个实例来体现一下: 功能:实现动态生成表格数据 html部分: <div class="tb"> <table> <thead> <tr> <th>id</th> <th>产品名称</th> <th>价格</th> </tr> </thead> <tbody> //里面的内容通过动态生成 </tbody> </table> </div> <scirpt> // 用数组对象的形式存储数据 var data = [{ id: 1, pname: '小米', price: 3999 }, { id: 2, pname: 'oppo', price: 999 }, { id: 3, pname: '荣耀', price: 1299 }, { id: 4, pname: '华为', price: 1999 }]; // 获取元素 var tbody = this.

HttpServletRequest获取URL、URI

从Request对象中可以获取各种路径信息,以下例子: 假设请求的页面是index.jsp,项目是WebDemo,则在index.jsp中获取有关request对象的各种路径信息如下 import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String getContextPath = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+getContextPath+"/"; String getRemoteAddress=request.getRemoteAddr(); String getServletPath =request.getServletPath(); String getServletContext_getRealPath =request.getServletContext.getRealPath("/"); String getRequestURL =request.getRequestURL().toString(); String getRequestURI =request.getRequestURI(); String getQueryString =request.getQueryString(); String getRemoteUser =request.getRemoteUser(); out.println("getContextPath:"+ getContextPath +"<br>"); out.println("basePath:"+basePath+"<br>"); out.println("getRemoteAddress:"+ getRemoteAddress +"

MySQL :ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)

报错: ERROR 2003 (HY000): Can’t connect to MySQL server on ‘localhost’ (10061) 起因: 执行了一行语句 先这个没问题 SELECT * FROM targets WHERE gene_name in (SELECT gene_name from vitiligo_gene277); 再 SELECT DISTINCT gene_name FROM targets WHERE gene_name in (SELECT gene_name from vitiligo_gene277); 然后MySQL炸了,ERROR 2003 服务手动重启 但是一运行就报错(因为刚开始没意识到是这条语句的问题,随意每次重启MySQL后我就继续之前的操作,结果emmm) 电脑重启 目前运行的项目: show processlist; SET GLOBAL event_scheduler = ON; SET GLOBAL event_scheduler = OFF; 手动重启MySQL ,别运行这条语句就好,猜测是因为存储空间大小问题,已经不足以再查询这么复杂的数据。 先记录一下,深层原因还不知道,只是猜测内存不够了,之前类似的语句已知可以运行。

你不知道的HTML页面刷新全部方法

1、reload 方法,该方法强迫浏览器刷新当前页面。 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页。true, 则以 GET 方式,从服务端取最新的页面, 相当于客户端点击 F5(“刷新”) 2、 replace 方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,你不能通过“前进”和“后退”来访问已经被替换的URL。 语法: location.replace(URL) 通常使用: location.reload() 或者是 history.go(0) 来做。 此方法类似客户端点F5刷新页面,所以页面method=”post”时,会出现”网页过期”的提示。 因为Session的安全保护机制。 当调用 location.reload() 方法时, aspx页面此时在服务端内存里已经存在, 因此必定是 IsPostback 的。 如果有这种应用: 需要重新加载该页面,也就是说期望页面能够在服务端重新被创建,期望是 Not IsPostback 的。 这里,location.replace() 就可以完成此任务。被replace的页面每次都在服务端重新生成。 代码: location.replace(location.href); 3、返回并刷新页面: location.replace(document.referrer); document.referrer //前一个页面的URL 不要用 history.go(-1),或 history.back();来返回并刷新页面,这两种方法不会刷新页面。 4、Javascript刷新页面的几种方法: 1,history.go(0) 2,location.reload() 3,location=location 4,location.assign(location) 5,document.execCommand('Refresh') 6,window.navigate(location) 7,location.replace(location) 8,document.URL=location.href 5、自动刷新页面的方法: 5.1、页面自动刷新:把如下代码加入区域中,其中20指每隔20秒刷新一次页面 <meta http-equiv="refresh" content="20"> 5.2、页面自动跳转:把如下代码加入区域中,其中20指隔20秒后跳转到https://www.baidu.com页面 <meta http-equiv="refresh" content="20;url="https://www.baidu.com"> 1 5.3、页面自动刷新js版 <script language="

Python3.8解决No module named 'numpy'报错

报错: 解决: python -m pip install --upgrade pip pip install numpy (pip是python包管理工具) 安装好执行 python import numpy 没报错即可 不行的话(强行安装更新更高的版本) sudo pip install numpy --ignore-installed numpy

keepalived配置tomcat的高可用

我这里只说配置tomcat的高可用的步骤,不再讲解原理以及执行流程方面的知识, 关于keepalived的原理以及执行流程,请参考我的其他文章。 机器: ip操作系统版本备注10.253.12.10CentOS Linux release 7.0 (Core) 将被配置为MASTER10.253.12.30CentOS Linux release 7.0 (Core) 将被配置为BACKUP 约定: 为了简便,下文10.253.12.10我会简称10,10.253.12.30我会简称为30。 一、10上的keepalived的配置文件 vi /etc/keepalived/keepalived.conf: ! Configuration File for keepalived global_defs { router_id zaspark02 #当前机器标识 } vrrp_script monitor_tomcat { script "/etc/keepalived/script/tomcat_monitor.sh" interval 3 } vrrp_instance VI_1 { state MASTER #主MASTER 从BACKUP interface eth0 #ifconfig 得到,机器不同可能不同 virtual_router_id 51 priority 100 #1-254 ,从需要小于主 #如果机器不支持组播,需要使用单播模式开始 unicast_src_ip 10.253.12.10 unicast_peer { 10.253.12.30 } #如果机器不支持组播,需要使用单播模式结束 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.

chrome 调试进入 paused in debugger 状态解决办法

最近发现谷歌F12总是进入断点...... 在chrome中进行调试时,即使未设置任何断点,脚本也始终在调试器中暂停 原因: 选中了DOMException的Pause按钮,您启用了“异常暂停”(窗口左下方带有停止符号( || )的停止符号形状的图标) 解决方法: F12调试切换到Sources窗口,尝试将停止符号( || )单击回到关闭/灰色状态(不是红色或蓝色状态),然后重新加载页面即可

数据可视化踩坑指南之引用echarts.min.js放置位置问题

首先上bug图: 由于自己的自作聪明,将echarts.min.js文件引用放置在了head标签体当中,代码中也没有报错信息,一运行就是并没有出现想要的数据图,此时回头来看控制台显示的错误信息。 引起错误的引用位置: <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="css/index.css" /> <script src="js/echarts.min.js"></script> <script src="js/index.js"></script> </script> </head> 正确运行的引用位置: <body> /*这里是你设计的盒子的代码*/ /*echarts.min.js文件和自己定义的文件引用放在</body>之前*/ <script src="js/echarts.min.js"></script> <script src="js/index.js"></script> </body>

R语言|簇状条形图(二)———R语言数据可视化系列(三)

簇状条形图的绘制与美化 建立数据绘制簇状条形图条形图着色条的大小更改条形图间间距堆积条形图完整代码仅供参考创作不易,都浏览到这儿了,看官可否将下面的收藏点赞帮忙点亮。 建立数据 巧妇难为无米之炊,按例我得先搬出我得伙伴们。这次为了让图像效果更加好看,对数据进行了稍微的调整。 绝不是剧里真实的信息 姓名性别科目成绩顾未易男语文97顾未易男数学95顾未易男英语89司徒末女语文84司徒末女数学81司徒末女英语91宁为谨男语文98宁为谨男数学86宁为谨男英语88郑叮叮女语文86郑叮叮女数学84郑叮叮女英语95韩商言男语文92韩商言男数学87韩商言男英语85佟年女语文92佟年女数学87佟年女英语91 ## 簇状条形图 ### 数据建立 name_cz <- c(rep(c("顾未易", "司徒末", "宁为谨", "郑叮叮", "韩商言", "佟年"), each = 3)) # 姓名 sex_cz <- c(rep(c(rep(c("男", "女"), each = 3)), 3)) # 性别 subject <- c(rep(c("语文", "数学", "英语"), 6)) # 科目 score_cz <- c(97,95,89,84,81,91,98,86,88,86,84, # 成绩 95,92,87,85,92,87,91) data_cz <- data.frame(name_cz, sex_cz, subject, score_cz) # 合并为数据框 如果对代码中rep()函数不太了解的可移步观看R语言|数据结构(一) 向量 ———R语言入门到入土系列(二)文章。 在有了数据基础后,就可以进行数据的可视化工作。 绘制簇状条形图 ### 基本簇状条形图 ggplot(data_cz,aes(x = name_cz, y = score_cz, fill = subject))+ # 选择xy轴的数据 geom_bar(position = "

Failed to introspect annotated methods on class

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.xja.udai.customer.UdaiCustomerApplication]; nested exception is java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:609) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:310) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:249) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:206) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:174) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:319) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.

【菜鸟进阶之路】P1152 欢乐的跳 - 洛谷

一、题目部分 题目描述 一个n个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了[1,n-1]之间的所有整数,则称之符合“欢乐的跳”,如数组1 4 2 3符合“欢乐的跳”,因为差的绝对值分别为:3,2,1。 给定一个数组,你的任务是判断该数组是否符合“欢乐的跳”。 输入格式 每组测试数据第一行以一个整数n(1≤n≤1000)开始,接下来n个空格隔开的在[-10^8 − 10^8]之间的整数。 输出格式 对于每组测试数据,输出一行若该数组符合“欢乐的跳”则输出"Jolly",否则输出"Not jolly"。 输入输出样例 输入 #1 4 1 4 2 3 输出 #1 Jolly 输入 #2 5 1 4 2 -1 6 输出 #2 Not jolly 二、解题过程 思路 (1)输入 (2)判断是否符合绝对值条件 (3)输出判断结果 提交AC答案 #include<bits/stdc++.h> using namespace std; int n,a[10000]; int search(int *a,int n) { for(int i=1;i<n;i++) { int d=a[i]-a[i-1]; if( ( d<-1 && d>1 ) || ( d>(n-1) || d<(1-n) ) ) { return 0; break; } } } int main() { //输入整数n scanf("

zabbix 4.4.7 监控图形 界面中文乱码

zabbix web 的PHP程序调用graphfont.ttf这个字体文件: ll /usr/share/zabbix/assets/fonts graphfont.ttf -> /etc/alternatives/zabbix-web-font graphfont.ttf 指向 /etc/alternatives/zabbix-web-font /etc/alternatives zabbix-web-font -> /usr/share/fonts/dejavu/DejaVuSans.ttf zabbix-web-font 指向 /usr/share/fonts/dejavu/DejaVuSans.ttf 创建目录 mkdir -p /usr/share/fonts/zabbix/ 下载字体 百度网盘 链接:https://pan.baidu.com/s/1MyiuklyRN6nDNj1IYRMp_w 密码:3uvb 上传字体到/usr/share/fonts/zabbix/ chmod 777 /usr/share/fonts/zabbix/simkai.ttf cd /etc/alternatives 备份 mv zabbix-web-font{,.date +%F-%H%M} 链接到新的字体 ln -s /usr/share/fonts/zabbix/simkai.ttf zabbix-web-font 不用重启,查看已解决

sql语法,查询字段如果为空/null,就返回0,写法

# 为 NULL 时写法 SELECT 字段1,字段2,CASE WHEN 字段3 IS NULL THEN 0 ELSE 字段3 END FROM 表名 SELECT id,account,CASE WHEN score IS NULL THEN 0 ELSE score END FROM accountinfo # 为 '' 时写法 SELECT 字段1,字段2,CASE WHEN 字段3 = '' THEN 0 ELSE 字段3 END FROM 表名 SELECT id,account,CASE WHEN score = '' THEN 0 ELSE score END FROM accountinfo

修改vue组件中的样式

开发中需要修改组件的样式:下面是对应的方法,亲测有效,下面是参考链接。 详细链接

解决编码问题:AttributeError: 'str' object has no attribute 'decode'

1. 问题发现: 出现:读取文件,对其进行解码,出现以上错误,AttributeError: 'str' object has no attribute 'decode' 解释:属性错误,str对象不包含‘decode’属性。 2.原因解释: 出现问题原因:str与bytes表示的是两种数据类型,str为字符串型,bytes为字节型。对str编码encode得到bytes, 对bytes解码得到str,两者互为转换。而上面出现问题的原因是对str字符串使用了解码,显然是猪头不对马尾。 3.解决方法: 解决办法:删除decode(‘utf-8’) 4.代码演示: txt = '你好,shiyi,很感谢你陪伴我的日子' #str->bytes encode txt = txt.encode('utf-8') print(type(txt)) #bytes->str decode txt = txt.decode('utf-8') print(type(txt)) 5.结果展示: E:\tool\python\python.exe "E:/学习笔记/NLP学习/NLP code/情感分析2/decodetest.py" <class 'bytes'> <class 'str'> Process finished with exit code 0

小型文件系统FatFS和LittleFS对比和区别

关注、星标公众号,不错过精彩内容 素材来源:网络 编辑整理:strongerHuang 对于许多物联网设备而言,拥有一个小型且具有弹性的文件系统至关重要。 在MCU上运行的文件系统不多,绝大部分人应该知道FatFS这个文件系统,今天就给大家讲讲FatFS和LittleFS的内容,以及他们之间的一些差异。 一、文件系统FatFS FatFs是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。 网址: http://elm-chan.org/fsw/ff/00index_e.html FatFs组件的编写遵循ANSI C(C89),完全分离于磁盘 I/O 层,因此不依赖于硬件平台。它可以嵌入到资源有限的微控制器中,如 8051, PIC, AVR, ARM, Z80, RX等等,不需要做任何修改。 ---来自百度百科 特征 a.DOS/ Windows兼容的FAT/exFAT文件系统。 b.平台无关,容易移植。 c.程序代码和工作区的占用空间非常小。 d.支持以下各种配置选项: ANSI / OEM或Unicode中的长文件名。 exFAT文件系统,64位LBA和GPT可存储大量数据。 RTOS的线程安全。 多个卷(物理驱动器和分区)。 可变扇区大小。 多个代码页,包括DBCS。 只读,可选API,I / O缓冲区等... 如果你会使用STM32CubeMX,想要使用FatFS非常容易,轻松几步就能将STM32“变成”一个U盘。 二、文件系统Littlefs 知道Littlefs文件系统的人相对比较少,但是如果使用过Mbed OS系统的人绝大部分都应该知道。 Mbed OS是Arm公司针对Cortex-M系列处理器,面向IoT开发的一套免费、开源开源嵌入式操作系统,专门为物联网中的“things”而设计。 而Littlefs只是Mbed其中的一部分内容,如下框图: 源码地址: https://github.com/armmbed/mbed-littlefs Littlefs特点: 占用资源小:物联网设备受到ROM和RAM的限制。 断电恢复能力:要求文件系统保持一致,并将数据刷新到底层存储。 平均磨损:通常情况下,存储支持每块数量有限的擦除,因此使用整个存储设备对于可靠性非常重要。 用法也挺简单,参看官方例程: #include "LittleFileSystem2.h" #include "SPIFBlockDevice.h" // Physical block device, can be any device that supports the BlockDevice API SPIFBlockDevice bd(PTE2, PTE4, PTE1, PTE5); // Storage for the littlefs LittleFileSystem2 fs("

STM32——IIC基础知识及例程使用(后续拓展)

文章目录 IIC协议软件实现IIC例程(操作24C02芯片)软件程序流程硬件设计软件设计IIC协议实现代码操作24C02芯片代码 编译成功后进行下载验证: STM32自带IIC部分实现例程操作 IIC协议 IIC(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接 微控制器及其外围设备。它是由数据线 SDA 和时钟 SCL 构成的串行总线,可发送和接收数据。 在 CPU 与被控 IC 之间、 IC 与 IC 之间进行双向传送, 高速 IIC 总线一般可达 400kbps 以上。 I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答 信号。 开始信号: SCL 为高电平时, SDA 由高电平向低电平跳变,开始传送数据。 结束信号: SCL 为高电平时, SDA 由低电平向高电平跳变,结束传送数据。 应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲, 表示已收到数据。 CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号, CPU 接 收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为 受控单元出现故障。 这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。 IIC 总线时序图如 图所示: 之前一直听过也偶尔用IIC协议,但是真的在单片机中自我实现或者随意配置还是做不到,这里还是先用开发板上自带的IIC模块和例程来进行学习记录。 开发板上的例程IIC主要使用板载的EEPROM芯片,型号为24C02。该芯片的总容量是256个字节,通过IIC总线与外部连接,通过操作该芯片可以初步了解IIC的初始化及整个协议的运作流程。 一般例程上都是采用软件模拟来达到IIC协议的效果,而对于硬件IIC却很少见有人做个相关的例程,我这里先使用软件模拟IIC来实现操作芯片的效果,后期深入了解后尝试能够使用STM32的硬件IIC来进行操作。 软件实现IIC例程(操作24C02芯片) 软件程序流程 该例程主要使用IIC协议来完成对24C02芯片的操作。整个例程的流程基本上:开机先检测24C02是否存在,然后在主循环中使用按键(KEY0)来执行写入芯片操作,另一个按键(WK_UP)来执行读取操作,通过TFTLCD模块显示相应的信息,同时使用LED0来提示程序正在运行。 硬件设计 根据前面的描述,这个例程中需要操作的外设有:24C02芯片、按键KEY、LED灯以及用来显示的LCD屏幕模块。KEY、LED灯都是通过简单的GPIO通用输入输出功能来实现,这里就不进行详细描述了,LCD屏幕会在另一篇文章中详细描述。 接下来我们看板子上对于24C02芯片的相关硬件连接,如下:

关于JFormDesigner注册的问题

第二步 进行注册 选择插件 生成成功 生成key 生成key成功 可以看到key文件 然后退出 再次打开IDEA的JFromDesigner插件进行注册 点击OK没有反应,接下来从IDEA中卸载掉该插件,然后将JFormDesigner压缩成压缩文件,再从IDEA离线安装该插件,就能够使用成功了。

【数据库】作业16——第七章: 数据库设计

课后习题 7、8、10、11 作业原地址:作业 目录 7. 8. 10. 11. 总结 7. 8. 10. 11. 因为各个关系模式都只有一个码,且都是唯一确定的,所以都属于BCNF,不会产生更新异常。 总结 不是很难,挺简单的。E-R图用word做了一遍发现太大了,截下图来看的不清楚,就用ProcessON做了一遍。 完成时间:22min 以上 ————(2020.4.26)

SonarQube最全安装步骤,教你完美避开所有的坑

在经历了一上午的安装和查找资料后,对于这篇文章,其实我更想口吐芬芳。 值的你关注并提升你薪资待遇的面试算法:开源数据结构和算法实践 目标: 安装一个代码扫描工具,对代码进行静态扫描,及时发现潜在的问题。 SonarQube介绍 SonarQube是一个用于管理代码质量的开放平台 可以快速的定位代码中潜在的或者明显的错误。目前支持java,C#,C/C++,Python,PL/SQL,Cobol,JavaScrip,Groovy等二十几种编程语言的代码质量管理与检测。集成jenkins和DevOps进行CI/CD工作。 七个维度检测代码质量 复杂度分布(complexity):代码复杂度过高将难以理解重复代码(duplications):程序中包含大量复制、粘贴的代码而导致代码臃肿,sonar可以展示源码中重复严重的地方单元测试统计(unit tests):统计并展示单元测试覆盖率,开发或测试可以清楚测试代码的覆盖情况代码规则检查(coding rules):通过Findbugs,PMD,CheckStyle等检查代码是否符合规范注释率(comments):若代码注释过少,特别是人员变动后,其他人接手比较难接手;若过多,又不利于阅读潜在的Bug(potential bugs):通过Findbugs,PMD,CheckStyle等检测潜在的bug结构与设计(architecture & design):找出循环,展示包与包、类与类之间的依赖、检查程序之间耦合度 安装所需环境(所以的坑都在这) 1.Java环境2.数据库3.SonarQube4.Sonar-Scanner 坑 对于上述的4个环境,我并没有说明是什么版本,为什么不说明呢?因为随着 SonarQube 版本的不同,其他三个环境都会变化,先举例几个明显的坑: 1、SonarQube-7.9.1需要 java11 才能启动。2、SonarQube7.9 及以后的版本不再支持 MySQL,SonarQube7.9 之前的版本要求 MYSQL5.6-8.0(左闭右开区间),否则会出现 java.io.IOException: 远程主机强迫关闭了一个现有的连接。3、有些版本(好像是7以后)的SonarQube,只能扫描master分支,不能扫描其他分支。4、据其他博文说明:SQL Server 2016(sql server version需要在12以上,也就是SQL Server 2012及以下版本是不兼容sonarqube 8.2的)5、SonarQube无法连接远程数据库,必须使用localhost。(这个坑有些文章提到,据我实测,不存在,因为我用的就是远程服务器上的sqlserver数据库) 安装大致步骤 1、安装Java11,并配置环境变量(注意:Java11安装后是没有jre的,运行:bin\jlink.exe --module-path jmods --add-modules java.desktop --output jre,会在本目录下生成jre文件夹)2、安装数据库(根据SonarQube的不同版本,选择不同版本的mysql,或者SonarQube7.9 及以后,直接选择sqlserver吧)(我用的是sonarqube-7.9.1 + Microsoft SQL Server 2017 (RTM-CU20) (KB4541283) - 14.0.3294.2 (X64))3、下载 SonarQube,(切记选择你想要的版本)。4、解压缩sonarqube,进入conf文件,配置sonar.properties,这里的配置文件写错了,都会出现连接问题。 配置文件如下: sonar.jdbc.url=jdbc:sqlserver://xxxxxxxx;databaseName=sonarqube sonar.jdbc.username=sa sonar.jdbc.password=xxxxx sonar.login=admin sonar.password=admin 5、进入sonarqube\sonarqube-7.9.1\bin\windows-x86-64文件夹,双击StartSonar.bat,出现下图就可以了。 使用步骤 如何扫描扫描后如何导出pdf 下载插件,如何这个型号:sonar-pdfreport-plugin-2.1.1.jar放置到sonarqube-7.3\extensions\plugins目录下重启sonar服务服务重启后可以看到新增了一个配置页,PDF report为添加插件后新增页签。

一个好的组件应该是什么样的?

背景 19 年 6 月左右,我发布过一篇文章《Bit 初体验》 。在梳理这篇文章的过程中,我可以说深度体验了一把 bit 所提出的概念和做法,就像一颗种子种在我的脑海中,一开始我觉得这东西没什么。 我还记得我第一次与我的同事分享 bit 后,他说: emm,虽然你讲了这么多,但是我觉得好像没有那么...有体感? 感觉没什么卵用? 啊,emm,既然你说了,就像你说的。我觉得我们现在如果引入 bit 会不会对我们的日常工作带来很多额外的工作量。 这种反应很正常,我是在 18 年初,就在 Vue 的官网见到过 bit ,当时我点进去大致浏览过一下。我当时的感受就是,没什么卵用,无非就是 " 前端垂直领域的 git "。对国内的支持情况还不咋地,连一篇像样的中文文档都找不到。 在我们的团队中一下子直接切换到 bit 的工作流,这确实不现实,在公司有那么多的基础建设都不知道 bit 这么个玩意。 但是,bit 的做法和概念,却是非常非常有价值和可以借鉴的! 所以,我想做一件事情,一步一步的把 bit 的玩法用我们熟悉的方式引入进来甚至有所延伸扩展,让大家认同其中的好处和价值。 认识组件 随着近些年”微前端“概念的不断酝酿,越来越多的团队开始着手将自己的业务处理为不同组件,然后通过一些微前端做法,编排到一个业务页面中去。 那么对于组件的维护就会变得越来越重要。所以,先来看看现在大多数团队是怎么维护组件的吧! 大库型,Antd、Element 标准的大库型一次型,完全业务组件,用完一次再也不维护高复用型,一看就应该单独封装以后给其他人用,比如:视频播放器项目融合型,与业务项目在一起,混合 store,不分你我 我暂时能想到的就这几种类型的组件,如果你的团队也在维护自己的一套组件库,那么应该很容易理解我上面所说的。 我相信,既然这么做了,肯定有这么做的理由和好处,没有人会闲着没事找麻烦做不是,那么这些做法都有什么好处和痛点呢?我从几个方面入手分别分析一下。 方便、快捷 组件嘛,当然是最快能跑起来,最方便能看到效果最好咯。就这点来讲,还有什么比直接在业务项目里撸组件更快的方式吗!? 现在用个展示的面板,立马去 components 目录撸一个。 数据?不是有 store 吗?引入进来不就拿到数据了! 所见即所得,现在改完马上看到页面上的效果!无法反驳.. 这么看确实开发这个组件是好快了,但是从整个业务需求实现来看,这么做真的是最快的吗?如果这样的做法是最快捷的,那为什么那么多团队在强调沉淀、封装、抽象呢? 其实很多组件当时看起来,这辈子就只可能用一次,不用封装。可是往往交互稿过来的时候就会发现,这个样式好像我在哪里见过。然后去各种业务项目里一顿翻,哇终于找到了,复制过来发现各种爆红,定睛一看,store??? 所以,聪明的团队早已洞察这一切,让我们把组件都维护到同一个地方,然后大家写好文档,用的时候从库里面取就可以了,有 Bug 的话统一修复就是,棒 👍! 可维护性 于是乎,大家便如火如荼的开始的组件抽象,组件整改的浩大工程。 一开始,一般会有一个团队中较为靠谱、能力突出的小伙子(嗯?怎么是我?)去把 Webpack、Babel、TypeScript、SassLess、目录结构、单元测试结构、代码规范、Review 规范、发布规范这些梳理好,然后写一个标准的组件出来,最后再强调一下大家一定要按照规范认真维护组件,书写文档,编写单元测试。 从维护性上来讲,大家把组件都写在一个库里面,然后再用到的项目中直接引入,业务上的问题逐渐被分为组件问题还是项目问题,甚至有些需求可以用这个交互在组件库中有相似的,用那个组件就可以了,来反驳产品和设计 😏。 就在大家用的不亦乐乎的时候,有一天发现,呀,我们的组件库怎么打包出来有 10M 啊 😱!

1.数据中心网络架构设计-两地三中心

道友们们大家好;自2012年至今,在网络领域混了将近10年,今天将自己在此领域关于数据中心架构设计分享给各位道友,技术领域无止尽,让我们共同学习,共同探讨,共同进步,不足之处大家多多指点。 一,逻辑拓扑关系 1. internet 代表公网出口 2.本架构共含5个数据中心,办公区运维管理业务发布2个办公区。 二,IDC间链路冗余设计 SLA 99.99% 三,IDC间链路规划(增加一个DB同步节点) 四,业务设计分区 五,IDC南北向流量调度(入) 六,IDC内南北向流量调度(出) 七,IDC内东西向流量调度 八,IDC间流量调度 九,IDC间流量调度2 十,IDC间流量调度3 十一,IDC间流量调度4 十二,IDC间备份线路切换策略(正常) 十三,IDC间备份线路切换策略(故障1) 十四,IDC间备份线路切换策略(故障2) 十五,IDC间备份线路切换策略(故障3) 十六,IDC间备份线路切换策略(故障4)

Python 安装Python-Jenkins 报错No matching distribution found for python-jenkins

1、报错情况 报错原因: 找不到与python-jenkins匹配的分布,pip 安装使用的是外国源镜像,导致获取超时,安装失败,获取不到新版本 解决办法: 切换至 pip 源到国内镜像 2、切换pip源的方法 可以直接通过Pycharm-设置 永久更换 pip 安装源为国内镜像 win+R 打开“运行”,然后输入 %HOMEPATH% 快速访问当前用户目录:C:\Users\lenovo 找到本地用户新建pip文件,在 pip 目录下创建 pip.ini 文件(新建 txt 文件,添加内容,然后修改文件名为 pip.ini), 内容如下: [global] timeout = 6000 index-url = https://pypi.tuna.tsinghua.edu.cn/simple trusted-host = pypi.tuna.tsinghua.edu.cn # timeout 设置超时 # index-url 指定国内镜像地址 # trusted-host 指定国内镜像地址的 host ,即国内镜像地址域名 安装成功

2020“远光杯”网络资格赛L 捕鱼达人(树状数组/区间最大值/单点更新)

题目 门前大桥下,游过一群鱼,小红鱼,黄花鱼,绿草鱼,蓝顶鱼,粉鲳鱼,砂紫鱼,竟然在鱼塘中排成了一条队列,捕鱼达人坤坤打算将他们捕获。但是由于这些鱼比较稀有,坤坤需要在指定的规则下才能抓捕他们,规则如下: 在捕鱼过程中当前捕获的鱼颜值必须大于等于前一条鱼颜值a_i,对于捕获的第一条鱼没有要求。 每一条鱼变身后他的价值b_i为他的颜值的1/10000(整除)。 每一条鱼变身后他的颜值会变成原本颜值对10000的余数,也就是a_i%10000。(例如变身前颜值a_i为20001,则变身后它的价值变为2,颜值变为1)。 所有鱼在一开始的时候就会变身,变身后坤坤才可以开始捕鱼。 鱼群顺序是从左到右排列的,鱼群的顺序是不可变的,坤坤可以从鱼群头或者鱼群尾开始捕鱼,但是顺序必须是从左到右或者从右到左。 坤坤希望他捕获到的鱼的价值最多。 输入要求 第一行先输入一个T(1 <= T <= 10)表示接下去有T组数据 对于每组数据 第一行会有一个n(1 <= n <= 10^4)表示接下来从左到右会有n条鱼。 第二行会有n个数,对于每个数表示这个鱼的颜值为a_i(-6 * 10^4 < a_i < 6 * 10^4)。 输出要求 对于每组数据,输出Case #i: val 表示当前为第i组数据,每次捕鱼获得的最大价值为val。 对于每行输出,最后没有空格,输出后直接换行。 样例输入 5 5 10001 10002 10003 10004 10001 5 50001 10001 10002 10003 10004 5 50001 10002 10003 10004 10005 5 50005 10001 10002 10003 10004 5 -10001 -10002 -10003 -10004 0 样例输出 Case #1: 4 Case #2: 9 Case #3: 9 Case #4: 6 Case #5: 0 代码

计算机视觉——立体图像

文章目录 立体图像一、计算视差图二、双目立体匹配三、NCC算法实验3.1实验要求3.2实验准备3.3实验代码3.4实验结果及分析 四、实验总结 立体图像 一个多视图成像的特殊例子是立体视觉(或者立体成像),即使用两台只有水平(向 一侧)偏移的照相机观测同一场景。当照相机的位置如上设置,两幅图像具有相同 的图像平面,图像的行是垂直对齐的,那么称图像对是经过矫正的。该设置在机器 人学中很常见,常被称为立体平台。 一、计算视差图 归一化相关性,简称NCC,就是用于归一化待匹配目标之间的相关程度,注意这里比较的是原始像素。通过在待匹配像素位置p(px,py)构建n*n邻域匹配窗口,与目标像素位置p’(px+d,py)同样构建邻域匹配窗口的方式建立目标函数来对匹配窗口进行度量相关性,注意这里构建相关窗口的前提是两帧图像之间已经校正到水平位置,即光心处于同一水平线上,此时极线是水平的,否则匹配过程只能在倾斜的极线方向上完成,这将消耗更多的计算资源。相关程度的度量方式由如下式子定义: 上式中的变量需要解释一下:其中p点表示图像I1待匹配像素坐标(px,py),d表示在图像I2被查询像素位置在水平方向上与px的距离。如下图所示: 左边为图像I1,右边为图像I2。图像I1,蓝色方框表示待匹配像素坐标(px,py),图像I2蓝色方框表示坐标位置为(px,py),红色方框表示坐标位置(px+d,py)。 上述公式表示度量两个匹配窗口之间的相关性,通过归一化将匹配结果限制在 [-1,1]的范围内,可以非常方便得到判断匹配窗口相关程度: 若NCC = -1,则表示两个匹配窗口完全不相关,相反,若NCC = 1时,表示两个匹配窗口相关程度非常高。 二、双目立体匹配 假设有校正过的两帧图像I1,、I2,由上述NCC计算流程的描述可知,对图像I1一个待匹配像素构建n*n匹配窗口,在图像I2极线上对每一个像素构建匹配窗口与待匹配像素匹配窗口计算相关性,相关性最高的视为最优匹配。 双目立体匹配流程如下: 采集图像:通过标定好的双目相机采集图像,当然也可以用两个单目相机来组合成双目相机。(标定方法下次再说)极线校正:校正的目的是使两帧图像极线处于水平方向,或者说是使两帧图像的光心处于同一水平线上。通过校正极线可以方便后续的NCC操作。 特征匹配:这里便是我们利用NCC做匹配的步骤啦,匹配方法如上所述,右视图中与左视图待测像素同一水平线上相关性最高的即为最优匹配。完成匹配后,我们需要记录其视差d,即待测像素水平方向xl与匹配像素水平方向 X r Xr Xr之间的差值 d = X r − X l d = Xr - Xl d=Xr−Xl,最终我们可以得到一个与原始图像尺寸相同的视差图D。深度恢复:通过上述匹配结果得到的视差图D,我们可以很简单的利用相似三角形反推出以左视图为参考系的深度图。计算原理如下图所示: 如图, T x Tx Tx为双目相机基线, f f f为相机焦距,这些可以通过相机标定步骤得到。而 X r − X l Xr - Xl Xr−Xl就是视差 d d d。通过公式 z = f ∗ T x d z = \frac{f*Tx}{d} z=df∗Tx​可以很简单地得到以左视图为参考系的深度图了。 三、NCC算法实验 3.

NC57 登录报错--该账套已过期!

NC57 登录报错–该账套已过期!如图: 解决办法: 在账套里选择【系统管理】,用户填【root】,不用填密码,登录。 然后在【账套管理】选择对应的账套修改【失效日期】即可

通过WinPE卸载补丁,解决因安装补丁电脑蓝屏、无法开机等问题

安装windows安全补丁后,开机修复不成功,或者蓝屏,可以尝试以下解决方案 使用PE里面的dism工具卸载近期安装的补丁 WinPE进入系统以后 进入PE后,点击“开始” 》 “磁盘光盘” 》 Dism++ 运行 在顶部选择硬盘内安装的系统,并点击“打开会话” 选择“更新管理”,并点击“安装日期”来排序 勾选上一次安装的补丁后,点击“删除” 删除完毕后重启电脑,即可卸载补丁

7.zabbix网页汉化

一. zabbix网页默认似使用英文 1.如果英文熟悉的话建议直接用英文 2.把Admin用户改成中文的 二. zabbix默认的字段问题 1.中午会有部分乱码情况 2.监测->图形的监控图形会有乱码的产生 三. 解决zabbix部分乱码 1.C:\Windows\Fonts 2.zabbix字体的放置目录: /usr/local/nginx/html/zabbix/fonts/ 3.上传微软雅黑字体 4.zabbix网页的字体配置修改 /usr/local/nginx/html/zabbix/include/defines.inc.php 5.默认是DejaVusan字体,改成msyh微软雅黑字体 6.验证中文是否正常

Ansible的简介及部署

1. ansible简介 1.1 什么是ansible ansible是一款开源自动化平台,是一个配置管理工具,自动化运维工具 1.2 ansible的优点 跨平台支持人类可读自动化: ansible提供linux,Windows,unix和网络设备的无代理支持,适用于物理、虚拟、云和容器环境完美描述应用:playbook轻松管理版本控制:playbook是纯文本,可视作源代码支持动态清单编排可与其他系统轻松集成:puppet、jenkins基础架构即代码减少人为错误 运行playbook时,如果目标主机处于正确状态,则不会进行任何更改。 1.3 安装ansible 1. 在虚拟机上安装ansible,充当控制节点 yum install -y ansible 2. 查看ansible版本信息 ansible --version 3. 使用setup模块验证python ansible localhost -m setup | grep python_version 2. 部署ansible 2.1 构建ansible清单 清单:定义了ansible将要管理的一批主机 2.1.1. 静态清单 注:如果填写的是主机名,请确保可以解析主机名(/etc/hosts) 每行一个,填写主机名或ip,如: 还可以定义主机组: 注:一台主机可以存在于多个主机组' 2.1.2 定义嵌套组 ansible主机清单可以包含多个主机组构成的组,如: 2.1.3 通过范围简化主机规格 可以指定主机名称或ip范围或者数字和字母范围 2.1.4 验证清单 ansible all --list-hosts 2.1.5 默认清单位置 /etc/ansible/hosts #一般不使用,而是自己新建 2.1.6 动态清单 可以从开源社区的脚本中获取 练习: 列出清单中所有受管主机 ansible all --list-hosts 列出不属于某个组的主机 ansible ungrouped --list-hosts 列出属于webservers组的主机

SQL中判断奇偶数的方法

查询ID是奇数的记录 “JIOUSHU”表: SELECT * FROM JIOUSHU WHERE ID%2 != 0; #适用于Mysql、SQL Server SELECT * FROM JIOUSHU WHERE ID&1; #适用于Mysql SELECT * FROM JIOUSHU WHERE MOD(ID,2) = 1; #适用于Mysql 练习题: 有如下一张表T 希望用SQL 将每列数据中存在奇数的数据统计出来,结果如下: Solution: ----建表 if object_id('T','U') is not null drop table T Create table T( IP int, NUM1 int, NUM2 int, NUM3 int ) Insert INTO T VALUES (1,3333,4442,221); Insert INTO T VALUES (2,65,24,96); select * from T --查询 select *,case when NUM1 % 2 = 1 then 1 else 0 end + case when NUM2 % 2 = 1 then 1 else 0 end + case when NUM3 % 2 = 1 then 1 else 0 end as 奇数个数 from T

C语言画图形(图形库graphics的使用)

目录 工具 c语言基本绘图 文字输出 c语言基本贴图 获取鼠标、键盘信息 工具 (1)环境:VC++ (2)库函数:graphics.h(因为不是标准库函数,所以需下载EASYX) (3)编译软件:VS、VC++6.0 c语言基本绘图 本节目录:窗口的创建及背景颜色、基本绘图函数(点、线、圆、矩形以及设置其属性) #include <stdio.h> #include <graphics.h>//图形库 #include <time.h>//时间库函数 int main(){ //注意窗口的横纵坐标原点是左上角 (1)窗口的创建及背景颜色 ①窗口的创建 initgraph(int width,int hight);//创建窗口 closegraph();//关闭窗口 ②设置背景颜色 setbkcolor(RED);cleardevice();//参数可以为颜色的英文,记住需要刷新窗口才能显示设置后的颜色 setbkcolor(RGB(int x,int y,int z));cleardevice();//或者可以调制三原色,记住需要刷新窗口才能显示设置后的颜色 (2)基本绘图函数 ①绘点 putpixel(int x,int y,color color);//参数为横纵坐标和颜色 //如何随机生成点呢 #include <time.h> srand((unsigned int)time(NULL));//设置随机点的种子 int x = rand()%n;//rand()是生成随机数,然后对n取余,则得到的所有的x值都小于等于n int y = rand()%n; putpixel(x,y,color); ②绘线 line(int x1,int y1,int x2,int y2);//两点确定一条直线 //如何设置线的属性呢(注意必须写在画线函数的前面) setlinecolor(color color);//参数可以是颜色,也可以是三原色 setlinestyle(linestyle linestyle,int width);//参数linestyle可以点进去库函数查看,可以设置虚线、直线....,width是线的宽度 ③矩形 rectangle(int x1,int y1,int x2,int y2);//两点确定一个矩形 ④圆 circle(int x,int y,int r);//圆心的横纵坐标和圆的半径 ⑤填充(实心填充(不渲染边的颜色)、全部填充) //圆的填充 setfillcolor(color color);//先设置填充颜色 //全部填充 fillcircle(int x,int y,int r);//参数横纵坐标和半径 //实心填充 solidcircle(int x,int y,int r); //矩形的填充 略 } 文字输出 #include <stdio.

牛顿迭代法-matlab实现

牛顿迭代法-matlab实现 牛顿迭代法简介: 牛顿迭代法又称为切线法,简单来说就是不断求切线与x轴的交点,来逐渐接近解的迭代过程。方法使用函数f(x)的泰勒级数的前面几项来寻找方程f(x) = 0的根。具体迭代的方法可以看度娘的解释,或者相关的教材。今天来介绍下简单的matlab的实现。 代码实现: 使用了三个.m文件来实现,分别是原函数(需要迭代的函数)文件、牛顿迭代函数文件、和实现的主文件。 1.原函数的输入: function y = newton(x) y = exp(-x/4)*(2-x)-1;%任意函数 end %function的自定义函数用来保存咱们要进行牛顿迭代的函数 2.牛顿迭代函数: 把你要进行牛顿迭代的函数进行变化,变成牛顿迭代函数。先要了解牛顿迭代函数的基本格式, 牛顿迭代公式: **𝝋 (𝒙) = 𝒙 − 𝒇 𝒙 𝒇′** 代码:` function y = newton1(x) syms a; f = a - (newton(a)./diff(newton(a))); y = subs(f,x);%牛顿迭代公式 end %如果直接用y和x来实现的话,在掉用原函数的时候就算出了具体数值,公式中的求导就会变为0, 无法求解,所以先用f,a来代替y和x,最后再进行替换,实现牛顿迭代公式。 3.主程序(进行牛顿迭代) 代码: x = input('x=');%开始迭代最初的x eps = input('eps=');%定义所要求解的精度 syms x1;%定义两Xk+1和Xk的差,一次来限制精度的要求 x1=100; syms xa; xa=x; syms xb;%记录上一个x和下一个x while x1>eps xb = xa; xa = newton1(xb); x1 = abs(xa-xb);%得到▲x end disp('该函数符合规定精度的解是:'); double(xa) xa即为所求的值 总结: 代码用来限制精度的方面只是简单的用前后两次的x进行做差来限制,还有很多不足,有时候是不成立的,像这两次的x误差很小,但是第三个x的时候开始发散,那xa所求的就不是正确答案,牛顿迭代法也有很多的限制,例如开始迭代的x如果取得不好也无法实现迭代过程,求最开始的迭代x值,可以结合二分法迭代来解决,进一步缩小有根区间,在进行牛顿迭代,代码可能还有很多不足和错误,欢迎大家指正。

2020年“远光杯”粤澳计算机程序设计大赛网络资格赛------D.分三排

题目: 体育课上,学生如果站成一排上课会造成很大的麻烦,现在按照1、2、3的办法报数,报数1的前进2步,报数2的前进1步,报数3的原地不动,假设刚开始的时候同学们是按照学号站成一排,那么你能输出分成三排后同学的学号么? 输入要求: 第一行包括一个整数n,表示班级里有n位学生,班级人数至少是1,不超过100。 第二行包括n个整数,表示站成一排时每个同学的学号。 输出要求: 请按顺序输出分开三排后每排每位同学的学号,用空格隔开(每排最后同学后没有空格)。 排好队后,同学站成三排,报1的同学在第1排。 每排队伍的输出格式:同学空格同学空格…同学换行 输入输出: 简单介绍: 题目:分三排 使用语言:C++。 这道题来自2020年“远光杯”粤澳计算机程序设计大赛网络资格赛。 解题思路: 首先看题、分析题意,我们可以明1个关键点: 1.保存报数1,2,3的学生 既然,我们已经分析出来题目的关键任务了,下面我们就可以开始思考实现了。 我们采用算法与数据结构的思路来剖析一下这题 数据结构: 要实现对数据的操作,我们要先明确存储数据的数据结构。 该题的数据结构的作用,保存学生的学号。 在这里我们采用三个容器来保存学生的学号 算法: 既然明确了容器作为解决该题的数据结构,我们就可以开始我们的算法分析了。 该题的算法主要实现学生的顺序存入容器 1.for循环1遍,因为数组是从零开始的,我们用i%3==0代表第1个,第4个…喊口号的同学 代码部分: #include<iostream> #include<vector> using namespace std; void show(vector<int> s); int main() { int n;//n位学生 int stu[100];//学生数组 vector<int> s1,s2,s3;//1,2,3排学生 cin>>n; for(int i=0;i<n;i++){ cin>>stu[i]; } for(int i=0;i<n;i++){ if(i%3==0)s1.push_back(stu[i]);//报数1 else if(i%3==1)s2.push_back(stu[i]);//报数2 else s3.push_back(stu[i]);//报数3 } show(s1); show(s2); show(s3); return 0; } void show(vector<int> s) { for(int i=0;i<s.

面向对象四大特性

面向对象四大特性:封装、抽象、继承、多态 封装:封装也叫作信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式来访问内部信息或者数据。它需要编程语言提供权限访问控制语法来支持,例如 Java 中的 private、protected、public 关键字。封装特性存在的意义,一方面是保护数据不被随意修改,提高代码的可维护性;另一方面是仅暴露有限的必要接口,提高类的易用性。 抽象:封装主要讲如何隐藏信息、保护数据,那抽象就是讲如何隐藏方法的具体实现,让使用者只需要关心方法提供了哪些功能,不需要知道这些功能是如何实现的。抽象可以通过接口类或者抽象类来实现,但也可以并不需要特殊的语法机制来支持。抽象存在的意义,一方面是提高代码的可扩展性、维护性,修改实现不需要改变定义,减少代码的改动范围;另一方面,它也是处理复杂系统的有效手段,能有效地过滤掉不必要关注的信息。 继承:继承是用来表示类之间的 is-a 关系,Java 语言是单继承的。继承主要是用来解决代码复用的问题。 多态:多态是指子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。Java 语言通过继承、接口类的方式来实现多态。多态可以提高代码的扩展性和复用性。

K8S 完美搭建的家庭云运算中心

需求 一台笔记本(4C8G),一台台式机(12C 32G),后面公司马上又要退役下来两台笔记本。还有自己买的游戏本,这些闲置机器也是吃灰,想着把它利用起来。如何把它联接起来也是一个事情?现在这种硬件资源管理器也是Yarn、Mesos、K8S之流。 Mesos没有接触过,也没怎么听说过,passYarn的话一个是界面太丑,上CDH成本太高,一个CM就大的要是,二是不支持微服务、中间件。K8S 看了比较完美,也支持大数据平台的部署(Docker),也支持微服务、中间件的部署(Docker),支持Docker集群。 (没用过,实践发现K8S的镜像占用资源贼小) 设计 首先把所有机器通过交换机进行连接,目前买的是4口的交换机,等所有电脑退役了后续需要升级。K8S平台安装,将笔记本作为主机,因为它24小时不间断运行。Harbor作为私有云镜像中心NextCloud作为家庭网盘中心,同步视频、照片和一些文档备份大数据套件: Hadoop体系 + Flink 流式处理 + Hue中间件:Redis、Kafka、Mysql、Zk、FastDFS等搜索与日志:ELKNginx作为主入口配置。 实现 搭建K8S集群 https://blog.csdn.net/u013076044/article/details/105568896搭建Harbor https://blog.csdn.net/u013076044/article/details/105543100搭建ELK-EK

linux虚拟机网络配置之桥接模式

环境:vmware workstation上安装的centos 6.5 说明:在虚拟机上安装好centos 6.5之后,是没办法连接网络的,你没办法通过ssh工具、ftp工具在本地连接上自己安装的虚拟机,也更别想通过虚拟机访问internet外部网络,怎么办呢?下面介绍三种配置网络使之联通的方法。 前提:选择网络连接方式为桥接,所谓桥接模式,就是指该虚拟机就被当做跟你安装虚拟机的电脑(宿主机器)在同一个局域网的真实机器一样,你就把这种模式下的虚拟机当做另外一台真实的电脑就可以了。 桥接模式的优缺点: 优点:桥接模式的网络配置好之后,宿主机器和虚拟机因为是在一个局域网,因此它们之间是可以互相访问的,而且虚拟机也可以访问外网。 缺点:当局域网的机器比较多时,比如在公司里面,你这里给虚拟机设置的ip可能会与其他人的ip冲突,导致你测试的问题达不到预期的效果,我是真吃过这方面的亏呀,因此在给自己的虚拟机通过桥接方式设置ip之前,一定要确保该ip没有被使用。 1.临时配置,所谓临时配置就是指的是我这次配置好了网络,关机重启后还要重新配置,使用ip addr命令查看一下使用的网卡: 我现在通过宿主机器肯定连不上虚拟机的,因为我的虚拟机都没有设置ip呢,肯定连接不上: 上面看到虚拟机使用的网卡是eth0,好,知道了网卡就可以配置这个网卡了,命令如下: ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up #设置ip和子网掩码,注意不要和局域网内的电脑的ip冲突了 当然了,我这里设置的ip为"192.168.1.100",是因为我自己的机器ip地址是"192.168.1.101",子网掩码是255.255.255.0,我只要设置的和192.168.1.101在同一网段(根据子网掩码的值可以知道,只要前3段相同,即192.168.1就是在同一网段了)并且不和其他机器冲突就行了,你设置的时候要根据自己的网段来设置,这是啰嗦了一下,如果不太懂网段这些概念,自己去百度吧。这时候能和局域网内地机器通信了吗?看看结果: 遗憾的是,通过上面的命令只能实现跟本地局域网内的通信,并不能上外网: 这时候还需要设置一下网关才能上外网: route add default gw 192.168.1.1 #网关就是你访问你自己路由器的网址,通过你在自己电脑上执行ipconfig都可以看到 依然是眼见为实吧: 2.千辛万苦终于配置好了,一个reboot就让你回到了解放前,开不开心?不要不开心,这没什么大不了,有那种一劳永逸的永久配置,也就是我前面说的第二种方法了,这种方法需要修改网卡的配置文件,文件位于/etc/sysconfig/network-scripts/ifcfg-eth0,当然了,如果你的网卡是eth1,那么你就应该去配置/etc/sysconfig/network-scripts/ifcfg-eth1了。打开这个文件发现内如如下: DEVICE=eth0 HWADDR=00:0C:29:09:4D:E6 TYPE=Ethernet UUID=64d534c1-a9d9-487f-a8b8-3ac1ce13d169 ONBOOT=no NM_CONTROLLED=yes BOOTPROTO=dhcp 修改如下: DEVICE=eth0 HWADDR=00:0C:29:09:4D:E6 TYPE=Ethernet UUID=64d534c1-a9d9-487f-a8b8-3ac1ce13d169 ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=static IPADDR=192.168.1.100 NETMASK=255.255.255.0 GATEWAY=192.168.1.1 DNS1=10.139.1.2 DNS2=10.139.1.3 保存之后,还要重启网络服务才可以使配置生效,怎么重启网络服务?命令: service network restart 至此呢,虚拟机就可以上网啦。 说明:上面配置文件里面的各个项是什么意思呢?我在这里给大家解释一下,也给自己做个备忘录: DEVICE=eth0 #本配置文件针对的是哪个网卡 HWADDR=00:0C:29:09:4D:E6 #网卡设备MAC地址 TYPE=Ethernet #网卡类型 UUID=64d534c1-a9d9-487f-a8b8-3ac1ce13d169 ONBOOT=yes #本配置文件是否在计算机启动的时候被加载,当然需要被加载了,不然我配置干嘛 NM_CONTROLLED=yes BOOTPROTO=static #有dhcp和static两个值,dhcp就是让计算机自动分配ip地址,也可以。static就需要自己知道ip地址了

你一定要了解的Kubernetes

前言 随着容器技术的发展,Docker近几年突然崛起,变得炙手可热,已经成为容器技术的事实标准。然而想要在生成环境中成功部署和操作容器的关键是容器编排技术,市场上有各种各样的容器编排工具(如Docker原生的Swarm),其中谷歌公司开发的Kubernetes得到开源社区的全力支持,IBM、惠普、微软、RedHat等业界巨头纷纷加入,Kubernetes已经成为GitHub上的明星开源项目。 简介 Kubernetes这个名字源于希腊语,是舵手的意思,所以它的Logo既像一张渔网,又像一个罗盘。有意思的是Docker的Logo为驮着集装箱在大海上遨游的鲸鱼,Kubernetes与Docker的关系可见一斑。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mvXVtVZH-1587721676743)(https://img-blog.csdn.net/20180116211103919?)] Kubernetes(也常称K8s,用8代替8个字符“ubernete”而成的缩写。)是一个全新的基于容器技术的分布式架构方案,它源自Google内部大规模集群管理系统——Borg,也是CNCF(Cloud Native Computing Foundation,今属Linux基金会)最重要的项目之一,旨在让部署容器化的应用简单并且高效。 Kubernetes 具备完善的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建负载均衡器、故障发现和自我修复能力、服务滚动升级和在线扩容、可扩展的资源自动调度机制、多粒度的资源配额管理能力。还提供完善的管理工具,涵盖开发、部署测试、运维监控等各个环节。 Kubernetes 于2015年7月22日迭代到 v 1.0并正式对外公布,截至2018年1月5日稳定版已经发布到 v.1.9.1。无论是英文还是中文社区都非常活跃,全球开源解决方案领导者 RedHat 公司已经将自己Paas产品OpenShift V3 的底层技术换成了Kubernetes与Docker。Kubernetes俨然已经成为全新容器生态的领导者。 架构 Kubernetes使用Go语言开发,集群采用 Master/Node(最初称为Minion,后改名Node) 的结构,Master(主节点)控制整个集群,Node(从节点)为集群提供计算能力。用户可以通过命令行或者Web页面的方式来操作集群。 Master是Kubernetes集群的大脑,负责公开集群的API,调度部署和管理整个集群。集群至少有一个Master节点,如果在生产环境中要达到高可用,还需要配置Master集群。 Master主要包含API Server、Scheduler、Controller三个组件,需要etcd组件来保存整个集群的状态。 **etcd:**由CoreOS开发,是一个高可用、强一致性的服务发现存储仓库,为Kubernetes集群提供存储服务,类似于zookeper。 API Server: kubernetes最重要的核心组件之一,提供资源操作的唯一入口(其他模块通过API Server查询或修改数据,只有API Server才直接操作etcd),并提供认证、授权、访问控制、API注册和发现等机制。 **Scheduler:**负责资源的调度,按照预定的调度策略将Pod(k8s中调度的基本单位)调度到相应的Node上。 **Controller:**通过API Server来监控整个集群的状态,并确保集群处于预期的工作状态,比如故障检测、自动扩展、滚动更新等。 Node是Kubernetes集群的工作节点,可以是物理机也可以是虚拟机。Node需要包含容器、kubelet、kube-proxy等组件。Fluentd用来提供日志收集功能(可选)。 **kubelet:**维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理。每个节点上都会运行一个kubelet服务进程,接收并执行Master发来的指令,管理Pod及Pod中的容器。每个kubelet进程会在API Server上注册节点自身信息,定期向Master节点汇报节点的资源使用情况,并通过cAdvisor监控节点和容器的资源。 kube-proxy: 为 Service 提供集群内部的服务发现和负载均衡,监听 API Server 中 service和endpoint的变化情况,并通过iptables等方式来为服务配置负载均衡。 Docker: 每台Node上需要安装Docker来运行镜像,但是Docker不是唯一选择,Kubernetes支持多种容器,比如CoreOS公司的Rkt容器(之前称为Rocket,现更名为Rkt)。 资源对象 API对象是Kubernetes集群中的管理操作单元。集群中的众多技术概念分别对应着API对象,每个API对象都有3大类属性: metadata(元数据):用来标识API对象,包含namespace、name、uid等。 spec (规范):描述用户期望达到的理想状态,所有的操作都是声明式(Declarative)的而不是命令式(Imperative),在分布式系统中的好处是稳定,不怕丢操作或运行多次。比如设置期望3个运行Nginx的pod,运行多次也还是一个结果,而给副本数加1的操作就不是声明式的,运行多次结果就错了。 status(状态):描述系统当前实际达到的状态,比如期望3个pod,现在实际创建好了2个。 在Kubernetes众多的API对象中,Pod是最重要的也是最基础的,是kubernetes中可以创建的最小部署单元。Pod就像是豌豆荚一样,它可以由一个或者多个容器组成,这些容器共享存储、网络和配置项。 目前Kubernetes中的业务类型可以分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-daemon)和有状态应用型(stateful application)这四种类型,而这四种类型的业务又可以由不同类型的Pod控制器来完成,分别为:Deployment、Job、DaemonSet和StatefulSet。 Deployment: 复制控制器(Replication Controller,RC)是集群中最早的保证Pod高可用的API对象,副本集(Replica Set,RS)是它的升级,能支持更多种类的匹配模式。部署(Deployment)又是比RS应用模式更广的API对象,以Kubernetes的发展方向,未来对所有长期伺服型的的业务的管理,都会通过Deployment来管理。 Service: Deployment保证了Pod的数量,但是没有解决如何访问Pod的问题,一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。要稳定地提供服务需要服务发现和负载均衡能力,Service可以稳定为用户提供服务。 Job: 用来控制批处理型任务,Job管理的Pod根据用户的设置把任务成功完成就自动退出了。 DaemonSet: 后台支撑型服务的核心关注点在集群中的Node,要保证每个Node上都有一个此类Pod运行。比如用来收集日志的Pod。 StatefulSet: 不同于RC和RS,StatefulSet主要提供有状态的服务,StatefulSet中Pod的名字都是事先确定的,不能更改,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂载上原来Pod的存储继续以它的状态提供服务。比如数据库服务MySQL,我们不希望一个Pod故障后,MySQL中的数据即丢失。

GIS技术在水资源领域的应用与发展

地理信息系统(GIS)是以计算机为基础的综合处理和空间数据分析系统,是集计算机科学、管理科学、信息科学、地学等为一体的新兴边缘研究领域。20世纪70年代,美国田纳西河流域管理局利用GIS技术处理分析各种流域数据,为流域管理和规划提供决策服务,GIS便开始逐渐应用于水文水资源领域。80年代后随着计算机技术的飞速发展,GIS与水文水资源领域也有了广泛结合。 1 应用进展 1.1 在水资源评价和规划中应用 水资源评价和规划中涉及大量的空间信息,如行政区划、河流水系、地形地貌、水利工程分布、水文站控制断面位置以及人口、实测水文数据等属性数据,GIS可以支持这些具有明显的时维性数据的获取、管理、分析、模拟及显示。 根据大汶河流域水资源量的形成、多少及分布受地形地貌、植被等下垫面要素和降水量的影响等特点,利用GIS建立了水资源计算与评价模型;探讨了如何将GIS技术应用到淮海流域的水资源综合规划中。此外,近年GIS技术在我国水环境质量评价与规划中也得到了越来越广泛的应用, 在国外,Gupta等早在1977年就实现了将栅格型GIS数据管理工具用于流域规划。随后欧洲一些研究机构也联合开发了具有水文过程模拟、水污染控制、水资源规划等功能的流域规划决策支持系统“WATERWARE”。近年Carlo等在GIS平台上开发了Ag-PIE模型,用于评价由于农业生产造成的地表和地下水水质下降的程度。 1.2 在区域水资源管理中的应用 在GIS基础上建立的水资源管理信息系统,可为水资源管理提供迅速而全面的信息支持。以MapInfo为开发平台,将全国河流水系、水文站网、行政区划和重要城市等地理要素集成为一个整体,建立了全国水文站网管理信息系统,为优化水文站网和提高站网管理水平提供了信息支撑。GIS在灌区水资源管理中也得到了广泛应用,建立了辽宁省农田水利管理信息系统,改善了辽宁省农田水利的管理等。 自20世纪70年代美国田纳西河流域管理局利用GIS技术处理和分析各种流域数据,开始为流域管理提供决策服务以来,GIS技术亦广泛应用于国外的水资源管理中。如美国科罗拉多州的一些机构联合开发了科罗拉多河决策支持系统,GIS被用于流域空间的存储、检索、分析和显示,以便于科罗拉多河水资源的管理。在灌区的水资源管理方面,位于美国德克萨斯州Lower Rio Grande Valley的8个灌区较早地开发以GIS为基础的灌区管理系统(DMS)。 1.3 在防洪减灾中的应用 GIS技术可以作为防汛决策支持系统或信息管理系统的平台,并在此基础上进行灾情评估和洪涝灾害风险分析。我国一些科研部门和流域水管理机构先后将GIS技术应用于防洪决策支持系统和洪水灾情评估系统的开发,部分省份和城市相应建立了基于GIS的城市防洪决策支持系统。此外,基于GIS的洪水演进模拟已在我国许多单位研制成功,技术也相当成熟。 在国外,Davis曾将HEC-1、HEC-2与 GIS结合对洪水、水质和土坡侵蚀进行了模拟,可很好地用于洪灾损失评估。 1.4 在水环境监测和水资源保护中的应用 GIS技术为水循环监测和区域水资源保护管理和决策提供了方便、直观和科学的工具,管理者可通过资料查询分析水质变化特点和未来趋势并了解方案实施效果,特别是当污染事故发生时借助GIS能迅速模拟预测污染物未来的时空分布特征,从而为迅速采取应急措施提供决策依据。在国内,上海市环境管理部门于20世纪80年代末开始GIS的应用研究,建立了黄浦江流域水环境GIS,该系统具有动态监测显示、水污染过程模拟及取水口水环境管理功能,可对水质做出快速预测分析和预报。此后国内不少学者基于GIS进行水质监测和水资源保护方面的研究,如何进朝等建立了水质动态管理信息系统,实现了水质监测、实时数据处理、水质评价和预测、系统维护等功能;张俐等以GIS数据为基础进行一维恒定流方程组和二维水质模型计算,实现了浓度场在GIS平台上的可视化;秦福来等在GIS和非点源污染模型SWAT的技术支持下,对DEM在非点源污染研究中的应用进行了有益的探讨。 在国外,为了支持各种层次的水资源和水环境管理,美国国家环保局基于GIS技术和地调局水文数据开发了全美河段文件。He等将AGNPS、GRASS与GRASS Water Works模型集成在一起,综合评价了非点源污染对美国密歇根州Cass河水质的影响,近年来,Boyle等建立的IDOR2D系统将水污染模型与GIS集成。 1.5 在水文模拟中的应用 基于GIS的数字地形模型(DTM)和数字高程模型(DEM)存储的地形信息为流域水系统信息参数的自动化提取提供了可能。通过GIS提取流域特征,不仅可以使GIS与传统的概念性水文模型相结合,更重要的是其为物理性分布式水文模型的研制提供了平台。 国外的分布式水文模型起始于1969年,比较著名的有TOPMODEL、SHE、IHDM模型和美国农业部的SWAT模型,目前得到了长足发展并在多个地区进行了实践和应用。近年出现的基于不规则三角网格(TIN)构建出得完全分布式模型,只需原始栅格节点的5%~10%就可以充分描述流域地形的水文特征,大大提高了分布式模型的计算效率,为大型流域的水文模拟提供了可能,是今后分布式水文模型研究的热点。国内的分布式水文模型研究起步较晚,沈晓东等在研究降雨和下垫面自然地理参数空间分布的不均匀性对径流过程的影响基础上,提出一个动态分布式降雨径流流域模型,实现了基于栅格DEM的坡面产汇流与河道汇流的数值模拟;郭生练等建立了一个基于DEM的分布式流域水文物理模型,用来模拟小流域的降雨径流时空变化过程;任立良等考虑了流域空间的变异性,基于DEM建立了参考作物蒸散量的分布式模型;李兰等在提出的变动生态产流模式的概念基础上建立了LL-I分布式降雨径流模型,能明显改善模拟预报精度,适合不同水文特征地区的产汇流计算 当前GIS技术已逐步应用到了水文水资源领域的各个方面。除以上五个方面外,GIS技术还在水利工程移民安置、旱情分析预测、库区地质分析等多方面得到成功的应用。 2 发展趋势与展望 2.1 加强GIS应用规范和标准的研究 在实际操作中,GIS的应用和开发基本上是各部门根据具体的生产和科研需要而独立开发的。由于缺乏一个完整的技术规范和标准,开发平台、数据格式的多样化给信息交流与共享带来了较大的困难。在国内,尽管行业规范的试点工作已经开始,但仍然存在与国家规范保持一致的问题,因此应加强GIS应用规划和标准研究。 2.2 建立水文水资源地理空间数据库 空间数据库是系统的核心、决策的基础,因而必须在加强GIS应用标准化、规范化的基础上大力开展基础数据库德建设,尤其是具有水文水资源领域特色的数据库,如雨情和水情数据库、水旱灾情数据库、蓄滞洪区空间展布式社会经济数据库等。此外,数据库还要包括流域流域内自然资源和社会经济环境的基本数据。数据库的数据采集要保持全面、准确,并及时更新。 2.3 建立水文水资源空间决策支持系统 空间决策支持系统(SDSS)是近年来在常规决策支持系统和GIS相结合的基础上发展起来的一种新型信息系统。由于其开发难度大,需要大量的人力和财力,必须集中财力保证重点,分布实施,成熟后再予以推广,就我国当前状况来看,长江和黄河的防洪决策支持系统以及黄河的水资源调度系统是当务之急,应该优先建立并逐步完善。 2.4 GIS与水文水资源专业模型的融合 在目前的一些水文水资源专业模型中,尽管大多数GIS对水文水资源信息具备了较强的数据存储、管理和输入输出功能,但其主要是以数据为中心,在表达水文地理空间、水文现象空间分析和支持决策的能力方面还远远不够,尤其体现在基于GIS、RS的分布式水文模型中。如何将现有的各类计算方法和软件逐步过渡到以栅格为计算空间数据管理功能,实现水文水资源专业模型与GIS的集成,是今后的研究重点。 2.5 水文水资源领域要求GIS向多维方向发展 由于水文水资源变化过程具有明显的时空动态特征,所以需要开发能实现三维和四维空间分析和显示等功能的GIS软件。目前只有少量的GIS软件可以进行真三维的分析,如IVM、SGM、GRASS系统等,但它们在几何建模和分析功能上存在不足。随着计算机与空间技术的进步以及水文水资源领域的发展要求,GIS将由独立的系统走向兼容与集成,从二维走向多维。 3 结语 GIS的应用促进了水文水资源领域的发展,反过来,水文水资源领域对GIS的需求又加快了GIS的更新换代,水文水资源、地理信息系统随着技术的进步和社会需求的变化,其含义也会发生相应的变化。“数字水利”的提出,以及工程水利向资源水利、传统水利向现代水利和可持续发展水利的转变,水利信息化是必由之路,可见GIS与水文水资源研究紧密结合的应用前景将十分广阔。

1. Elastalert-设计规则

1.告警规则配置文件 # (Optional) # Elasticsearch host # es_host: elasticsearch.example.com es_host: 1.65.17.102 # (Optional) # Elasticsearch port # es_port: 14900 es_port: 9200 # (OptionaL) Connect with SSL to Elasticsearch #use_ssl: True # (Optional) basic-auth username and password for Elasticsearch #es_username: someusername #es_password: somepassword # (Required) # Rule name, must be unique name: OSPF_LAST_NBR_DOWN(最近一次邻居down) # (Required) # Type of alert. # the frequency rule type alerts when num_events events occur with timeframe time

Games101课程笔记_lecture22_欧拉视角、拉格朗日视角与物质点法

Games101课程笔记_lecture22_欧拉视角、拉格朗日视角与物质点法 1 Single Particle Simulation1 常微分方程:ODE2 Euler's Method欧拉方法3 解决不稳定的方法1 中点法2 Adaptive Step Size3 隐式欧拉方法4 Runge-Kutta Familie图形学要使用的课程 5 Position-Baseed / Verlet Intergration 2 Rigid Body Simulation刚体仿真3 Fluid simulation1 拉格朗日方法和欧拉方法2 物质点方法 4 视频5 总结下一步怎么学 实时渲染和离线渲染 1 Single Particle Simulation 速度场: 任何一个位置任何时间知道这个点的速度。 1 常微分方程:ODE 2 Euler’s Method欧拉方法 上一个位置有个位置,速度,加速度 上一帧的位置+上一帧的速度*一帧的时间 所有的量都用上一帧的, 问题是:非常不稳定。 存在下面两个问题: Euler method error欧拉误差 不稳定性 一定会离开这个螺旋桨的速度场,取步长后粒子肯定会出去。 欧拉方法肯定有误差并且不稳定;大家都在解决这个不稳定性。 Diverge. 3 解决不稳定的方法 1 中点法 核心是用的欧拉方法 第一次得到中点的读速,第二次使用 a点是一般欧拉方法算出来的 c点是中点法算出来的 模仿出来了一个抛物线,原本的欧拉方法上加了个局部的二次模型。 2 Adaptive Step Size 把时间考虑的再短点,每次跑一半的时间。

5.logstash采集 API 对接

1 概述 logstash日志采集系统对MonitorAgent采集到的的主机日志数据进行处理,上报到gateway监控集群,通过监控指标进行数据的查询。 2 上报的指标信息 2.1 URI POST api/objs/monitor/gateway/receive 2.2 参数信息 请求参数 名称 类型 是否必须 描述 name string 是 指标名称 fields map[string]interface{} 是 指标数据点(字典) tags map[string]string 是 指标tag(字典) type string 是 指标类型(GAUGE/COUNTER) timestamp int64 是 unix时间戳(精确到毫秒,13位),多次测试上报时间戳必须依次递增,否则无法上报成功 dStore uint8 是 上报指标转发后端(storage,alerting)(默认0,转发到所有后端) 0: 转发到storage,alerting(兼容旧的逻辑) 1: 一个都不转发 2:两个都转发 4:只转发到storage 8:只转发到alerting 16: 只转发到Aplugin 20: 转发到storge和Aplugin tags参数 tags 值 描述 ip 100.73.18.12 主机地址 tenant nerv 租户信息 region cn_hb_1 地域信息 project_id 12 项目id 返回参数 名称

4. Logstash 系统服务设备日志格式 API 对接

input { file { path => ["/root/nerv-app/nerv-rds/log/*.log"] } } filter { grok{ // 自定义grok,如果日志中有时间,将匹配结果存入log_timestamp,其余字段,存入[log_content][*]下 match => { "message" => "time=\"%{NOTSPACE:log_timestamp}\" level=%{NOTSPACE:[log_content][level]} msg=\"%{GREEDYDATA:[log_content][msg]}\" file=\"%{NOTSPACE:[log_content][file]}\""} } mutate { remove_field => ["host", "path", "tags", "@version"] // 删除无用字段,由于需要删除tags,grok必须放在该mutate上面,因为如果没有匹配成功,会生成_grokparsefailure的tag,其他会生成tag的,也一同放在该mutate上面 rename => { "message" => "[log_content][message]" } // 如果不需要保留原始采集日志,请删除此行 add_field => {"region" => "cn_hb_01"} // 地域 add_field => {"zone" => "cn_hb_01_xy"} // 可用区 add_field => {"service_type" => "nerv-rds"} // 服务类型 add_field => {"service" => "nerv-rds"} // 服务名称

3. Logstash 网络设备日志;输入-格式化-输出

================================================================= 1. 日志输入接口 input{ # 输入接口 udp{ #启用UDP协议 type => "syslog" # 类型为syslog host => "100.76.37.69" # 本机对外服务器IP地址 port => 514 # 启用UDP 514 端口,一般接收 网络设备日志。 } } ============================================================================ 2. 日志策略 filter{ # 策略 ============================================================================== 2.1 针对于华为防火墙日志格式化 if "HW" and "FW" in [message]{ # 判断 HW 和 FW 字段同时在本条日志中出现 grok{ #日志格式化 match => { "message" => "\S+[0-9]{1,4}-\d\d-\d\d %{TIME} %{HOSTNAME:Log_Device_Name} %%01(?<Log_Total>[A-Z]{1,9})/(?<Log_Level>\d)/(?<Log_Type>\S+):" } } grok{ match => { "message" =>"\S+[0-9]{1,4}-\d\d-\d\d %{TIME} (?

【蓝桥杯】翻硬币-贪心

资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 小明正在玩一个“翻硬币”的游戏。 桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。 比如,可能情形是:**oo***oooo 如果同时翻转左边的两个硬币,则变为:oooo***oooo 现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢? 我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求: 输入格式 两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000 输出格式 一个整数,表示最小操作步数。 样例输入1 ********** o****o**** 样例输出1 5 样例输入2 *o**o***o*** *o***o**o*** 样例输出2 1 思路:从左往右遍历,遇到不对的翻即可 #include <stdio.h> int main() { char s1[1000],s2[1000]; gets(s1); gets(s2); int l = strlen(s1); int i,sum = 0; for(i = 0;i < l;i++) { if(s1[i] != s2[i]) { sum++; if(s1[i+1]=='*') s1[i+1]='o'; else s1[i+1]='*'; } } printf("%d",sum); return 0; }

ssh远程No route to host问题解决

ssh远程No route to host问题解决 问题描述 服务器ssh 端口设为10022 主机A192.168.237.1/24 远程登录虚拟 主机B192.168.237.138 报错:ssh: connect to host 192.168.237.136 port 10022: No route to host 解决思路 ssh端口设置是否正确网络是否可达防火墙策略是否合理 1.ssh端口检查 主机B测试本地: ssh -p 10022 root@localhost 网络是否可达 主机Aping主机B ping 192.168.237.138 防火墙策略是否合理 cat /etc/sysconfig/iptables iptables部分参数解释: 详细资料参考REDHAT6-IPTABLES ACCEPT:匹配的数据包指定了目标,则该数据包将跳过其余的规则检查,并允许其继续到达其目的地。 DROP:则将拒绝该数据包访问系统,并且不会将任何内容发送回发送该数据包的主机。 QUEUE:则将数据包传递到用户空间。 REJECT:则将丢弃数据包,但会将错误数据包发送到数据包的始发者。 考虑到数据包在接受的过程中匹配防火墙REJECT规则,直接丢弃数据包的可能性。 试着将-A INPUT -p tcp -m tcp --dport 10022 -j ACCEPT策略往上挪至:REJECT 前 重启iptables: /etc/init.d/iptables restart 测试: ssh -p 10022 root@192.168.237.138 远程登录 成功 总结 防火墙策略执行顺序由上至下,依次匹配;在做防火墙配置时注意策略顺序。但我在firewallctl设置下没有出现这种情况,大多是基于iptables设置。

jwt讲解及工具类

官方github地址:https://github.com/jwtk/jjwt 官网地址: https://jwt.io/ 1、简介 JWT,全称是 Json Web Token , 是一种 JSON 风格的轻量级的授权和身份认证规范,可实现无状态、分布式的 Web 应用授权。 JWT 作为一种规范,并没有和某一种语言绑定在一起,常用的 Java 实现是 GitHub 上的开源项目 jjwt,地址如下:https://github.com/jwtk/jjwt 2、JWT 数据格式 JWT 包含三部分数据: 1.Header:头部,通常头部有两部分信息: 声明类型,这里是JWT 加密算法,自定义 我们会对头部进行 Base64Url 编码(可解码),得到第一部分数据。 2.Payload:载荷,就是有效数据,在官方文档中(RFC7519),这里给了 7 个示例信息: iss (issuer):表示签发人 exp (expiration time):表示token过期时间 sub (subject):主题 aud (audience):受众 nbf (Not Before):生效时间 iat (Issued At):签发时间 jti (JWT ID):编号 这部分也会采用 Base64Url 编码,得到第二部分数据。 3.Signature:签名, 是整个数据的认证信息。一般根据前两步的数据,再加上服务的的密钥 secret(密钥保存在服务端,不能泄露给客户端),通过 Header 中配置的加密算法生成。用于验证整个数据完整和可靠性。 点隔开的三部分,对应前面的三部分 3、JWT 存在的问题 说了这么多,JWT 也不是天衣无缝,由客户端维护登录状态带来的一些问题在这里依然存在,举例如下: 续签问题,这是被很多人诟病的问题之一,传统的 cookie+session 的方案天然的支持续签,但是 jwt 由于服务端不保存用户状态,因此很难完美解决续签问题,如果引入 redis,虽然可以解决问题,但是 jwt 也变得不伦不类了。

web实战基础(pycharts篇):pycharts基础知识(组合图形)

这是一篇非常非常基础的入门教程,但是也能让你深入了解pycharts的实现机制和带着你深入了解细节的设计,因此非常建议你能看完,相信一定会有所收获! 这一篇讲深入介绍组合图形的基础知识。 有四种类型,分别是: (1)Grid:并行多图 (2)Page:顺序多图 (3)Tab:选项卡多图 (4)Timeline:时间线轮播多图 文章目录 一、Grid:并行多图(一)基本函数(二)上下布局(三)左右布局 二、Page:顺序多图三、Tab:选项卡多图(一)基本函数(二)案例(三)运行效果 四、Timeline:时间线轮播多图(一)基本函数(二)Bar图 Timeline 效果(三)Pie 图 Timeline 效果 一、Grid:并行多图 (一)基本函数 class pyecharts.charts.Grid(Base) class Grid( # 初始化配置项,参考 `global_options.InitOpts` init_opts: opts.InitOpts = opts.InitOpts() ) func pyecharts.charts.Grid.add def add( # 图表实例,仅 `RectChart` 类或者其子类 chart: RectChart, # 直角坐标系网格配置项,参见 `GridOpts` grid_opts: Union[opts.GridOpts, dict], # 直角坐标系网格索引 grid_index: int = 0, # 是否由自己控制 Axis 索引 is_control_axis_index: bool = False, ) GridOpts:直角坐标系网格配置项 class pyecharts.options.GridOpts class GridOpts( # grid 组件离容器左侧的距离。 # left 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比, # 也可以是 'left', 'center', 'right'。 # 如果 left 的值为'left', 'center', 'right',组件会根据相应的位置自动对齐。 pos_left: Optional[str] = None, # grid 组件离容器上侧的距离。 # top 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比, # 也可以是 'top', 'middle', 'bottom'。 # 如果 top 的值为'top', 'middle', 'bottom',组件会根据相应的位置自动对齐。 pos_top: Optional[str] = None, # grid 组件离容器右侧的距离。 # right 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。 pos_right: Optional[str] = None, # grid 组件离容器下侧的距离。 # bottom 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。 pos_bottom: Optional[str] = None, # grid 组件的宽度。默认自适应。 width: Union[Numeric, str, None] = None, # grid 组件的高度。默认自适应。 height: Union[Numeric, str, None] = None, # grid 区域是否包含坐标轴的刻度标签。 is_contain_label: bool = False, ) (二)上下布局 from pyecharts.

Eclipse__mybatis跳转xml的插件MyBatipse

背景: emmmm,不多说废话。国内开发基本上大多都是使用 mybatis 进行开发的,但是每次在查找到 mapper 层的时候,要看 SQL 语句只能通过自己手动查找文件,然后再根据方法进行查找。不仅很繁琐,还很耗时间。不过现在有插件可以帮我们解决这个问题了。 1. 安装 步骤如下: 插件路径为:http://dl.bintray.com/harawata/eclipse/ 然后一直下一步即可完成。

Eclpise2020 maven添加spring依赖失败:Failed to read artifact descriptor for org.springframework:spring-core

java学习记录,如果帮到你,评论里鼓励一下(手动滑稽),谢谢。 注:本文我在学习java spring使用maven构建项目遇到的问题,记录供以后细求证,很多东西错误的原理我不是很清楚,仅记录过程。 接上一篇记录:https://blog.csdn.net/zy199701/article/details/105656062 上一篇文章我更改了阿里的镜像,目前国内镜像好像只有阿里,虽然能够成功的创建项目和添加jnuit测试依赖库,但是我在添加spring依赖库的时候却出现错误如下图,此时的pom.xml文件名上也有一个小红×: 我猜测是程序通过添加的镜像地址没有下载到所需要的spring库,我百度是时候看到很多版本的阿里镜像仓库,所有我推测是阿里的镜像地址维护时可能频繁改动。百度了很多文章是几年前的,而且有一些不是在eclipse软件中遇到,参考价值不高,于是在阿里官方查询到目前挂出来的镜像地址,一并加进了setting.xml文档中,更新后如下: <mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> </mirror> <mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>https://maven.aliyun.com/repository/central</url> </mirror> <mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/repositories/central</url> </mirror> 最后一点:更新了setting.xml的镜像地址后,一定要到maven目录下m2\repository\org(如我的:D:\Program Files\Java\apache-maven-3.6.3\m2\repository\org)中删除springframework文件夹,然后重新保存修改pom.xml重新保存,就会成功下载。

JSTL基本语法

JSTL基本语法 <c:if> 相当于java的if语句 test—if语句的布尔表达式为true进入if,为false,不进入if和EL表达式连用 <c:if test="${1==1}"> 等于 </c:if> <c:choose> 相当于if…else…else 结构: <c:choose> <c:when></c:when> <c:otherwise></c:otherwise> </c:choose> when的属性 test—if语句的布尔表达式为true进入if,为false,不进入if和EL表达式连用 <c:choose> <c:when test="${1>1}"> 大于 </c:when> <c:when test="${1=1}"> 等于 </c:when> <c:otherwise"> 其他 </c:otherwise> </c:choose> <c:forEach> 用来替代JSP页面的for循环 items—必有属性,需要遍历的数组/集合,和EL表达式连用 var—必有属性每次遍历出啦的元素,保存一个临时变量 <c:forEach items="${strArr}" var="xx"> ${xx} </c:forEach> varStatus—遍历的状态变量 .index<当前遍历的索引> .count<当前遍历的次数> .first<是否为第一次遍历> .last<是否为最后一次遍历> begin—循环从哪个索引开始 end—循环到哪个索引结束 step—每次循环完毕,索引加几 <c:forEach items="${strArr}" var="xx" begin="1" end="5" step="2"> ${xx} </c:forEach> 特殊:没有items属性。 begin+end 可以替代 items <c:forEach begin="1" end="5" var="aa"> ${aa} </c:forEach>

mysql(重置root账号)

方法一: 在my.ini的[mysqld]字段加入: skip-grant-tables 重启mysql服务,这时的mysql不需要密码即可登录数据库 然后进入mysql mysql>use mysql; mysql>更新 user set password=password('新密码') WHERE User='root'; mysql>flush privileges; 运行之后最后去掉my.ini中的skip-grant-tables,重启mysqld即可。 方法二: 不使用修改my.ini重启服务的方法,通过非服务方式加skip-grant-tables运行mysql来修改mysql密码 停止mysql服务 打开命令行窗口,在bin目录下使用mysqld-nt.exe启动,即在命令行窗口执行: mysqld-nt --skip-grant-tables 然后另外打开一个命令行窗口,登录mysql,此时无需输入mysql密码即可进入。 按以上方法修改好密码后,关闭命令行运行mysql的那个窗口,此时即关闭了mysql,如果发现mysql仍在运行 的话可以结束掉对应进程来关闭。 启动mysql服务

Flutter页面不流畅,难道是使用姿势有问题?

作者|檀婷婷(三莅) 出品|阿里巴巴新零售淘系技术部 背景 高性能高流畅度一直是Flutter团队宣传的一大亮点,也是当初闲鱼选择Flutter的重要因素之一,但是随着复杂业务的应用落地,通过Flutter页面和原生页面滑动流畅度对比,我们开始产生怀疑,因为部分Flutter页面流畅度明显低于Native,是Flutter的宣传言过其实还是我们开发人员使用姿势有问题,今天我们就来具体分析下。 Flutter渲染原理简介 优化之前我们先来介绍下Flutter的渲染原理,通过这部分基础了解渲染流程以及主要耗时花费。 Flutter视图树包含了三颗树:Widget、Element、RenderObject Widget: 存放渲染内容、它只是一个配置数据结构,创建是非常轻量的,在页面刷新的过程中随时会重建 Element: 同时持有Widget和RenderObject,存放上下文信息,通过它来遍历视图树,支撑UI结构 RenderObject: 根据Widget的布局属性进行layout,paint ,负责真正的渲染 从创建到渲染的大体流程是:根据Widget生成Element,然后创建相应的RenderObject并关联到Element.renderObject属性上,最后再通过RenderObject来完成布局排列和绘制。 例如下面这段布局代码 Container( color: Colors.blue, child: Row( children: <Widget>[ Image.asset('image'), Text('text'), ], ), ); 对应三棵树的结构如下图: 了解了这三棵树,我们再来看下页面刷新的时候具体做了哪些操作 当需要更新UI的时候,Framework 通知 Engine,Engine 会等到下个 Vsync 信号到达的时候,会通知 Framework 进行 animate, build,layout,paint,最后生成 layer 提交给 Engine。Engine 会把 layer 进行组合,生成纹理,最后通过 Open Gl 接口提交数据给 GPU, GPU 经过处理后在显示器上面显示,如下图: 结合前面的例子,如果text文本或者image内容发生变化会触发哪些操作呢? Widget 是不可改变,需要重新创建一颗新树,build开始,然后对上一帧的element树做遍历,调用他的updateChild,看子节点类型跟之前是不是一样,不一样的话就把子节点扔掉,创造一个新的,一样的话就做内容更新,对renderObject做updateRenderObject操作,updateRenderObject内部实现会判断现在的节点跟上一帧是不是有改动,有改动才会别标记dirty,重新layout、paint,再生成新的layer交给GPU,流程如下图: 到这里大家对Flutter在渲染方面有基本的理解,作为后面优化部分内容理解的基础。 性能分析工具及方法 下面来看下性能分析工具,注意,统计性能数据一定要在真机+profile模式下运行,拿到最接近真实的体验数据。 performance overlay 平时常用的性能分析工具有performance overlay,通过他可以直观看到当前帧的耗时,但是他是UI线程和GPU线程分开展示的,UI Task Runner是Flutter Engine用于执行Dart root isolate代码,GPU Task Runner被用于执行设备GPU的相关调用。绿色的线表示当前帧,出现红色则表示耗时超过16.6ms,也就是发生丢帧现象。

Linux 系统进程管理

在 Windows 中主要是使用"任务管理器"来进行进程管理的。目的是: 1)利用"应用程序"和"进程"标签来査看系统中到底运行了哪些程序和进程; 2)利用"性能"和"用户"标签来判断服务器的健康状态; 3)在"应用程序"和"进程"标签中强制中止任务和进程; 但是,在使用 Windows 系统的过程中,使用任务管理器,很大程度上是为了强制关闭“未反应”的软件,也就是杀死进程。 Linux 中是使用命令进行进程管理,主要目的都是是一样的,进程管理的作用: 1) 判断服务器的健康状态 2)查看系统中所有的进程 3) 杀死进程 一、进程管理中的有些概念 1、程序(program) 程序是人使用计算机语言编写的指令和数据的代码集合。用来实现特定目标或解决特定问题,其本身没有任何运行的含义,是一个静态的概念。 2、进程(process) 进程是正在执行的一个程序或命令,每个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源。 主要包含两点: 1)进程是一个“执行中的程序”。 程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。 2)进程是一个实体,拥有资源。 每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储属性变量和进程执行期间使用的动态分配的进程的内存地址;堆栈区域存储着活动过程调用的指令和临时变量。 顺便说一下线程: 线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个进程由几个线程组成,线程与同属一个进程的其他的线程共享进程所拥有的全部资源。 总结:进程是资源分配的最小单位。线程是程序执行的最小单位。 3、Linux中的进程状态 R (TASK_RUNNING),可执行状态,只有在该状态的进程才可能在CPU上运行。 S (TASK_INTERRUPTIBLE),可中断的睡眠状态,处于这个状态的进程因为等待某某事件的发生(比如等待socket连接、等待信号量),而被挂起。 D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态,与TASK_INTERRUPTIBLE状态类似,进程处于睡眠状态,但是此刻进程是不可中断的,这种进程的特征就是kill -9命令杀不死,而TASK_UNINTERRUPTIBLE状态存在的意义就在于,内核的某些处理流程是不能被打断的。 T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态,向进程发送一个SIGSTOP信号,它就会因响应该信号而进入TASK_STOPPED状态,向进程发送一个SIGCONT信号,可以让其从TASK_STOPPED状态恢复到TASK_RUNNING状态,被跟踪的进程下一个断点,进程在断点处停下来的时候就处于TASK_TRACED状态。 Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程,进程在退出的过程中,处于TASK_DEAD状态,在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故称为僵尸。 之所以保留task_struct,是因为task_struct里面保存了进程的退出码、以及一些统计信息。而其父进程很可能会关心这些信息。 4、父进程和子进程 某些进程会产生一些新的进程,我们把这些进程称作子进程,而把这个进程本身称作父进程。子进程是依赖父进程而产生的,如果父进程不存在,那么子进程也不存在了。 每一个子进程都有一个父进程,当进程终止或者结束的时候,都会给父进程发送一个SIGCHLD信号,系统默认是父进程忽略这个信号,如果父进程希望被告知其子进程的这种状态改变,则应该捕获这个信号,捕捉函数一般是wait函数来取得子进程ID和子进程状态。CentOS6.x,系统启动的第一个进行是init,CentOS7.x,系统启动的第一个进行是systemd,其他的所有进程,都是第一个系统进程的后代。 5、Linux后台进程与前台进程的区别: 前台进程:是在终端中运行的命令,那么该终端就为进程的控制终端,一旦这个终端关闭,这个进程也随着消失 后台进程::也叫守护进程(Daemon),是运行在后台的一种特殊进程,不受终端控制,它不需要与终端交互; Linux的大多数服务器就是用守护进程实现的。比如,Web服务器httpd等。 6、缓冲(buffer)和缓存(cache)的区别: 缓存(cache):是在读取硬盘中的数据时,把最常用的数据保存在内存的缓存区中,再次读取该数据时,就不去硬盘中读取了,而在缓存中读取。 缓冲(buffer):是在向硬盘写入数据时,先把数据放入缓冲区,然后再一起向硬盘写入,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。 简单来说,缓存(cache)是用来加速数据从硬盘中"读取"的,而缓冲(buffer)是用来加速数据"写入"硬盘的。 二、进程与管理操作 1、查看正在运行的进程 -- ps命令 ps 命令用于查看系统中所有运行进程的详细信息。 基本格式为: [root@centos7 ~]# ps aux

EndNote X9报错

EndNote X9报错 报错现象问题解决 报错现象 在利用EndNote X9进行文献插入的时候,报错产生如下错误: the output style specified in this doctument, my_style, is not available in your Styles folder. Please select another style or Cancel and make sure that the style is in the proper folder. 标记部分my_style是你使用的style名字,因人而异。 问题解决 更改style的文件后缀,将后缀由ENS改为ens。 具体操作为, 1.找到EndNote X9的安装路径; 右键EndNote的图标>点击属性>快捷方式>在文件夹中找到起始位置; 2.进入Styles文件夹; 3.更改刚才无法使用的style后缀为ens。 在这附一张图 到此,问题解决。 2020/4/22

对接口类和实现类的理解:一个接口有多个实现类,当调用接口中的方法时,如何判定用的是哪个实现类?

一个接口有多个实现类,当调用接口中的方法时,如何判定用的是哪个实现类? 1. 直接new一个子类实例,这样肯定知道用的哪个实例。 2. 定义接口类型的变量,用某个实例去初始化,这样也可以确定用的哪个实例。 代码实例: 接口类: public interface CsBaseService { //获得总记录条数 public int getTotalCount(JDBCBean jdbcBean); } 实现类一: public class CsLastUpdateService implements CsBaseService { @Override public int getTotalCount(JDBCBean jdbcBean) { return 1; } } 实现类二: public class CsRelateModelService implements CsBaseService { @Override public int getTotalCount(JDBCBean jdbcBean) { return 2; } } 调用的时候可以确定用的是哪个实现类: public class RelateModelController extends BaseController{ //自动装配实现类二(这里就确定了调用的是实现类二 CsRelateModelService) @Autowired private CsRelateModelService relateModelService; //初始化实现类2,关键在这步,指定relateModelService为beaseService initParamProcess(relateModelService,new RelateModel(),new Page()); //然后直接调用实现类2的方法,输出为2 int totalCount = beaseService.

Xam.plugin.media调用相机, Unable to get file location

本来app 都很正常,升级xamarin.forms框架之后调用相机的时候,报 Unable to get file location. This most likely means that the file provider information is not set in.... Plugin.Media.Abstractions.MediaFile file = null; try { file = await Plugin.Media.CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions { Directory = "Sample", Name = "23123213.jpg", }); } catch (Exception ex) { return; } 找了半天原因,把xam.plugin.media什么的都更新了一下也没用,最后的最后发现是 fileProvider的P大写改成小写就可以了。。。

C语言如何实现数字金字塔

C语言如何实现数字金字塔 本题要求实现函数输出n行数字金字塔 其中n是用户传入的参数,为[1, 9]的正整数。要求函数按照如样例所示的格式打印出n行数字金字塔。注意每个数字后面跟一个空格 输入样例 5 输出样例 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 考虑将空格与数字分别输出,分别判断各自进行循环的条件 //void pyramid( int n ); //函数接口定义 #include <stdio.h> void pyramid( int n ); int main() { int n; scanf("%d", &n); pyramid(n); return 0; } void pyramid( int n){ int i; //行数 int j; //列数 for( i=1; i<=n; i++){ for( j=1; j<=n-i; j++){ //输出空格 printf(" "); } for( j=1; j<=i; j++){ //输出数字 printf("

Git管理项目,git的基本操作语法加注释

直接干货 git init---创建一个.git文件 git add --all---将目录下的所有文件与.git绑定 git commit -m "注释信息"---将所有文件暂存在缓存区 注意-m后面是注释信息且注释信息必须填写 git remote add origin 仓库地址---注意仓库地址选rw开头,意思是可读可写,一般为第二个 git pull origin master -- allow-unrelated-histories---将库中的其他文件刷下来更新 git add --all---绑定刷下来的文件 git commit -m "不一样的注释"---将文件放入缓存区 git push origin master---将所有文件上传至服务器的库中注意: 一般情况下直接跳转账号密码输入窗口,特殊情况无弹框 ,根据提示先输账号再输密码,密码为数字的时候可能不显示,无所谓继续输入不能输错

Docker学习(一)在Docker容器中部署一个基于TCP的简单Java应用——Windows

Docker学习(一)Docker入门、部署一个简单的基于TCP的Java应用——Windows 目录环境准备安装Dcoker运行hello-world部署自己的java应用准备可运行jar包为Docker容器准备java环境构建镜像并运行 附录 目录 在上云计算这门课——Docker部署实验,因为要求是部署自己的java应用,就做个平平无奇java的TCP应用部署的笔记和分享。 环境准备 操作系统:Windows10专业版使用软件:Docker-for-windows 19.03.8、Eclipse photon(其他java ide也可以) 安装Dcoker 安装过程中忘记截图了,这篇文章写得就挺详细的,跟着安装应该不会有大问题: https://www.runoob.com/docker/windows-docker-install.html 注意事项: 1) Windows家庭版需要先安装Docker ToolBox。防止Windows的平台虚拟化与Docker ToolBox互相冲突:控制面板–>程序和功能–>启用或关闭Windows功能–>Windows功能–>关闭Virtual Machine Platform、Windows Hyper-V platform。 2) Windows专业版在安装之前需要在本地先开启Windows自带的Hyper-V服务,开启后重启电脑服务才能生效。 3) VMware的虚拟机服务与Hyper-V不能并存,这时候你开启虚拟机会出现下面的报错。解决办法…后续尝试了再补充吧… 补充:由于目前用的Hyper-V和VMware的虚拟化技术无法兼容,还是分开用吧……其他人的答案也是启动的时候选择加载Hyper-V还是VMware,既然不能同时用就需要用谁再开吧,但是看到VMware的20H1好像支持同时使用,期待后面的版本吧。 Dcoker 成功安装后,使用dcoker --version查看可安装的Dcoekr版本,验证Docker是否成功安装: 运行hello-world 在CMD运行命令docker run hello-world ,成功运行的情况截图如下: 如果出现拉取超时导致失败的情况,一般是网络问题,再次运行该命令可以成功,或者搜索net/http: TLS handshake timeout更换国内的镜像源: 部署自己的java应用 准备可运行jar包 1. 项目结构 编写自己的java应用,一个非常简单的项目(之前学java写的代码逻辑可能不太严谨凑合用吧),项目结构如下: 2. Server.java package tcp; /* 服务器接收客户端发送的in.txt文件中的内容,并向out.txt中写入 * 当连接服务器的客户端数量达到5时不再接受连接,关闭服务器的socket */ import java.io.DataInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class Server { public static int client_num = 0;//初始化客户端连接数量 private static int MAX_NUM = 5;//可连接的客户端数量上限为5 public static boolean flag = true;//flag用于表示是否接受连接 public static void main(String[] args) { ServerSocket server = null; try { server = new ServerSocket(6666); // 监听6666端口的服务器Socket } catch (IOException e1) { System.

tf.estimator.Estimator的使用

tf.estimator.Estimator是TF比较高级的接口。 最近在使用bert预训练模型的时候用到了tf.estimator.Estimator。使用该接口的时候需要开发者完成的工作比较少,一共3个步骤: 第一步,设置input_fun,第二步,设置model_fun,第三步,开始训练。 第一步的input_fun完成的功能是数据的输入准备工作,比如读取一个tfrecord文件,然后解析里面的内容,返回dataset;或者读取音频、图像等数据,返回相应的结果,目前来说返回的结果为dataset格式比较好。 第二步的model_fun完成的功能有:创建模型(输入feature,输出predict这种),设置loss,设置优化器,返回结果是tf.estimator.EstimatorSpec。(后续会说明tf.estimator.EstimatorSpec是什么,怎么设置) 第三步的开始训练是:参数准备(比如学习率什么的,就是上面的步骤1-2中需要用到的参数),设置config(用于训练模型是指定模型的保存路径,多长时间保存一次模型,使用GPU的一些情况),开始根据情况调用estimator.train 和 estimator.evaluate 或者 estimator.predict。 第一步:input_fun def input_fn(filenames, batch_size=32, num_epochs=None, perform_shuffle=False): """ 每次调用,从TFRecord文件中读取一个大小为batch_size的batch Args: filenames: TFRecord文件 batch_size: batch_size大小 num_epochs: 将TFRecord中的数据重复几遍,如果是None,则永远循环读取不会停止 perform_shuffle: 是否乱序 Returns: tensor格式的,一个batch的数据 """ def _parse_fn(record): features = { "label": tf.FixedLenFeature([], tf.int64), "image": tf.FixedLenFeature([], tf.string), } parsed = tf.parse_single_example(record, features) # image image = tf.decode_raw(parsed["image"], tf.uint8) image = tf.reshape(image, [28, 28]) # label label = tf.cast(parsed["label"], tf.int64) return {"image": image}, label # Extract lines from input files using the Dataset API, can pass one filename or filename list dataset = tf.