错误代码: django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING_CONFIG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
解决办法: 将配置添加到pycharm中的python配置中
在环境变量(environment variables)这一栏添加如下信息:
此时去运行,完美解决!
阿里巴巴达摩院正在用AI算法抗击新型冠状病毒肺炎疫情。2月1日,浙江省疾控中心上线自动化的全基因组检测分析平台。利用阿里达摩院研发的AI算法,可将原来数小时的疑似病例基因分析缩短至半小时,大幅缩短确诊时间,并能精准检测出病毒的变异情况。
达摩院算法专家顾斐博士在疾控中心基因检测分析现场
当前,全国新型冠状病毒肺炎疫情依然严峻,快速、精确诊断对于疫情控制尤其重要。公开信息显示,该病毒是基因组序列最长的病毒之一,全基因组序列全长29847bp,临床诊断需要将患者样本与该病毒基因序列进行比对才能确定诊断结果。
目前医院普遍采用核酸检测方法,其只能检测到病毒基因的局部。由于病毒存在变异的可能性,对于整个基因序列来说这种检测方法犹如盲人摸象,一旦病毒发生变异,就可能出现漏检的情况。
新型冠状病毒结构
不同于传统核酸检测方法,全基因组检测技术可以对疑似病例的病毒样本进行全基因组序列分析比对,能够有效防止病毒变异产生的漏检。此次阿里巴巴达摩院与杰毅生物技术公司联合研发的平台采用的就是全基因组检测方法,其突破之处在于大幅缩短了检测时间。
在基因分析阶段,阿里巴巴达摩院和阿里云弹性计算团队提供的系统还能提供病毒快速拼接能力,将快速精准捕捉变异后的病毒序列,二级结构及三维结构,为病毒疫苗和药物提供了基础。
设置基因检测分析参数
诊断效率的提升得益于算法的创新。达摩院团队针对新型冠状病毒基因进行特征分析,并推出多个算法模型。在序列比对过程中,达摩院对算法增加了分布式设计,提升了比对效率;在病毒序列拼接阶段使用分布式设计的de Bruijn图算法,变异病毒也能精准检测。
浙江省疾控中心基因测序负责人孙逸博士表示:“该平台基于阿里云的强大算力与达摩院新算法可以为病毒的解析提供支撑,基于该平台,未来还可以在短时间内将检测范围覆盖整个确诊病例,也为后续疫苗与药物研发打下了坚实基础。”
以下是达摩院算法专家对该平台的解读:
Q:这一平台有何特点?
A:此次研发的自动化全基因组检测分析平台属于高通量测序,平台由阿里巴巴达摩院联合杰毅生物共同研发,可以给浙江省疾控在新型冠状病毒疫情防控上提供了全自动建库和分布式计算分析能力。杰毅生物开发了全自动高通量测序建库仪,把整体常规人工需要12小时的工作缩短到2个小时。每次测序过程会产生海量的数据,达摩院采用分布式设计的分析算法,样本基因分析的速度由数小时缩短到半小时;同时,由于采用分布式算法,病毒拼接的速度由30分钟-1小时缩短到15-30分钟。除此之外,不同于传统核算检测方法,这一平台还可以检测到病毒的全貌,避免因为病毒变异造成的漏检情况。
Q:达摩院团队提供的算法有哪些价值?
A:达摩院针对新冠病毒基因的特征进行了分析,基于pdb等公共数据集的数据进行算法的优化训练。本次分析病毒检测和病毒变异部分主要基于开源算法,设计分布式算法以加速分析流程。病毒序列拼接完成后,通过设计BiLSTM+DNN的方式训练模型预测病毒蛋白二级结构。同时,达摩院还在研究基于序列的蛋白质三维结构预测模型以及药物筛选模型。
相关阅读
点击下方图片即可阅读
@武汉人民,请收好这份名单
驰援武汉,就这么干了!
关注「阿里技术」
把握前沿技术脉搏
目录
unique_ptr设计目标
使用unique_ptr
通过unique_ptr转移所有权
源和槽
unique_ptr作为类成员
处理数组
default_delete<>类
其他关联资源的删除器
unique_ptr详细信息
C++11标准库提供的唯一指针unique_ptr有助于避免发生异常时的资源泄漏。它实现了专有所有权的概念,这意味着它可以确保一个对象及其关联资源一次只能由一个指针"拥有''。当此所有者被销毁或变空或开始拥有另一个对象时,先前拥有的对象也将被销毁,所有相关资源都将被释放。
唯一指针unique_ptr继承了自动指针auto_ptr(该类最初是C++ 98引入的,但现在已弃用)。 唯一指针unique_ptr提供了一个简单明了的接口,与自动指针auto_ptr相比,它更不容易出错。
unique_ptr设计目标 函数通常以以下步骤运行:
获取一些资源;执行一些操作;释放获得的资源。 如果获取的资源已经绑定到本地对象,则在进入时获取的资源会在函数退出时自动释放,因为函数退出时调用了这些本地对象的析构函数。但是如果资源是手动获取的,并且没有绑定到任何对象,则必须手动释放它们。使用指针时通常会手动管理资源。
以这种方式使用指针的典型示例是使用new和delete创建和销毁对象:
void f() { ClassA* ptr = new ClassA; //手动创建一个对象 ... //执行一些操作 delete ptr; //清理:手动销毁对象 } 上面代码的一个明显问题是,对象的销毁可能会被遗忘,尤其是在函数内部有return语句的情况下。 还有一种不太明显的危险就是可能发生的异常将导致函数立即退出,而不会调用末尾的delete语句,最终导致资源泄漏。
为了避免这种资源泄漏通常要求函数捕获所有异常。 例如:
void f() { ClassA* ptr = new ClassA; //手动创建一个对象 try { ... //执行一些操作 } catch (...) { //处理异常 delete ptr; //清理 throw; //重新抛出异常 } delete ptr; //正常退出时清理 } 为了在发生异常时正确处理此对象的删除,代码变得复杂和冗余。如果以这种方式处理第二个对象,或者使用了多个捕获子句,问题将变得更加严重。这不是一种好的编程风格,应避免使用,因为它很复杂且容易出错。
自动指针unique_ptr可以解决这个问题。只要自动指针本身被销毁,它就可以释放其指向的数据。此外,由于它是一个局部变量,所以退出函数时唯一指针会自动销毁,无论退出是正常的还是由于异常导致的。
unique_ptr是一个指针,作为它所引用的对象的唯一所有者。当对象的唯一指针unique_ptr被销毁时,对象将自动销毁。对意味唯一指针unique_ptr的要求是其对象只有一个所有者。
问题描述:
软件安装编译时,出现以下问题,是ceres库和glog库有问题
undefined reference to `google::LogMessageFatal::LogMessageFatal(char const*, int)' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `google::base::CheckOpMessageBuilder::CheckOpMessageBuilder(char const*)' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `ceres::Solver::Summary::FullReport[abi:cxx11]() const' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `ceres::Problem::AddResidualBlock(ceres::CostFunction*, ceres::LossFunction*, double*)' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `google::base::CheckOpMessageBuilder::~CheckOpMessageBuilder()' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `ceres::Solver::Summary::Summary()' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `google::LogMessageFatal::LogMessageFatal(char const*, int, google::CheckOpString const&)' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `ceres::Problem::~Problem()' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `ceres::Problem::AddParameterBlock(double*, int)' //usr/lib/libblas.so.3: undefined reference to `gotoblas' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `google::base::CheckOpMessageBuilder::ForVar2()' ../../../Linux-x86_64/libaliceVision_multiview.so.2.2: undefined reference to `ceres::Solve(ceres::Solver::Options const&, ceres::Problem*, ceres::Solver::Summary*)' 于是安装gflags,glog,suitsparse,安装后重新编译发现还是有问题,于是写了一个简单的测试ceres库的代码,可以正常cmake和编译,但执行程序时有以下报错
文章目录 归并排序理解归并排序模板 归并排序理解 归并排序的主要操作如下:
(1)分解。把初始序列分成长度相同的左、右两个子序列,然后把每个子序列再分成更小的两个子序列,直到子序列只包含一个数。这个过程用递归实现。
(2)求解子问题,对子序列排序。最底层的子序列只包含一个数,其实不用排序。
(3)合并。归并两个有序的子序列,这是归并排序的主要操作。比如下面举例,把a[ ]分成两个子序列,比较后存进b[ ],假设两个子序列已经分别排好序。
过程如下(有点丑…将就一下):
只要有一个子序列结束,就可以把另一个子序列后面的都放进去,因为是排好序的
归并排序的时间复杂度:对n个数进行排序:
需要log2(n)趟归并。 在每一趟归并中有很多次合并操作。共需O(n)次比较。所以时间复杂度为 归并排序模板 输入n个数,对n个数进行排序。
#include<iostream> using namespace std; const int N=1e6 + 10; int n; int q[N],temp[N]; void merge(int q[],int l,int r) { if(l >= r) return;//满足条件不再往下进行 int mid = (l + r)/2; merge(q,l,mid),merge(q,mid+1,r);//左右分开递归 int k=0,i=l,j=mid+1;//k表示temp里个数,i指向左子序开头,j指向右子序开头 while(i <= mid && j<= r) if(q[i] <= q[j]) temp[k++]=q[i++]; else temp[k++]=q[j++]; while(i <= mid) temp[k++ ]=q[i++ ];//若左半边没循环完 全部拿出来 while(j <= r) temp[k++ ] = q[j++ ];//若右半边没循环完 全部拿出来 for(i = l,j = 0;i <= r;i++,j++) q[i]=temp[j];//把temp排好的赋给q[] } int main() { cin>>n; for(int i = 0;i < n; i++) cin>>q[i]; merge(q,0,n-1);//从0~n-1 for(int i = 0;i < n; i++) cout<<q[i]<<"
Error 错误。
NodeJs应用程序一般会有四种错误:
标准的JavaScript错误;由底层操作系统触发的系统错误;由应用程序代码触发的用户自定义的错误;AssertionError错误,当Node监测到不应该发生的异常逻辑时触发,这类错误通常来自assert模块; 所有由Nodejs引起的Javascript错误与系统错误都继承自或实例化自标准的JavaScript类,
且保证至少提供类中的属性。
错误的冒泡和捕获 异常捕获处理try...catch。
// 抛出一个 ReferenceError,因为 z 未定义。 try { const m = 1; const n = m + z; } catch (err) { // 在这里处理错误。 } 回调中的Error参数 大多数Nodejs核心API所提供的异步方法都遵从错误信息优先的回调模式惯例,这种模式有时也称为Nodejs回调。
但JavaScript的try…catch机制不能用来截获异步方法产生的错误。
try { setTimeout(function () { throw new Error('async error'); // 抛出一个异常错误,这是因为异步函数执行上下文不同,所以捕获不到。 }, 1000); } catch (e) { console.log(e); } 为了捕获异步产生的异常错误,可以用domain模块。
var domain = require('domain'); var d = domain.create(); d.run(function () { setTimeout(function () { throw new Error('async error'); // 抛出一个异步异常 }, 1000); }); d.
本节将分享如何将python的flask框架结合uwsgi和nginx在阿里云服务器上进行生产环境的部署。这里会简单介绍一下这三者是什么,更具体的知识大家可以去查看其它博主的教程。
Flask:一种基于python的Web应用框架,通过它我们可以直接用python实现一个网站或所需的Web服务。这里结合我们后续的教程应用讲一下它的重要性。一些有AI基础的朋友们可能或多或少都用过一些深度学习框架:Tensorflow、pytorch或keras等等。但是大部分都是私底下自己电脑代码进行运行的,没有代码的其他人就无法使用。那么我们怎么将模型部署在网站或APP上使其落地供所有人使用呢?当然像Tensorflow2.0有提供像Tensorflow.js这种使用于工业部署的库,其语言基于JavaScript。个人认为其不够灵活且教程较少,不易初学者上手。所以Flask相对来说是一个更好的选择,我们可以直接利用其将python的模型或其它代码与网页部署结合,使其快速落地。相似的Web框架还有django、bottle等。
uwsgi: 一种基于uWSGI(Web服务器)的协议,用于定义传输数据的类型。简单来说在这协议里面我们要做一个转换的过程,因为前端的HTML、JavaScript等等代码和Python代码是不一样的,直接将前端代码传到python里去,python看不懂。因此我们通过uwsgi可以将Web的一些属性转换为python中对应的数据结构,使二者传输的信息可以互相读懂及接收。
Nginx:是一个HTTP和Web服务器,可加可不加。但加上的话会有一些好处,比如更易于处理负载均衡、静态资源的问题。
整个流程其实就是网页索求的信息通过http协议先发送到Nginx里,它经过处理后信息再发到uWSGI服务器里。然后uWSGI服务器再将http协议转换成uwsgi协议,让python可以直接使用。
上一节内容我们已经购买好了阿里云服务器并且可以查看系统默认部署的网站,接下来的内容是基于这个基础。如果有疑问的朋友们可以查看上一节内容。
一.配置准备部署的网站 1.创新网站。这里随便输一个域名,当然这个域名未购买未备用,我们没办法从这个域名登录。但我们可以将这个域名绑定上我们服务器公网IP地址的一个端口,就可以访问了。
2.绑定公网IP,后面随意接一个端口。但是这个端口因为阿里云服务器的防火墙阻挡,因此无法直接外网访问,我们后面还需要对防火墙进行相关设置。
3.在阿里云服务器控制台的防火墙处添加2222端口。
4.在阿里云控制台远程连接的linux后台中(用putty或mobaxterm等等的SSH连接上也可以),直接关掉防火墙(当然我为了测试省事直接暴力关掉了哈哈哈,也可以通过防火墙其它指令单独开通这个端口)。记得先输入sudo su root,有权限了才可以对防火墙进行操作。
5.测试该网站能否成功运行。
结果发现运行成功。
二.安装Python3、Flask库及建立虚拟环境 因为该环境默认的python版本是2.7,而python2目前已经不在更新,官方已经摒弃了。并且很多新的库只和python3兼容,因此我们需要将环境更换成python3。
这里需要大家掌握一些基础的linux指令,比如定位文件路径、复制、删除、等等,这一部分我就跳过,直接上代码。
1.创建python3系统文件夹。
2.安装依赖。
yum -y groupinstall "Development tools" yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel 3.Python3下载解压并安装。
wget https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tar.xz tar -xvJf Python-3.6.2.tar.xz cd Python-3.6.2 ./configure --prefix=/usr/local/python3 make && make install 4.创建python3软连接。
ln -s /usr/local/python3/bin/python3 /usr/bin/python3 ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3 5.安装虚拟环境包。
pip3 install --upgrade virtualenv 6.创建一个虚拟环境。
在上篇博客【死磕 Spring】—— IoC 之解析 标签:BeanDefinition 中,已经完成了对 <bean> 标签属性的解析工作。这篇博文开始,分析子元素的解析。
完成 bean 标签的基本属性解析后,会依次调用 BeanDefinitionParserDelegate 的 #parseMetaElements(lement ele, BeanMetadataAttributeAccessor attributeAccessor)、#parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides)、#parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides)方法,分别对子元素 meta、lookup-method、replace-method 元素完成解析。三个子元素的作用如下:
<meta> :元数据。<lookup-method> :Spring 动态改变 bean 里方法的实现。方法执行返回的对象,使用 Spring 内原有的这类对象替换,通过改变方法返回值来动态改变方法。内部实现为使用 cglib 方法,重新生成子类,重写配置的方法和返回对象,达到动态改变的效果。 <replace-method> :Spring 动态改变 bean 里方法的实现。需要改变的方法,使用 Spring 内原有其他类(需要继承接口org.springframework.beans.factory.support.MethodReplacer)的逻辑,替换这个方法。通过改变方法执行逻辑来动态改变方法。 1. meta 子元素 meta :元数据。当需要使用里面的信息时可以通过 key 获取。
meta 所声明的 key 并不会在 Bean 中体现,只是一个额外的声明,当我们需要使用里面的信息时,通过调用 BeanDefinition 的 #getAttribute(String name) 方法来获取。该子元素的解析过程,代码如下:
// BeanDefinitionParserDelegate.java public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) { NodeList nl = ele.
问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。
否则输出Impossible
样例输入
5
mamad
样例输出
3
分析:
本题要使用贪心算法。
(1)形如“mama”,每个字符出现的次数都是偶数次,可以得到完美的回文串“maam”或者“amma”。
(2)形如“mamad”,只有1个字符出现次数是奇数次,其余都是偶数次,可以得到完美的回文串“madam”或者“amdma”。
(3)形如“mamade”,有2个字符出现次数是奇数次,其余的都是偶数次,得不到完美的回文串。
以此类推,可以发现,字符串中出现奇数次的字符大于等于2的时候,得不到完美的回文串,输出“Impossible”
具体算法:
先定义i,k,两个变量,i从字符串最左边开始往右遍历,k从最右边开始往左遍历。如图:
i不变,k自减往左遍历,如果a[i]和a[k]不一样,则让k继续往左遍历,直到和a[i]相等,如下:
定义一个变量j,让他指向最后一个未经过交换对称的字符,最大值为n-1。
将a[k]移动到与a[i]对称的位置,可以通过a[k]=a[k+1]实现,条件为k<j,最后a[j]=a[i]即可,在此过程中,定义一个记录移动次数的变量sum=0,每次移动字符时加1。
由于移动后,变量i和j所指向的字符已形成对称,后面的移动不需改变其位置,可以让j=j-1,即j指向前一个,i++,i指向后一个,接下来只需要考虑红框内的字符,如下:
每一轮都让k==j,保证了k每次都从未经对称的末尾字符开始往左遍历,接下来k遇到m,然后移动,和上面的方法一样。
但是,如果一直找不到相等的字符,怎么办?
像这种情况,如果一直找不到相同的,最后会遇到i等于k的情况,当i等于k的时候,我们可以知道a[i]在数组内独一无二,我们是不是可以把它移动到中间,共移动(数组长度/2-i)次,此时并不移动它(若此时移动将增加代价,应将它放在最后移动),把剩下的看成一个整体,如下:
i++,i指向下一个字符,考虑矩形内的字符,用上面的方法移动。
如果出现两次i等于j的情况,则代表数组内存在两个独一无二的字符,不可能存在完美的回文串,结束程序,打印Impossible.
当i<j不满足时,代表对称交换已经执行完毕,可以输出sum的值。
代码:
#include <stdio.h> #include <stdlib.h> int main() { int n,sum=0; int i,j,k,m,flag=0; char a[8001],c; scanf("%d",&n); getchar(); gets(a); j=n-1; for(i=0;i<j;i++) { for(k=j;k>=i;k--) { if(i==k) { if(n%2==0) { printf("
setGeometry()函数是对窗体的综合设置,有四个参数,分别是坐标和长宽,但是注意,如果窗体是顶级窗体,例如Qwidget类设置的窗体时,设置的坐标只是窗体内灰色框的坐标,这是如果加上move()函数,就可以对窗体外部的边框进行位置的设定。
工作中使用的是Java,它和python差别并不大,寒假在家准备重新看一下python。今天在做练习,做到一题不是很难的,但是死活没有做出来,将排查的方法记录下来,希望能对看到这篇文章的你有所帮助。
1.最初 # 打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数, # 其各位数字立方和等于该数本身。例如:153是一个"水仙花数", # 因为153=1的三次方+5的三次方+3的三次方。 # 打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数, # 其各位数字立方和等于该数本身。例如:153是一个"水仙花数", # 因为153=1的三次方+5的三次方+3的三次方。 import math def check_narcissistic_number(number): hundred = number / 100 number %= 100 ten = number / 10 digit = number % 10 if (math.pow(hundred, 3) + math.pow(ten, 3) + math.pow(digit, 3)) == number: return True return False for i in range(100, 1000): if(check_narcissistic_number(i)): print(i) 打印出来却什么也没有,我首先怀疑的是我取出个十百的方法
“机智“的我打印了它们三者的值,我用了一个很蠢的方法打印
print("%d %d %d"%(hundred, ten, digit)) 结果拿153试验,发现打出来的是1 5 3.???
那是哪里有问题?之后我怀疑是我math.pow(hundred,3)使用错了。
Thompson Sampling for Contextual Bandits with Linear Payoffs(线性收益) 参考论文:
Agrawal S , Goyal N . Thompson Sampling for Contextual Bandits with Linear Payoffs[J]. 2012.
摘要 有关Thompson Sampling理论性能的许多问题仍未解决
本文设计和分析
Thompson Sampling algorithm随机 contextual multi-armed bandit 问题(上下文信息由自适应的adversary提供)线性收益函数 Introduction MAB问题主要用于为许多顺序决策问题中固有的勘探/开发权衡建模。
1. contextual MAB 在这个问题中,在每轮T轮中,一个learner会从N个action中选择一个最好的,N个action称为N个arms。
在选择要哪个arms之前,learner会看到与每个arm i相 关联的d维特征向量bi,称为“上下文”。
learner将这些特征向量与她过去使用过的arm的特征向量和reward一起使用,以选择在当前回合中要选择的arm。
随着时间的流逝,learner的目标是收集有关特征向量和reward如何相互关联的足够信息,以便她可以确定地通过观察特征向量来预测哪条arm可能会提供最佳reward。
learner与一类预测变量竞争,其中每个预测变量都接受特征向量并预测哪条arm会获得最佳回报。如果learner可以保证在事后预测中所做的工作与最佳预测者的预测几乎一样(即,regret很低——用于评判该learner(算法)的有效性),那么该learner可以成功地与该类竞争。
pridictor由d为参数 μ ˉ \bar{\mu} μˉ来定义,然后根据 b i T μ ˉ b_{i}^{T} \bar{\mu} biTμˉ来将arms排序
即:假设有个未知参数 μ \mu μ,则每个arm对应的reward为 b i T μ ˉ b_{i}^{T} \bar{\mu} biTμˉ,学习者的目标就是学习该未知参数 μ \mu μ
目录
shared_ptr指针存在的问题
循环引用示例
代码
运行结果
使用weak_ptr解决循环引用问题
代码
运行结果
共享指针shared_ptr指针存在的问题 使用共享指针shared_ptr指针的主要原因是避免手动管理指针所关联的资源。但是,在某些情况下共享指针shared_ptr不能实现预期的行为:
一种情况是循环引用。如果两个对象使用shared_ptr指针相互引用,并且不存在对这些对象的其他引用,若要释放这些对象及其关联的资源,则共享指针shared_ptr不会释放数据,因为每个对象的引用计数仍为1。在这种情况下,可能想使用普通的指针,但是这样做需要手动管理相关资源的释放。另一种情况是当明确想要共享但不拥有对象。这种情况下引用的生存期超过了它所引用的对象的生命周期。如果使用共享指针shared_ptr指针则其将永远不会释放对象。如果使用普通指针则可能出现指针所引用的对象不再有效,这会带来访问已释放数据的风险。 对于这两种情况都可以使用弱指针weak_ptr指针处理。弱指针weak_ptr是共享指针shared_ptr的辅助类。该类允许共享但不拥有对象。它的use_count()返回对象的共享指针shared_ptr拥有者数量,共享该对象的弱指针weak_ptr指针不计入该数量。
弱指针weak_ptr需要共享指针shared_ptr才能创建。每当拥有该对象的最后一个共享指针失去其所有权时,任何弱指针weak_ptr都会自动变为空。因此,除了default和copy构造函数外,弱指针weak_ptr指针仅提供采用共享指针shared_ptr的构造函数。
使用初始指针所指对象的类型来对weak_ptr<>类进行模板化:
namespace std { template <typename T> class weak_ptr { public: typedef T element_type; ... }; } 不能使用运算符*和->直接访问weak_ptr的引用对象。相反,必须从中创建一个共享指针。这有两个原因:
根据弱指针创建共享指针,以检查是否存在(仍然)关联对象。如果不是,此操作将引发异常或创建一个空的共享指针(实际发生的情况取决于所使用的操作)。在处理引用的对象时,共享指针无法释放。 因此,弱指针weak_ptr仅提供少量操作:足以创建,复制和赋值一个弱指针,并将其转换为共享指针或检查它是否指向对象。
循环引用示例 代码 #include <iostream> #include <string> #include <vector> #include <memory> using namespace std; class Person { public: string m_sName; shared_ptr<Person> m_pMother; shared_ptr<Person> m_pFather; vector<shared_ptr<Person>> m_oKids; Person (const string& sName, shared_ptr<Person> pMother = nullptr, shared_ptr<Person> pFather = nullptr) : m_sName(sName), m_pMother(pMother), m_pFather(pFather) { } ~Person() { cout << "
前言 Vue 项目中,当需要页面刚刚载入后就要立马触发一个函数该怎么实现?
实现 例如,当页面载入时触发 message() 。
mounted: function(){ this.message();//需要触发的函数 } message(){ //业务逻辑 }
下载安装git git下载页面
https://git-scm.com/downloads git安装很简单,只需要下一步下一步即可。
下载安装TortoiseGit git版本管理需要依赖TortoiseGit,因此,我们要到TortoiseGit官网里面下载安装TortoiseGit,TortoiseGit的官网下载地址
https://tortoisegit.org/download/ 在官网下载地址中,我们可以下载两个文件,1个是安装文件,1个是中文简体语言包
先安装软件,在安装软件过程中,会出现语言选择的界面,这时,你再安装语言包,安装语言包后,点击右边更新按钮,接着选择chinese_simplified中文简体即可。
git克隆项目 在需要创建的目录里,按右键,选择git克隆
在弹出的窗口中,填写要克隆url地址,核对存储项目的目录,点击【确定】
Hbuilder安装git插件 1.打开软件,点击【文件】>【打开目录】,将我们刚才下载的项目引入软件。 2.点击【工具】,选择【插件安装】 3.选择【Git插件】,点击右边绿色安装按钮,安装成功后,按钮会显示卸载文字。 git提交、同步代码 方法一: 插件安装成功后,可以点击【工具】>【外部命令/插件】>【git插件】
方法二: 选中左侧某一个文件夹,按【右键】>【外部命令/插件】>【git插件】
很久不写博客了,最近在使用ts和tsx开发vue类项目,网上资料比较少,顺便记录一下方便同样开发的人互相学习共同进步。
本篇文章尽量不遗漏重要环节,本着真正分享的心态,不做标题党
下面进入正题:
由于现在vue的官方脚手架已经非常完善我们就不单独配置webpack了,节省大量的时间成本。
首先使用@vue/cli创建一个vue模版项目(记得是@vue/cli不是vue-cli还不知道的人可以点此传送门进入先导学习站)。
在自己觉得合适的目录下打开命令行输入如下代码,创建一个名为vue-tsx的项目
vue create vue-tsx 接下来的步骤vue的cli会给出相应的配置提示,着重配置已截图
第一步选择自定义配置
第二步选择如图的配置
剩下的按个人喜好自己选择就可以了
创建完成后的项目结构如图所示
从图上看出这是一个普通的vue模版项目,使用typescript语言开发
默认使用的仍然是vue的template进行渲染
正常在这种情况下就可以开发直接写代码了,模版项目所提供的示例代码已经很良心了
不过今天要介绍的是使用tsx语法进行开发vue项目
首先介绍一下什么事tsx
其实他就是typescript的jsx语法
那么什么是jsx呢?从这里介绍的话又变成无脑长文了,所以直接掠过,想了解jsx的人可以先去看一下react的开发文档5分钟上手
,但是必须要说的是为什么要使用tsx来写vue项目?vue提供的自带模版不香吗?网友对vue和react的争论喋喋不休到现在,我在这里给的答案其实很简单,vue和react之间没有好坏之分,论性能差距在使用上已经近乎55开,论生态各自都很完善了,这两个框架并存的原因很简单,vue的作者在自己的文章中曾经也提过,创造vue项目只不过是想有一个“自己用起来顺手的框架”。答案就在这句话上,所以我觉得没必要争论哪个好,其实没有可比性,只是喜欢的人各自会觉得对方好而已。
所以今天介绍tsx开发vue项目其实原因很简单,就是让适应了jsx语法的人能无缝从react过渡到vue上。就是给用起来舒服的人准备了一个方案而已。
所以继续我们的项目搭建
接下来先运行一下刚才的模版项目
在vue-tsx目录下打开命令行输入
npm run serve 出现如下图片证明以上操作全部没问题
以上操作全部通过后可以关闭服务器了,我们下一步要做的是修改项目的目录结构
首先
删除views文件夹,
删空components文件夹的内容保留文件夹,
删除App.vue文件
项目结构与图片一样即可,其他地方暂时不要动
首先将router文件夹中的index.ts文件内容修改为如下代码
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes:any = [] const router:VueRouter = new VueRouter({ routes }) export default router 然后修改main.ts中的代码为如下
import Vue from 'vue' import App from './App' import router from '.
设置Headers中Content-Type值为application/json
$str = ''; foreach ($result as $key=>&$item) { $index = ['index'=>['_id'=> $key+1]]; $str .= json_encode($index)."\n"; $str .= json_encode($item)."\n"; } echo $str; file_put_contents('studentCourse'.'.json', $str); 生成类似如下文件
{"index":{"_id": "1"}} {"username": "alfred way","job": "java engineer","age": 18,"birth": "1990-01-02","isMarried":false} {"index":{"_id": "2"}} {"username": "alfred","job": "java senior and java specialist","age": 28,"birth": "1980-05-07","isMarried":true} 先造一些测试数据
POST test_index_search/doc/_bulk {"index":{"_id": "1"}} {"username": "a","job": "java engineer","age": 18,"birth": "1990-01-02","isMarried":false,"salary":5000} {"index":{"_id": "2"}} {"username": "b","job": "java engineer","age": 28,"birth": "1980-05-07","isMarried":true,"salary":10000} {"index":{"_id": "3"}} {"username": "c","job": "java senior engineer"
转载:
https://blog.csdn.net/weixin_43638892/article/details/87100007
前段时间因为学校的考试还有实习公司的项目,因此断更了一段时间。最近准备先来更新一些关于在服务器上部署网站的教程,一方面是因为近期在公司做一个NLP的系统,边学习边记录。另一方面后续我会分享如何使用python的Flask+tensorflow2.0+阿里云服务器部署我们所实现的机器学习及深度学习项目在网页上,以便于工业使用。
这里我们选择通过阿里云服务器对项目进部署,当然腾讯云服务器也是可以的,操作原理类似。
一.阿里云服务器的购买 1.因为博主目前还是学生,因此可以使用学生的一些信息购买阿里云的学生机,价格可以说是比正常机的便宜很多。配置相对来说也不错,对于自己做做小网站什么的那是足够了。这里顺便附上阿里云学生机服务器的主页:https://promotion.aliyun.com/ntms/act/campus2018.html?spm=a2c4g.11186623.2.10.71564e6bLjLSM8,或者直接在阿里云的搜索栏里直接搜索轻量应用服务器也可以(不过这里我没发现学生优惠的进入渠道)。
2.在选择系统镜像的时候,我们选择宝塔linux面板。它是一种基于Centos系统(Linux其中的一个发行版)的服务器运维管理面板,简单来说就是可以通过Web端的操作,更方便监测、管理我们的服务器。
二.服务器的配置 1.购买完服务器之后,我们通过网页右上方的控制台按钮进入我们购买产品的控制台。
2.点击控制台中已开通的云产品“轻量应用服务器”,进入我们的服务器界面。下面显示的是我之前部署好的服务器的相关信息。
3.如果你是一开始就选择购买的宝塔linux版服务器,应该直接就是正确我们需要的系统了。如果不是的话,可以点界面上的重置系统,进行重新选择安装。
三.宝塔Linux的进入及配置 1.然后我们要进入宝塔linux的操作面板。我们点击页面右上角的远程连接,进入服务器的linux系统。
2.在远程连接界面输入 sudo cat /www/server/panel/default.pl 指令,查询宝塔linux面板的登录密码。
3.进入防火墙开启8888端口,因为我们是通过这个端口访问宝塔linux面板的。
4.复制服务器主页的公网IP。这里我的IP是47.101.143.24。
5.在网页上输入“复制的IP:8888”即可进入宝塔linux操作面板。用户名是admin,密码是刚才我们在远程连接桌面查询到的密码(可以在宝塔面板里修改)。登录后我们直接安装系统推荐的套件即可,我这里显示的是nginx和apache,我选择的是nginx服务器。
6.点击最左侧的网站按钮,之后再点击添加站点。域名因为我没有购买,所以可以直接写上我们的IP地址,如果需要多个网站,我们可以用设置不同的端口即可。
7.查看文件目录下的html文件,网页返回的即是系统的index文件。
8.在网页上输入我们刚才的域名(也就是我们的IP地址),即可看到建站成功,目前所有人都已经可以访问到这个IP地址。后续我们通过修改上面的html文件即可修改我们的网站显示的内容。如果需要域名的朋友们可以自行购买,这样就可以代替IP地址对网站进行访问。
这是本次的所有内容,下节会分享如何在服务器上运行python程序并使用python的flask库,这有利于我们以后在网页上部署tensorflow2.0的深度学习模型。谢谢大家的关看!
内容: 记录shell脚本的三种执行方式以及它们的不同
测试的脚本:打印乘法口诀
方式一: 先进入脚本所在目录,使用 ./ 执行脚本
1.脚本需要有执行权限,通过chmod +x xxx.sh来添加即可。 2.会产生一个子shell来执行脚本,脚本执行完毕后再返回父shell 3.由于是在子shell中执行,脚本设置的变量不会影响当前shell 4.子shell(即子进程)使脚本并行地,有效率地地同时运行脚本内的多个子任务 方式二: 先进入脚本所在目录,使用 bash执行脚本,bash可以简写为sh
1.脚本没有可执行权限或没有指定解析器,使用的方法。 2.会产生一个子shell来执行脚本,脚本执行完毕后 再返回父shell 3.由于是在子shell中执行,脚本设置的变量不会影响当前shell 4.子shell(即子进程)使脚本并行地,有效率地地同时运行脚本内的多个子任务 方式三: 先进入脚本所在目录,使用 source 或 . 执行脚本
1.先读入或加载xxx.sh脚本,然后从上到下依次执行脚本。是在当前的shell执行脚本 2.在一个脚本中需要引用另一个脚本,直接source XX.sh然后这个脚本产生的变量可以在当前脚本中使用。 如果是sh XX.sh则变量获取不了。 3.source的程序主体是bash,脚本中的$0变量的值是bash,而且由于作用于当前bash环境,脚本中set的 变量将直接起效 4.文件可以无"执行权限
Myclass.h #pragma once #include <iostream> using namespace std; class Myclass { public: Myclass(); Myclass(int value) : m_value(value) { } //重载+号运算符 const Myclass operator+(const Myclass & num) const; //重载-号运算符 const Myclass operator-(const Myclass & num1) const; //重载流运算符 friend ostream& operator <<(ostream&, Myclass&); friend istream& operator >>(istream&, Myclass&); int Intvalue() { return m_value; } ~Myclass(); private: int m_value; double real; double imag; }; Myclass.cpp #include "Myclass.h" Myclass::Myclass(): m_value(0) { } /* 重载加号运算符 */ const Myclass Myclass::operator+(const Myclass & num) const { Myclass result(this->m_value + num.
1月27日,武汉本地众多商户联合阿里巴巴旗下饿了么口碑、盒马、飞猪等业务,从衣食住行各个角度,为武汉一线医护人员提供安全、高品质的餐品及生活配套服务。首批100家餐厅已准备就绪。
其中麦当劳、华莱士、大米先生、仟吉KenGee、蔡林记、真功夫、老乡鸡等在武汉当地的店铺已经开始为武汉医护工作人员提供配餐服务。食材供应商“万吨通”等多家商超也在为武汉医护工作人员提供日常生活所需。
目前已经接到武汉市九医院、武汉大学中南医院、湖北省肿瘤医院、武汉市第一医院等10多家医院用餐等各类需求,并根据医院的特殊要求进行配送餐服务。
1月26日傍晚,蜂鸟骑手已经将第一批外卖餐食安全送到武汉的医生护士手中。 1月27日,饿了么采购270份餐食,由蜂鸟骑手送往武汉协和、第六医院、中南医院的医生护士手中。
1月28日,很多餐饮商户听闻后,纷纷表示支持加入。今天,饿了么骑手也继续向武汉医院派送餐食。
目前,大米先生通过饿了么向武汉医护人员捐赠了10000份自热米饭。
为了更好地响应医护工作者的生活服务需要,目前,口碑饿了么已制订“商户极速上线”、“骑手关爱保障”等多项措施,并在武汉首批建立100个生鲜便利服务站等多项有效措施,保障医护工作人员及市民的正常生活需求。
武汉市民只需在当日20:00时前,通过饿了么下单,购买蔬菜水果、肉禽蛋奶等各种商品,第二天即可到上述生鲜便利服务站自行提取或请外卖小哥安全送上门,不用开车出门,也不用到人员密集的场所。
在此,我们也持续呼吁更多商户参与进来,一起为武汉及全国医护工作人员提供切实有力的保障。
相关阅读
点击下方图片即可阅读
驰援武汉,就这么干了!
关注「阿里技术」
把握前沿技术脉搏
Qt Designer 是一个 GUI 设计器,能可视化设计出界面。PyQT5 通过 pyuic5 工具将 Qt Designer 生成的 xxx.ui 文件转换成 python 代码,大大节省手工编写界面代码的工作量。
本篇介绍如何在 PyCharm 中集成 Qt Designer 工具,包括 QT Designer 的配置, pyuic5 的配置和调用界面代码的方法。
pyqt5 可以使用 pip 工具来安装:
pip install pyqt5 安装了 pyqt5 之后,在 python 安装目录下面的 Scripts 文件夹中,有一个 pyuic5.exe 文件,这个可执行文件用于将 Qt Designer 生成的 ui 文件转换为 python 代码。
安装 Qt Designer 在 https://build-system.fman.io/qt-designer-download 这个网址可以下载和安装独立的 Qt Designer 安装版,根据操作系统选择合适的安装文件进行安装。
在 PyCharm 中配置 Qt Designer Qt Designer 安装后,在安装目录下面有一个 designer.exe 文件。打开该程序,以拖拽的方式设计界面元素。设计完成后保存为 xxx.ui 文件。ui 文件为 xml 格式,用于描述窗体和控件的属性。
题目链接:http://codeup.cn/problem.php?cid=100000583&pid=2
题目描述
有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40。John现在有n个想要得到的物品,每个物品的体积分别是a1,a2……an。John可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的口袋,John就可以得到这些物品。现在的问题是,John有多少种不同的选择物品的方式。
输入
输入的第一行是正整数n (1 <= n <= 20),表示不同的物品的数目。接下来的n行,每行有一个1到40之间的正整数,分别给出a1,a2……an的值。
输出
输出不同的选择物品的方式的数目。
样例输入
2
12
28
3
21
10
5
样例输出
1
0
代码 #include<stdio.h> #include<string.h> int pocket[30]; int slect(int a, int b) { if(b == 0) return 1; //选择成功 if(a <= 0) return 0; //选择失败 return slect(a - 1, b)+slect(a - 1, b - pocket[a]); } int main() { int n; while(scanf("%d", &n) != EOF) { for(int i = 1; i <= n; i++) { scanf("
一、DLL的概念 DLL(Dynamic Link Library),动态链接库文件,又称“应用程序拓展”,是软件文件类型,扩展名是“.dll”。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。例如:kernel32.dll中含有LoadLibrary()和GetProcAddress(),ws2_32.dll中含有winsock()函数。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为“共享DLL文件”。
DLL文件中存放的是各类程序的函数(子过程)实现过程,当程序需要调用函数时需要先载入DLL,然后取得函数的地址,最后进行调用。使用DLL文件的好处是程序不需要在运行之初加载所有代码,只有在程序需要某个函数的时候才从DLL中取出。另外,使用DLL文件还可以减小程序的体积。
通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。 例如,一个计帐程序可以按模块来销售。 可以在运行时将各个模块加载到主程序中(如果安装了相应模块)。因为模块是彼此独立的,所以程序的加载速度更快,而且模块只在相应的功能被请求时才加载。此外,可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。 例如,您可能具有一个工资计算程序,而税率每年都会更改。 当这些更改被隔离到 DLL 中以后,您无需重新生成或安装整个程序就可以应用更新。
二、DLL故障排除工具 Dependency Walker
Dependency Walker 工具可以递归扫描以寻找程序所使用的所有依赖 DLL。 当在 Dependency Walker 中打开程序时,Dependency Walker 会执行下列检查:
Dependency Walker 检查是否丢失 DLL。
Dependency Walker 检查是否存在无效的程序文件或 DLL。
Dependency Walker 检查导入函数和导出函数是否匹配。
Dependency Walker 检查是否存在循环依赖性错误。
Dependency Walker 检查是否存在由于针对另一不同操作系统而无效的模块。
通过使用 Dependency Walker,您可以记录程序使用的所有 DLL。 这可能有助于避免和更正将来可能发生的 DLL 问题。 当安装 Microsoft Visual Studio 6.0 时,Dependency Walker 将位于以下目录中:http://www.dependencywalker.com/(下载地址)
DLL Universal Problem Solver
DLL Universal Problem Solver (DUPS) 工具用于审核、比较、记录和显示 DLL 信息。 下表说明了组成 DUPS 工具的实用工具:
注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。
测试环境:Ubuntu 10.10
GCC版本:4.4.5
一、动态内存分配的意义
1) C语言中的一切操作都是基于内存的
2) 变量和数组都是内存的别名
- 内存分配由编译器在编译期间决定
- 定义数组的时候必须指定数组长度
- 数组长度是在编译期就必须确定的
需求:
程序运行的过程中,可能需要使用一些额外的内存空间。
程序编译完毕后,大小就已经固定。
二、malloc和free
1) malloc和free用于执行动态内存分配和释放
程序运行时通过malloc从内存池申请内存,释放内存时通过free函数内存。
2) malloc所分配的是一块连续的内存
3) malloc以字节为单位,并且不带任何的类型信息
4) free用于将动态内存归还系统 void* malloc(size_t size); void free(void* pointer); 三、注意。。。
1) malloc和free是库函数(需要调用相应的头文件),而不是系统调用
2) malloc实际分配的内存可能会比请求的多
3) 不能依赖与不同平台下的malloc行为
4) 当请求的动态内存无法满足时malloc返回NULL(此时内存池用完,内存不足,可以复位)
5) 当free的参数为NULL时,函数直接返回
四、思考
malloc(0);将返回什么?
test.c #include <stdio.h> #include <malloc.h> int main() { int* p = (int*)malloc(0); printf("p = %p\n", p); return 0; } 操作:
1)编译:gcc test.c -o test.
目录
操作符
赋值
追加值
去除价值
添加唯一值
替换值
变量扩展
访问qmake属性
域
域语法
域和条件
配置和域
平台域值
变量
替换功能
测试函数
许多qmake项目文件使用“名称=值”和“名称+=值”定义的列表来简单描述项目使用的源文件和头文件。 qmake还提供了其他运算符,函数和域,可用于处理变量声明中提供的信息。 这些高级功能允许从单个项目文件为多个平台生成Makefile。
操作符 在许多项目文件中,赋值(=)和追加(+=)运算符可用于包括有关项目的所有信息。 典型的使用模式是为变量分配值列表,并根据各种测试的结果附加更多值。 由于qmake使用默认值定义某些变量,因此有时有必要使用remove(-=)运算符过滤掉不需要的值。 以下各节描述如何使用运算符来操纵变量的内容。
赋值 =运算符为变量分配一个值:
TARGET = myapp 上一行将TARGET变量设置为myapp。 这将覆盖先前使用myapp为TARGET设置的任何值。
追加值 +=运算符将新值附加到变量的值列表中:
DEFINES += USE_MY_STUFF 上一行将USE_MY_STUFF追加到要预处理程序定义列表中。预处理器定义列表中的值将用于生成Makefile文件。
去除价值 -=运算符从变量的值列表中删除一个值:
DEFINES -= USE_MY_STUFF 上一行从预处理器定义列表中删除了USE_MY_STUFF。预处理器定义列表中的值将用于生成Makefile文件。
添加唯一值 *=运算符将一个值添加到变量的值列表中,但前提是其尚不存在变量的值列表中。 这样可以防止将值多次包含在变量中。 例如:
DEFINES *= USE_MY_STUFF 在上一行中,如果尚未定义USE_MY_STUFF,则只会将其添加到预处理器定义列表中。 请注意,unique()函数还可用于确保变量仅包含每个值的一个实例。
替换值 〜=运算符将所有与正则表达式匹配的值替换为指定的值:
DEFINES ~= s/QT_[DT].+/QT 在上一行中,列表中以QT_D或QT_T开头的任何值都将替换为QT。
变量扩展 $$运算符用于提取变量的内容,并可用于在变量之间传递值或将其提供给函数:
EVERYTHING = $$SOURCES $$HEADERS message("The project contains the following files:"
工具kali自带,终端中输入setoolkit回车,如果是第一次打开的话会给提示,输入y回车同意使用
1.setoolkit
2.进入软件界面,上方的logo部分这里我就不去截图了,直接看最下方的菜单界面,这里我们选择第一个 social engineering attacks社会工程攻击
3.回车后进入下一个界面,一大串洋文,这里选择第二个,Website Attack Vectors(网站攻击媒介)
4.回车后继续看洋文,我们选择第三个,Credential Harvester Attack Method(凭证收割机)
5.还得回车看洋文,到这一步就是最后一次看菜单了,这里选择第2个,Site Cloner(网站克隆)
6.回车后要求你填写监听的ip地址,因为我们这次攻击的目的是抄一个跟原网站相同的网站界面出来,然后让用户访问并登陆,在输入密码提交之后,这些本来应该隐藏的数据就会被提交到这里我们填写的这个ip地址上,这里我填写了kali的地址
7.要求输入一个需要克隆的网址,直接用百度的网址来测试
8.等一小会儿会出现以下界面,当然因为我们本来是要截取用户名和密码的,但百度的主页面是没有post传值的输入框的,所以它会中途提示我是否继续,这里直接回车就行,证明克隆完成,然后我们在本地访问一下这个网站,因为克隆下来的网站被默认打入了kali的/var/www/html目录中了,可以通过ip访问,下图演示的是我已经从本地访问了一次的效果,可以看到访问的ip是127.0.0.1
9.然后我们在本地浏览器上登陆这个假网站
当然如果抹除了地址栏看起来就非常像了,这边尝试在搜索框里输入一些内容,然后回车
很快你就会发现浏览器跳转了
当然后台也已经截取到了访问该网站的ip
浏览器会正常跳转是因为钓鱼网站的工作原理大致就是这样的,先给你一个高仿页面让你输入用户名密码,然后等你输入完毕点提交的时候页面直接把你转到正规网站上去,你克隆的网站只是一个假身,在假身施法完毕之后会再把你打回真身上去,这种情况就会让人误以为是浏览器卡了没登陆成功,但实际上假身已经把刚才输入的密码都记录下来了。
但这样实在是太不明显了,工具只是截取了一个ip,连内容都没给我取出来,所以这里又开了一台dvwa靶机把上述步骤重做一次。
,..-, ,;;f^^"""-._ ;;' `-. ;/ `. || _______________\_______________________ || |HHHHHHHHHHPo"~~\"o?HHHHHHHHHHHHHHHHHHH| || |HHHHHHHHHP-._ \,'?HHHHHHHHHHHHHHHHHH| | |HP;""?HH| """ |_.|HHP^^HHHHHHHHHHHH| | |HHHb. ?H|___..--"| |HP ,dHHHPo'|HHHHH| `| |HHHHHb.?Hb .--J-dHP,dHHPo'_.rdHHHHH| \ |HHHi.`;;.H`-./__/-'H_,--'/;rdHHHHHHHHH| |HHHboo.\ `|"\"/"\" '/\ .'dHHHHHHHHHHHH| |HHHHHHb`-|. \| \ / \/ dHHHHHHHHHHHHH| |HHHHHHHHb| \ |\ |\ |`|HHHHHHHHHHHHHH| |HHHHHHHHHb \| \ | \| |HHHHHHHHHHHHHH| |HHHHHHHHHHb |\ \| |\|HHHHHHHHHHHHHHH| |HHHHHHHHHHHb| \ | / dHHHHHHHHHHHHHHH| |HHHHHHHHHHHHb \/ \/ .
大家好,我是连人,本期分享线性时间选择问题。
线性时间选择是基于快速排序的一种延申,本质上和快排具有类似的地方。它的目的是找出这个数组中第k小的值。
既然只需找出1个值,我们就不必将整个数组排序。通过分治法和分区(partition)可以只将k所在范围内的值进行查找即可。
当然可以使用二分法去确立k的范围,但是我的课本上没有所以我们今天不讨论。
下面介绍两种算法:随机选择和中位数选择。
随机选择 随机选择是在当前处理的数组中随机挑选一个数,以这个数对数组进行partition操作,判断k与这个数的位置p的关系,如果k<=p,则再将左边进行当前操作,反之则对右边操作,体现了分治的思想。
举个例子。
查找第三小的数字
1,5,7,2,4,8,6
选择了7作为基准
partition后:
1,5,6,2,4,7,8
7的位置是6,3<6,所以将
1,5,6,2,4,7
再进行这次操作,直到数组只剩下一个数,即为所求
可以得知,随机选择在最坏情况下(例如找最大值时总是在最小值处划分)需要将所有元素都遍历一遍,需要O(n2)的时间。尽管如此,该算法的平均性能还是很好。可以证明,随机选择算法可以在O(n)的平均时间内找出n个输入元素中第k小的元素。
他说是,辣就是,反正我也不会证。
下面贴代码:
import random def partition(a, left, right): i = left j = right key = a[left] while i < j: while a[j] >= key and i < j: j -= 1 a[i] = a[j] while a[i] <= key and i < j: i += 1 a[j] = a[i] a[i] = key return i def randomized_partition(a, left, right): if left > right: # 为了保护randint函数的 i = random.
阿里妹导读:新年伊始,国家科学技术奖励大会在北京人民大会堂隆重举行。阿里云获得国家技术发明奖、国家科技进步奖两项国家大奖。这是互联网公司首次同时荣获两大国家科技奖,也实现了互联网公司在国家技术发明奖上零的突破,这意味着阿里巴巴以十年为周期的技术战略进入收获期。
此次阿里云联合上海交大过敏意教授团队开展的“面对突变型峰值服务的云计算关键技术与系统”获得国家技术发明二等奖,背后的相关技术源于超大规模互联网电商场景。早在2009年11月11日,阿里巴巴发起第一届“双十一购物狂欢节”,如何在“突变型峰值”下继续服务好行业新消费模式,就成为阿里巴巴面临的技术难题。十年后的今天,“突变型峰值”场景不降反增,逐渐成为行业技术普遍要解决的,甚至关乎国计民生的问题,比如:交通运输域的“春运抢票”、电子商务域的“秒杀”、全民共聚的“春晚”与“跨年”等大型场景。十多年的战略技术投入,伴随着十多年的云计算成熟之路,阿里云成功解决了“突变型峰值”难题,并通过普惠行业的云计算技术,将能力输送分享到行业的各个领域。
我们将走进获奖背后的故事,为大家介绍其中的技术。
1. 突变峰值的挑战
首先,我们要搞清楚阿里云“突变型峰值下的云计算技术”究竟是什么。
“突变型峰值服务”通常指:相邻单位时间内终端用户请求量显著增长的互联网服务。互联网服务在峰值突变时易出现用户请求响应慢、系统崩溃等后果,比如:
2014年某电商网站在“618”购物狂欢节时,响应慢、网站崩溃;
2015年除夕时某社交app红包出现无响应、交易失败等问题;
虽然云计算在面世之初,弹性能力和近乎无限的资源就是其卖点之一,但是传统的云计算技术面向通用性弹性计算设计,在处理突变型峰值服务时,常容易出现以下几类难题:
“成本高”:应对峰值需求预备容量,成本不节约;
“延迟长”:云中低算力节点负载高,调度不均衡;
“吞吐低”:存储设备扩展故障剧增,回复不迅速;
“扩展慢”:服务镜像仓库网络拥塞,分发不及时;
“运维难”:专家经验演进和查询慢,分析不智能。
阿里云经过多次阵痛和无数工程师的心血,解决了以上难题,造就了十年一剑的“基于容器与混合部署的高效资源整合技术”。
2. 技术探索的起点
阿里巴巴的容器与混部技术绝非一日之功,突变峰值的挑战亦非单一技术点可以应对的。但万事开头难,这些技术突破的起点可以追溯到“双十一”的诞生初期。
2011年,时下整个行业的虚拟化技术正发展得如火如荼,以KVM、XEN以及VMware为代表的虚拟化技术,几乎有着一统基础设施的大势,而阿里巴巴内部以多隆、毕玄为首的一个小团队,剑走偏锋,选择探索一个代号为“t4(淘宝第四代计算引擎)”的项目,t4的技术理念与如今云原生领域的核心技术——容器,恰恰如出一辙。每次提到这段历史,当时阿里的工程师都会提到两点:“扩展效率”与“资源利用率”。一来,“双十一”大促势必会给计算服务带来巨大的流量压力,面对访问峰值时,如何提供后端系统实时的“弹性可扩展能力”是一个技术难题;二来,面对超过日常情况几十倍、甚至几百倍的流量压力,如何做到提升数据中心资源利用率,实现资源不随着流量线性增长?(显然我们不能因为有百倍的流量压力就购买100X的服务器来解决这个问题)。
提出了正确的问题,让阿里巴巴在容器技术上的先行一步,从实际问题出发展开了有针对性的攻坚,为未来打开了道路。
3. 终成一剑的容器化、微服务与混部
容器技术在默默前进的同时,随着双11面临的系统峰值负载压力逐年增加,基础设施采购投入的成本也逐年成指数上升;同时由于日常业务日均仅有10%左右的利用率,新增购置的硬件服务器资源会造成巨大浪费。为此,在2014年,阿里巴巴开始探索混部技术,通过将在线业务和离线大数据计算的负载混部运行在共享的集群中,以期可以显著提高数据中心资源利用率。
在线业务和离线大数据计算这两类负载有多个可以互补的特点,构成了数据中心大规模混部技术的可行性基础:
在数据中心日常态下,在线业务普遍资源利用率较低,且业务峰值压力时间短,或固定在大促脉冲波峰时间,白天压力较大,且对延迟和抖动敏感;
离线业务正好相反,平时资源使用压力较高,业务资源使用较为固定,主要资源压力集中在晚上,重视高吞吐,但对时延不敏感。
直观地看,两类负载只要能跑在共享的集群中,就可以达到提升利用率的目的。但我们的目的并非利用率这个数字,而是所有负载是否可以正常运行。在集群资源利用率较高时,在线和离线业务会发生资源争抢(CPU、内存、网络带宽、IO以及各种微资源)。对于具有超长复杂链路的微服务,在超高集群资源压力下,任何一个环节的延时响应都会造成整个业务链路对外暴露的服务体验下降。如何在混部场景下保证极低的时延和稳定性便成为了历史难题。
为了全方位、系统性地解决这个问题,从2016年起,阿里巴巴用三年时间,通过重建数据中心、全量业务迁移和集团全量业务容器化改造,在早期阿里巴巴业务的微服务化的基础上,形成了基于容器和微服务的统一混部调度资源池,促进了整体基础实施架构的演进升级。下面我们简单列举部分有代表意义的措施。
宏观的资源管理方面,实现在线业务和离线业务调度器的协同工作,在调度层为混部负载之间的隔离建立了良好的技术架构,让两个调度器在各司其职的同时能够最大限度保证在线业务的瞬时需求(保证可以在需要时及时拿到资源)和离线业务的长期需求(保证在给定时间窗口内可以获得足够完成计算任务的资源)。为了降低大规模部署时的资源碎片,工程师们还通过升级智能调度算法,解决类似高维度背包问题,大大提高了服务器的资源部署密度,让同样数目的服务器可以承载更多应用同时正常运行,降低成本:若仅考虑CPU资源,在满足内存、网络带宽、磁盘IO、打散、亲和等约束的同时,将CPU分配率从70%(普通贪心算法)提升到95%以上(智能调度算法)。
微观的资源隔离方面,阿里工程师深入到操作系统和内核当中,针对不同业务特点进行了多方面的努力。在CPU资源分配方面,工程师深度优化了Linux的CFS调度算法,在排队时间、驱逐等级等方面为重要性不同的业务设计优先级,保证重要任务在需要时可以迅速获取CPU资源,降低业务响应时间、提升业务稳定性。在多核处理器环境中,通过Noise Clean等技术,保证了高优先级任务可以充分使用自己所在的CPU核(Hyper Thread)的微资源,进一步保证业务的稳定性。CAT、NUMA、JVM冷内存回收等技术也在这里大放异彩。
在超大规模部署效率方面,阿里云的Dragonfly提供了高效镜像分发技术,实现了指数级别的镜像分发时间的提升,将原本需要数十分钟才可以完成的镜像分发工作降低到数秒之内完成。Dragonfly现在已经是CNCF认可的正式项目之一。
上述这些措施也为集团全面上云,以及云原生升级打实了基础。正是这套完整的资源隔离和弹性共享机制,使得阿里巴巴的大规模数据中心在提高资源利用率的同时,稳定支持了在线业务大促脉冲峰值,最终实现了大促0增量成本投入。 实际上,容器化、微服务、混部这些脱胎于应对“突变型峰值”问题的技术,在大促以外的日常运行带来了更大的经济价值:通过混部技术,阿里巴巴数据中心的日均资源利用率由10%提高到40%,每年节省数十亿成本,实现了历史性突破。2019年阿里巴巴集团基于阿里云智能天然的弹性能力和自研神龙服务器强大稳定的性能,通过混部集群全面上云,实现了基于安全容器的新一代云原生混部技术的架构升级;且通过基于数据智能驱动的运维、调度和管控等创新方法,实现了自动智能化的云原生混部集群管理能力,大大提高了混部集群的业务稳定性,更进一步降低了成本。 4. 走出阿里:从服务内部到普惠社会
为了无法计算的价值,阿里一直把内部多年沉淀下来的核心技术逐步推向社会。一方面通过开源,比如高效轻量的企业级富容器引擎技术Pouch,大规模低耗时的P2P分发系统Dragonfly;另一方面,通过阿里云,让企业可以非常简单的使用全球最具领先的企级容器技术,并享受到云时代带来的技术红利。根据Forrester的第三方报告,阿里云的容器服务能力,中国排名第一。
应对突变型峰值的能力也不例外。阿里云如何通过阿里的容器技术来帮助业界的呢?下面我们就来讲两种在阿里云上常见的峰值问题的解决方案。
4.1 云上电商:让秒杀活动不再被秒杀
电商场景下,它的特点是短时间内峰值较大,而且活动比较频繁。在传统情况下,因为弹性效率不高,所以扩容的资源平时就预置并长期处于就绪状态,费用开销太大,另外扩容的资源需要根据活动的时间来预置,活动越密集运维工作量越大,频繁的进行扩缩容,手工介入越多越容易出错,扩缩的时间长难度大。
在非业务峰值时,保持少量节点维持日常业务,通过业务容器化,业务和运行环境统一进容器镜像,极大的简化部署,并且由K8s来保障业务故障自愈高可靠,弹性伸缩等能力,容器业务的全生命周期管理都交给K8s,简化运维工作量。当业务峰值,原有工作节点已不能满足当前的业务需求,需在大促峰值前快速扩容工作节点的数量。通过已对接弹性伸缩服务ESS的能力,集群具备工作节点自动伸缩能力,我们可提前配置好自动伸缩的规则,而容器化的业务会在工作节点就绪后,迅速自动扩容并调度到可用的工作节点上去,自动配置好网络,并由K8s来保障应用的高可用。当业务峰值结束后,K8s会根据HPA(horizontal pod autoscaler)的能力将业务进行自动缩容,业务缩容后,集群自动伸缩规则会缩容释放工作节点。
4.2 基因计算:让典型计算类型任务也受益于更好的弹性和混合云能力
基因行业中的基因检测计算也是一种典型的计算场景,虽然不像前面的秒杀、双11那样有突发峰值的挑战,但是同样也得益于容器突发弹性场景所锤炼出来的弹性性能和成本优势。目前,国内70%以上的基因测序公司和研究机构都在使用阿里云的服务。在传统的模式下,由于线下资源的限制,需要几天甚至更长的时间才能出得出结果。如果要提升计算效率,那必须要持有大量的计算资源,但这个检测工作又不是每时每刻都需要运行的。如果采用混合云容器弹性计算的方式,那么这个问题就能迎刃而解。当线下的数据采集完成时,通过混合云,把数据传递到云端,并通过容器化的弹性能力,在分钟级内,自动快速拉起成百上千个检测程序,从而快速完成计算。而当检测完成时,又在分钟级内快速销毁资源,极大地降低了资源使用的成本,充分利用了云的能力。除了成本的降低,由于有了阿里云中强大的计算能力作为依托,仅用15分钟,即可完成一个科学界普遍需要120个小时才能完成的高精度个人全基因组测序全流程。
容器已经成为最流行的云的构建方式和最佳的应用运行环境。阿里巴巴自身是容器的重度用户,加上在公有云中通过服务海量客户积累的经验,配合阿里云中弹性计算ECS、神龙服务器、ESS、各种中间件和大数据服务能力等,让阿里云在公有云、专有云或混合云,成为企业级业务上云和数字化改造的最佳实践。
4.3 12306的故事:帮助每个回家的人
12306是我们每个人都熟悉的应用,它是一个以售票业务为核心的交易系统,用户在购票之前需要做余票查询,尤其是在十一、春运这样的特殊情景下,12306必须提供海量数据查询服务,是系统中最重要的一个环节。在传统IT解决方案里,为了每年一次的春运,需要按照峰值采购大量硬件设备;春运后,这些设备会处于空闲状态,造成巨大资源浪费。另一个致命问题是,按照传统方案,如果春运峰值流量超出预期,服务将面临瘫痪,而大规模服务器的采购、上架、部署调试至少需要耗费一两个月时间,是完全来不及的。在这种情况下,将业务上云并且充分利用阿里云提供的弹性能力,可以将成本优势发挥到极致,同时完全满足业务的需求。从十一到春运这些旅游出行高峰时刻,阿里云上的余票查询业务每次扩容的资源交付在分钟级就能完成,并且可以做到在流量洪峰过后将资源进行及时的释放,大大降低成本的同时,也让每个人都能体会到流畅的购票体验。
5、 总结
突变型峰值服务中的云计算技术突破,最初源自阿里巴巴自身的电商特点和阿里工程师们勇于面对困难的精神,也凝结了阿里工程师和国内高校的高水平团队的心血。随着相关技术难点的陆续攻克,我们发现在当前日新月异的发展大潮中,我们的技术可以帮助社会解决更多、更加重要的问题,对此我们深感自豪。这里我们引用邬江兴院士对本项目的评价作为总结:
“‘面对突变型峰值服务的云计算关键技术与系统’体现了我国科技创新的一种特有模式:超大规模市场中蕴含的巨大技术挑战,让很多只有通过大规模应用的经验及教训反复迭代锤炼的技术能够百炼成钢,而且量变的过程必然会伴随质的飞跃,期间无疑会内生出不竭的科技创新动力。过去大家可能对互联网企业有偏见,觉得他们没有硬件厂商技术含量高,但能满足全球最大规模用户群的需求,背后一定是有全球最顶尖的技术能力支撑的。”
又一喜报 阿里巴巴达摩院获得全国人工智能大赛 AI+4K HDR 赛项冠军,识别下方二维码或点击“阅读原文”立刻查看。
你可能还喜欢
点击下方图片即可阅读
阿里开发者工具盘点:用它!让开发事半功倍 整洁的应用架构“长”什么样?
关注「阿里技术」
把握前沿技术脉搏
戳我,查看喜报。
注册事件的方式
ele.on事件类型 = function(){}addEventListener(事件类型,事件处理函数,useCapture) 第三个参数默认是false,冒泡阶段执行attachEvent(事件类型,事件处理函数) 1.第一种方式只能有一个事件处理函数,而第二、三种可以定义 多个事件处理函数
2.addEventListener IE9以下版本以及OPERA7以下版本不支持
3.attachEvent 只有IE6-10版本里支持,IE11及其他浏览器不支持
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <input type="button" value="按钮" id="btn"> <script> var btn = document.getElementById('btn'); addEventListener(btn, 'click', function () { alert('hello world'); }); addEventListener(btn, 'click', function () { alert('hello itheima'); }); // 处理注册事件的兼容性问题 // eventName, 不带on, click mouseover mouseout function addEventListener(element, eventName, fn) { // 判断当前浏览器是否支持addEventListener 方法 if (element.addEventListener) { element.addEventListener(eventName, fn); // 第三个参数 默认是false } else if (element.
在⼩程序的开发⼯具中,勾选 es6转es5语法下载 facebook的regenerator库中的 https://github.com/facebook/regenerator/blob/5703a79746fffc152600fdcef46ba9230671025a/packages/regenerator-runtime/runtime.js在⼩程序⽬录下新建⽂件夹 lib/runtime/runtime.js ,将代码拷⻉进去在每⼀个需要使⽤async语法的⻚⾯js⽂件中,都引⼊(不能全局引⼊) 引入方式 : import regeneratorRuntime from ‘…/…/lib/runtime/runtime’ (一定是这一样行代码引入)
runtime.js 文件中需要拷贝的代码如下:(或者自己到github上去拷贝也可以,github链接地址在第二步上已给出)
/** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var regeneratorRuntime = (function (exports) { "use strict"; var Op = Object.prototype; var hasOwn = Op.hasOwnProperty; var undefined; // More compressible than void 0.
一、安装说明 安装环境:CentOS7 64bit远程服务器终端控制工具:Xshell远程服务器文件上传工具:WinSCP操作权限身份:root 用户 二、安装步骤 1、检查Linux系统是否安装有jdk java -version CentOS7系统中自带有OpenJDK,与经常用到的Java SE的JDK相比,OpenJDK相当于精简版的JDK,要少一部分功能,比如不支持有的服务部署,还有源码的完整性比不上完整版的JDK。
2、查找Linux系统中的java文件 rpm -qa | grep java 3、卸载系统自带的jdk,检查卸载效果 卸载名称包含"-openjdk-"的文件(为了适配不同的Linux版本,有的可能需要把所查找到的java文件都删除)
命令格式:rpm -e --nodeps xxx-openjdk-yyy
具体如下:
rpm -e --nodeps java-1.7.0-openjdk-1.7.0.191-2.6.15.4.el7_5.x86_64 rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.181-3.b13.el7_5.x86_64 rpm -e --nodeps java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64 rpm -e --nodeps java-1.7.0-openjdk-headless-1.7.0.191-2.6.15.4.el7_5.x86_64 ...... 检查卸载效果:
java -version rpm -qa | grep java 4、在/usr/local/路径下创建java目录 mkdir /usr/local/java 5、下载jdk,上传至java目录下 JDK历史版本下载:https://www.oracle.com/technetwork/java/javase/archive-139210.html
本次Linux服务器上安装JDK版本号选择,与Windows主机上保持一致,如:"1.8.0_181"
利用WinSCP以root用户登录Linux服务器之后,从Windows目录将Linux版本jdk的安装包上传至Linux的/usr/local/java目录下:
6、解压jdk,进入java目录查看解压效果 cd /usr/local/java # 解压JDK压缩包 tar -zxvf jdk-8u181-linux-x64.tar.gz # 解压完成后,删除压缩包 rm -f jdk-8u181-linux-x64.tar.gz 7、配置java环境变量,刷新配置 获取jdk安装的绝对路径,作为标识JAVA_HOME
一、Kafka 1、简介 Kafka 是一种高吞吐量的分布式发布订阅消息系统
2、kafka角色必知 producer:生产者。
consumer:消费者。
topic: 消息以topic为类别记录,Kafka将消息种子(Feed)分类, 每一类的消息称之为一个主题(Topic)。
broker:以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一个broker;消费者可以订阅一个或多个主题(topic), 并从Broker拉数据,从而消费这些已发布的消息。
3、经典模型 一个主题下的分区不能小于消费者数量,即一个主题下消费者数量不能大于分区属,大了就浪费了空闲了一个主题下的一个分区可以同时被不同消费组其中某一个消费者消费一个主题下的一个分区只能被同一个消费组的一个消费者消费 4、常用参数说明 request.required.acks
Kafka producer的ack有3中机制,初始化producer时的producerconfig可以通过配置request.required.acks不同的值来实现。
0:这意味着生产者producer不等待来自broker同步完成的确认继续发送下一条(批)消息。此选项提供最低的延迟但最弱的耐久性保证(当服务器发生故障时某些数据会丢失,如leader已死,但producer并不知情,发出去的信息broker就收不到)。
1:这意味着producer在leader已成功收到的数据并得到确认后发送下一条message。此选项提供了更好的耐久性为客户等待服务器确认请求成功(被写入死亡leader但尚未复制将失去了唯一的消息)。
-1:这意味着producer在follower副本确认接收到数据后才算一次发送完成。
此选项提供最好的耐久性,我们保证没有信息将丢失,只要至少一个同步副本保持存活。
三种机制,性能依次递减 (producer吞吐量降低),数据健壮性则依次递增。
auto.offset.reset earliest:自动将偏移重置为最早的偏移量latest:自动将偏移量重置为最新的偏移量(默认)none:如果consumer group没有发现先前的偏移量,则向consumer抛出异常。其他的参数:向consumer抛出异常(无效参数) 二、Kafka安装和简单测试 1、安装kafka(不需要安装,解包即可) # 官方下载地址:http://kafka.apache.org/downloads # wget https://www.apache.org/dyn/closer.cgi?path=/kafka/1.1.1/kafka_2.12-1.1.1.tgz tar -xzf kafka_2.12-1.1.1.tgz cd kafka_2.12-1.1.0 2、启动kafka server # 需先启动zookeeper # -daemon 可启动后台守护模式 bin/zookeeper-server-start.sh config/zookeeper.properties bin/kafka-server-start.sh config/server.properties 3、启动kafka客户端测试 # 创建一个话题,test话题2个分区 bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 2 --topic test Created topic "test". # 显示所有话题 bin/kafka-topics.sh --list --zookeeper localhost:2181 test # 显示话题信息 bin/kafka-topics.
1.前端代码 SSM框架下的jsp文件代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <% String path = request.getContextPath(); %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>Title</title> <script type="text/javascript" src="<%=path%>/js/jquery.min.js"></script> </head> <body> <button name="butt1" >提交</button> <script type="text/javascript"> $(function () { $("button[name='butt1']").click(function () { $.ajax({ url: "<%=path%>/get/submit", //从前端传送过去的数据是json格式的字符串 data:JSON.stringify({"id":1,"Number":"1255655","Flag":"illegalID"}), type: "POST", contentType: "application/json;charset=utf-8", success: function (data) { //后端返回的数据 for(var i = 0; i < JSON.parse(data).length; i++) { console.log(JSON.parse(data)[i]["id"]) console.log(JSON.parse(data)[i]["Number"]) console.log(JSON.parse(data)[i]["Flag"]) } }, //一定要有状态码,知道哪里出错 error: function (XMLHttpRequest, textStatus, errorThrown) { // 状态码 console.
具体步骤如下:
.idea > workspace.xml 中找到 RunDashboard 替换成如下:
<component name="RunDashboard"> <option name="configurationTypes"> <set> <option value="SpringBootApplicationConfigurationType" /> </set> </option> <option name="ruleStates"> <list> <RuleState> <option name="name" value="ConfigurationTypeDashboardGroupingRule" /> </RuleState> <RuleState> <option name="name" value="StatusDashboardGroupingRule" /> </RuleState> </list> </option> </component>
SpringBoot集成thymeleaf做开发遇到的错误 Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field ‘name’ cannot be found on null
详细信息:(片段) org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates//admin/types-input.html]") Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "name" (template: "/admin/types-input" - line 59, col 72) at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393) ~[attoparser-2.0.5.RELEASE.jar:2.0.5.RELEASE] at org.attoparser.MarkupParser.parse(MarkupParser.java:257) ~[attoparser-2.0.5.RELEASE.jar:2.0.5.RELEASE] at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE] ... 53 common frames omitted Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "name" (template: "/admin/types-input" - line 59, col 72) at org.
//本题需要注意的是gets或者getline遇到回车即结束,注意下面***号标注的地方 //getline的使用详见 https://blog.csdn.net/qq_45472866/article/details/104045610 //gets和scanf区别详见:https://blog.csdn.net/tjy199610_10/article/details/78650839 #include<stdio.h> #define MAX 1000 void delchar(char* str, char c); int main() { char str[15][MAX]; char c, n, i; scanf("%d\n", &n); //***必须把\n吃掉,否则下次gets直接读到它结束 for (i = 0; i < n; i++) { gets(str[i]); scanf("%c", &c); getchar(); //***同上 delchar(str[i], c); printf("result: %s\n", str[i]); } return 0; } void delchar(char* s, char c) { int k, i; for (k = i = 0; s[i]; i++) //s[i] 等价于 s[i] != '\0',因为'\0'的ASCII码为0 if (s[i] !
******看完位姿估计原理过一段时间又忘记了,现参考高翔视觉SLAM十四讲做本文笔记。
SLAM中的里程计都是基于特征点方式的算法。
1.特征匹配
特征匹配是视觉SLAM中极为关键的一步,它解决了数据关联问题。通过图像与图像或图像与地图间描述子进行准确匹配,可以为后续姿态估计、优化等操作减轻大量负担。由于图像特征的局部特性、误匹配、重复纹理等,仅利用局部特征很难解决问题。首先讨论图像与图像匹配情况。不同相机匹配原理不一样,2D-2D:对极几何, 3D-3D:ICP, 3D-2D: PnP,本文重点考虑3D-3D的情况。
2.3D-3D: ICP
假设有一对匹配好的3D点:寻找一个欧氏变换R,t使,这个问题使用迭代最近点ICP求解。ICP的求解有两种方式:线性代数的求解(SVD),非线性优化方式(BA).
2.1SVD方法的一般步骤如下:
a.计算两组点的质心位置p,p',然后计算每个点的去质心坐标:
b.根据以下优化问题计算旋转矩阵:.
c.根据第二步的R,计算t:.
2.2非线性优化方法:以迭代方式寻找最优值
以李代数表达位姿时,目标函数可以写成,使用李代数扰动模型得到:。不断迭代找到极小值。具体BA的求解参考https://blog.csdn.net/xranmail/article/details/86486759.
3.李群李代数参考(https://blog.csdn.net/xiaocainiaodeboke/article/details/75041547)
使用2.2中非线性优化方法求解ICP问题时,需用李代数表达位姿。使用重投影计算位姿的表达式为:
.Pi是3D点, ui是Pi对应的像素位置, K为相机内参矩阵,si为ui对应的深度值。直接对上式求导无法解出,因为 T满足以下约束:R为旋转矩阵,它是正交矩阵并且行列式为1,t是平移向量。在求解T的时候,必须考虑到T满足的约束,那么这个问题就变成了有约束优化问题.可以去另外一个空间求解,比如李代数,可以将位姿表达式转化为无约束问题,然后很方便的通过GN法\LM法等优化算法求解。
3.1 群:一种集合加上一种运算的代数结构,把集合记为A,运算记为 .,群可以记为G=(A,.)
群要求这个运算要满足封闭性,结合律,幺元和可逆。矩阵中常见的群有:a.一般线性群GL(n):指n×n的可逆矩阵,它们对矩阵乘法成群;b.特殊正交群SO(n):就是旋转矩阵群,其中SO(2),SO(3)最为常见;c.特殊欧式群SE(n):就是n维欧式变换,其中SE(2),SE(3)最为常见。群结构保证了在群上的运算具有良好的性质,李群是指具有连续性质的群。SO(n),SE(n)在实数空间上是连续的,可以直观的感觉到一个刚体能够在空间中连续运动,所以SO(n)和SE(n)都是李群。那么相机的位姿就可以表示为:
这里说明了相机位姿是特殊欧式群,旋转矩阵是特殊正交群。
3.2李群和李代数相互转化
3.3 李代数的求导
使用李代数解决问题的求导思路分为两种:
step 1. 用李代数表示位姿,然后根据李代数加法来对李代数求导.
step 2. 对李群左乘或者右乘微小扰动量,然后对该扰动求导,成为左扰动和右扰动模型.
step1: 首先关于旋转矩阵对应的李代数SO(3)求导,第一种的求导过程,如下:
这样就得到了旋转后点相对于李代数的导数:,由于旋转矩阵对应的李代数是一个三维向量,所以我们可以用模长与单位向量的乘积表示。ϕ=θa, θ为模长,a为单位向量。
附:f(x)的导数为
step 2.接下来计算旋转矩阵李代数的左扰动模型,左乘一个微小扰动,对微小扰动求导:
,这种方式省去了计算雅克比Jl,
使用左扰动模型SE(3)上的李代数求导如下:
有了李群和李代数相互转换公式,李代数上的导数,那么我们就可以将位姿求解公式用李代数重新表达如下:
,对这个式子使用左扰动模型,利用链式法则展开:
相机投影模型相对于P‘为:,消去s后,
得到,求导的第二项前面已经给出,取出这部分的前三行,然后两个导数项相乘,就可以得到一个2*6的雅克比矩阵:
。如果变换矩se(3)的旋转在前,平移在后,只需要将上式的前面3列和后面3列对调即可。有了李代数表示,下一步可以利用一些优化库(ceres,g2o)计算。
第二个小案例新鲜出炉啦,小人不才,斗胆将其公之于众,请各位大佬手下留情,也希望给出些许建议,万分感谢!
同是天涯码字猿,共勉,共勉!
案例目的:C语言实现登录界面
实现功能:
1.用户登录:用户名、用户密码登录,进入主菜单
密码正确:进入主菜单
密码错误:重新登录或找回密码
找回密码:输入绑定手机号,输入正确,返回账号信息
2.用户注册:注册账号、密码,账户密保,返回登录界面
注册账号:输入用户名:用户名重复,重新输入
输入密码:两次输入密码,密码不同,重新输入
输入验证码:产生验证码,输入验证码,不同重新输入
账户密保:绑定手机号,手机号重复,重新输入手机号
函数声明: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #include<Ctype.h> #include<windows.h> void Exit(void); //退出函数 void Empty(int a); //清空返回 void IdentifyingCode(void); //生成验证码 void Create(void); //用户注册 int TestaCcount(char ch1[11]); //注册辅助函数:账号验证 void security(char ch1[11],char ch2[11]): //绑定手机 int TestaPhone(char ch1[11]); //绑定辅助函数:手机号验证 void Entry(); //登录账号 int TestaPassword(char ch1[11],char ch2[11]);//登录辅助函数:密码验证 void PasswordHelp(void); //密码错误 void FoundPassword (void); //找回密码 主函数:显示登录界面 int main() { int n; do { system("cls"); printf("
Spring学习随记2 spring-IOC之依赖注入 官网地址
XML篇
POM依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.2.RELEASE</version> </dependency> 代码结构 使用@Configuration,@Bean注解代码实现 package com.csh.test.project.annotation.configure; import com.csh.test.project.annotation.service.EmployeeService; import com.csh.test.project.annotation.service.ManagementService; import com.csh.test.project.annotation.service.impl.EmployeeServiceImpl; import com.csh.test.project.annotation.service.impl.ManagementServiceImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created on 2020-01-19. * * @author chensihong */ @Configuration public class AppConfig { @Bean public EmployeeService employeeService() { return new EmployeeServiceImpl(); } @Bean public ManagementService managementService(EmployeeService employeeService) { final ManagementServiceImpl managementService = new ManagementServiceImpl(); managementService.
ServerBootstrap 服务启动类 结构: 继承 AbstractBootstrap 抽象类
使用案例:
ServerBootstrap server = new ServerBootstrap(); server.group(new NioEventLoopGroup(), new NioEventLoopGroup()); // EventLoopGroup接口 server.channel(NioServerSocketChannel.class); // Channel.class类类型 server.childHandler(new ChannelInitializer<Channel>(){ // ChannelHandler接口 initChannel(Channel c){ c.pipeline().addLast(new SimpleChannelInboundHandler<Object>(){ // ChannelHandler接口 channelRead0(ChannelHandlerContext ctx, Object msg) // 发送消息 }); } }); ChannelFutrue future = server.bind(8899).sync(); 方法:group(EventLoopGroup) 配置线程池 group(EventLoopGroup, EventLoopGroup) 创建 NioEventLoopGroup 线程组(池). 为 ServerBootstrap 配置 childGroup 线程池, AbstractBootstrap 父类配置 group 线程池.
(这里暂时未讲解,一个线程池与二个线程池的区别)
方法:channel(Channel.class) 配置传输管道 注意, NioServerSocketChannel 是 NIO 的传输管道. 内部是封装 java.
lucene的概述
Lucene是一个高性能、可伸缩的信息搜索(IR)库。它可以为你的应用程序添加索引和搜索能力。Lucene是用java实现的、成熟的开源项目,是著名的Apache Jakarta大家庭的一员,并且基于Apache软件许可 [ASF, License]。同样,Lucene是当前非常流行的、免费的Java信息搜索(IR)库。
1:ES的概述
ES是对apache lucene的封装。
ES是elasticSearch的缩写,它是一个实时的分布式的查询和分析引擎。它是基于apache lucene开发的。
2:ES的目标是让全文搜索变得简单
3:ES可以支持横向的扩展,支持pb级别的结构和非机构化的数据处理。
4:使用ES可以以前所未有的速度来处理大数据。
5:https://www.elastic.co/cn/点击这个链接,获取更多的信息。
ElasticSearch 的工作原理
我们假设 百度的用的是 ElasticSearch,工作的流程如下,
1:是在百度的搜索框中输入要的关键词信息 。
2:回车或者点击百度一下按钮,
3:把关键词的信息传入到搭建好的ES集群。
4: 把查询到的结果返回 给client。
有俩个前提的条件如下
1:ES集群要搭建好的
2:使用爬虫技术爬取海量 的数据,把爬到的数据存入到这个ES集群的索引中。
ES的应用场景
1:站内的搜索如(淘宝,天猫等。。
2:在数据存储和数据可视化方面是引领者。
3:国外的维基百科 ,github使用ES的搜索引擎,
4:国内的百度,阿里云 等。。
solr的概念
1:solr和elasticsearch一样也是在apache lucene的全文搜索服务器进行开发的。
2:solr和elasticsearch都是基于该apache lucene做的一些封装
三种的区别与联系:
在使用Lucene时仍需要关注搜索引擎系统,例如数据获取、解析、分词等方面的东西。而solr和elasticsearch都是基于该工具包做的一些封装。
Solr是一个有HTTP接口的基于Lucene的查询服务器,封装了很多Lucene细节,自己的应用可以直接利用诸如 …/solr?q=abc 这样的HTTP GET/POST请求去查询,维护修改索引。
solr的安装是比较复杂的,而elasticsearch是比较简单的开箱即用。
Lucene使用上更加灵活,但是你需要自己处理搜素引擎系统架构,以及其他附加附加功能的实现。而Solr帮你做了更多,但是是一个处于高层的框架,Lucene很多新特性不能及时向上透传,所以有时候可能发现需要一个功能,Lucene是支持的,但是Solr上已经看不到相关接口。
solr和elasticsearch都是基于Lucene实现的!
其次
solr利用zookpper进行分布式管理,而elasticsearch自身带有分布式协调管理功能;
solr比elasticsearch实现更加全面,solr官方提供的功能 更多,而elasticsearch本身更注 重于核心功能,高级功能多由第三方插件提供;
solr在传统的搜索应用中表现好于elasticsearch,而elasticsearch在实时搜索应用方面比solr表现好!
es天生就是为分布式而生的,而solr在4.x以后 才逐渐支持
es只支持json的格式,而solr支持更多的格式如csv,json,xml;
solr 在查询时速度较快,但是更新索引(插入删除)时比较慢的,适合用于查询多的业务,
es在建立索引快,查询快, 适合新兴的的实时搜索应用。
1、拉取Tomcat镜像并启动tomcat容器 1、拉取tomcat镜像 [root@localhost /]# docker pull tomcat(#拉取tomcat镜像,不指定TAG,默认表示拉取最新版本的) Using default tag: latest latest: Pulling from library/tomcat ..................... 2、启动tomcat容器 [root@localhost /]# docker run --name my_tomcat -it -d -p 8080:8080 tomcat(#在后台启动tomcat容器,容器名称为my_tomcat,虚拟机端口号为8080,tomcat默认端口号为8080) c2a785689e09704a4281709c0641eddac1acd639e38c36cca350632628537a36 (#注意:第一个端口号是宿主机的端口号,用来对应tomcat的端口号,可以自定义,第二个端口号是tomcat的默认端口号,一般不修改,如果要变更,则需要更改tomcat的配置文件) [root@localhost /]# docker ps(#查看本地正在运行的容器) CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c2a785689e09 tomcat "catalina.sh run" 14 seconds ago Up 5 seconds 0.0.0.0:8080->8080/tcp my_tomcat 3、本地访问tomcat首页 192.168.79.128:8080 2、查看Docker宿主机的ip地址 3、在虚拟机(此处Centos7安装在VMware中)中打开浏览器,访问tomcat 注意:如果使用上面的地址无法访问到tomcat,可以检查一下tomcat的首页是否存在 使用命令: docker exec -it 运行的tomcat容器ID /bin/bash 进入到tomcat的目录 进入webapps文件夹,发现里面是空的(tomcat默认的欢迎页面实际上放在的路径应该是:webapps/ROOT/index.jsp或者index.html) 发现旁边还有个webapps.dist的文件,进入才发现原本应该在webapps文件中的文件都在webapps.dist文件中,现在也不知道为什么!!! [root@localhost /]# docker exec -it my_tomcat /bin/bash(#进入到启动好的tomcat容器中去) root@4bc234fa03cf:/usr/local/tomcat# ls BUILDING.
Spring学习随记1 spring-IOC之依赖注入 官网地址: https://docs.spring.io/spring/docs/5.2.2.RELEASE/spring-framework-reference/core.html#beans-factory-collaborators 涉及名词: IOC:Inversion of Control控制反转 DI:dependency injection 依赖注入 IOC和DI之间的关系:IOC是一种解耦思想,DI是IOC的一种实现方式 依赖注入的实现 1.构造器注入 2.setter方法注入 3.接口注入(传闻早期有,但不人性故被移除,自由鸡没找相关文档,!·_·!) 代码结构 POM依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.2.RELEASE</version> </dependency> 构造器注入 代码实现 package com.csh.test.project; import com.csh.test.project.service.ManagementService; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Hello world! */ public class App { public static void main(String[] args) { //加载xml元数据 ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("beanXml.xml"); // 从容器中获取ManagementService bean ManagementService managementService = cxt.getBean(ManagementService.class); } } EmployeeService.java
package com.csh.test.project.service.impl; import com.csh.test.project.service.EmployeeService; /** * Created on 2020-01-17.
cJSON移植 参考博客
cJSON下载 下载地址
下载源码链接解压源码
其中cJSON.c,cJSON.h便是要使用的源码。 cJSON配置 添加源码
使用cJSON要用到malloc相关函数,所以要添加cJSON源码和malloc源码到工程中。
修改源码 修改堆栈大小Heap_Size EQU 0x00001000修改cJSON源码malloc,free函数为my_malloc,my_free函数,代码如下: /* Copyright (c) 2009 Dave Gamble Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
线性表的定义 由n(n>=0)个数据特性相同的元素构成的有限序列称为线性表。
线性表中元素的个数n(n>=0)定义为线性表的长度,n=0时称为空表。
对于非空的线性表或线性结构,其特点是:
1.存在唯一的一个被称作“第一个”的数据元素;
2.存在唯一的一个被称作“最后一个"的数据元素;
3.除第一个之外,结构中的每个数据元素均只有一个前驱;
4.除最后一个之外,结构中的每个元素均只有一个后驱。
线性表的顺序表示和实现 线性表的顺序表示指的是用一组地址连续的存储单元一次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像。通常,称这种存储结构的线性表为顺序表。(特点:逻辑上相邻的数据元素,其物理次序也是相邻的)
假设线性表的每个元素需占用l个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储起始位置。则线性表中的第i+1个数据元素的存储位置LOC(ai+1)和第i个数据元素的存储位置LOC(ai)之间满足下列关系:
LOC(ai+1)=LOC(ai)+l
一般来说,线性表的第i个数据元素ai的存储位置为:
LOC(ai)=LOC(ai)+(i-)*l
线性表的顺序存储结构示意图如下
由此可知,只要确定了存储线性表的起始位置,线性表中任一数据元素都可随机选取,所以线性表的顺序存储结构是一种随机存取的存储结构。
由于线性表的长度可变,且所需最大存储空间随问题不同而不同,则再C语言中可用动态分配的一维数组表示线性表,描述如下:
#define MAXSIZE 100 typedef struct { ElemType*elem; //存储空间的基地址 int length; //当前长度 }SqList; //顺序表的结构类型为SqList 注:*1.元素类型定义中ElemType数据类型是为了描述统一而自定的,在实际应用中,用户可根据实际需要具体定义表中数据元素的数据类型,既可以是基本数据类型,如int、float、char等,也可以是构造数据类型,如struct结构体类型。
2.length表示顺序表中当前数据元素的个数。因为C语言数组的下标是从0开始的,而位置序号是从1开始的,所以要注意区分元素的位置序号和该元素在数组中的下标位置之间的对应关系。*
多项式顺序存储结构的类型定义如下:
#defne MAXSIZE 100 //多项式可能达到的最大长度 typedef struct //多项式非零项的定义 { float coef //系数 int expn //指数 }Polynomial; typedef struct { Polynomial *elem; //存储空间的基地址 int length; //多项式中当前项的个数 }SqList; //多项式的顺序存储结构类型为SqList 图书表的顺序存储结构的类型定义如下:
#defne MAXSIZE 10000 //图书表可能达到的最大长度 typedef struct //图书信息定义 { char no[20]; //图书ISBN char name[50]; //图书名字 float price; //图书价格 }Book; typedef struct { Book*elem; //存储空间的基地址 int length; //图书表中当前图书个数 }SqList; //图书表的顺序存储结构类型为SqList 在上述定义后,可以通过变量定义语句 SqList L; 将L定义为SqList类型的变量,便可以利用L.
WinPcap卸载后安装问题
通常winpcap的根目录:C:\Program Files\WinPcap。。。一般里面会有个"uninstall.exe"也可使用卸载。
卸载WinPcap.exe后,重新安装,错误提示:
A newer version of WinPcap (internal version 5.0.9986.1217 is alreadyinstalled on this machine.The installation will be aborted.
解决办法:
找到相应文件,并把扩展名修改即可:
● C:\Windows\SysWOW64 的wpcap.dll改成 wpcap.dll.old
● C:\Windows\SysWOW64的packet.dll改成 packet.dll.old
https://blog.csdn.net/hs_err_log/article/details/79646455
https://blog.csdn.net/jack2code/article/details/7684806
1.模糊测试概念: 模糊测试 (fuzz testing, fuzzing)是一种软件测试技术。其核心思想是自动或半自动的生成随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏。模糊测试常常用于检测软件或计算机系统的安全漏洞。
我们使用维基百科的这个定义,然后着重讲一下“随机数据”长什么样,又如何“输入到另一个程序中”。
2.模糊测试方法: 模糊测试(fuzz testing)和渗透测试(penetration test)都是属于安全测试的方法,它们有同也有异。
渗透测试:渗透测试一般是模拟黑客恶意入侵的方式对产品进行测试,对测试者的执行力要求很高,成本高,难以被大规模应用。
模糊测试:模糊测试通过向应用提供非预期的输入并监控输出中的异常来发现软件中缺陷,整个执行过程依靠工具进行自动化或半自动化测试。模糊测试技术具有自动化程度高、可用性好、误报率低, 对目标程序源码没有依赖等优点。它能够充分利用机器本身,随机生成和发送数据;与此同时,又能够引进业内安全专家在安全性方面的建议。模糊测试其数据具有不确定性,也没有明显的针对性,简单来说就是没有逻辑,没有常理。只要将准备好的那些杂乱的程序插入其中,然后等待bug的出现,而出现的漏洞是渗透人员先前无法预知的。
模糊测试执行过程主要包含几个基本阶段:
(1)识别测试目标
确定明确的测试目标,才能决定使用的模糊测试工具或方法。比如需要选择应用包含的特定文件或者库作为测试目标,需要把注意力放在多个应用程序之间共享的那些二进制代码上。因为如果这些共享的二进制代码中存在安全漏洞,将会有非常多的用户受到影响,因而风险也更大。
(2)识别输入
大部分可被利用的安全漏洞都是由于应用没有对用户的输入进行校验或是进行必要的非法输入处理。是否能找到所有的输入向量(Input vector)是模糊测试能否成功的关键。寻找输入向量的原则是:从客户端向目标应用发送的任何东西,包括头(Headers)、文件名(File Name)、环境变量(Environment variables),注册表键(Registry keys),以及其他信息,都可能是潜在的模糊测试变量。
(3)生成模糊测试数据
大多数模糊测试的方法是通过向目标系统不断输入可以诱发软件缺陷的测试数据,因此测试数据的生成是模糊测试非常关键的环节,主要依赖测试目标系统的特点和数据格式进行生成。
(4)执行模糊测试数据
自动化地向被测的系统发送数据包、打开文件、或是执行被测应用的过程。这个阶段一般与生成测试数据并行进行。
(5)监视异常
监控异常和错误是模糊测试中重要但经常容易被忽略的步骤。模糊测试需要根据被测应用和所决定采用的模糊测试类型来设置各种形式的监视。
(6)判定发现的漏洞是否可被利用
在模糊测试中发现了一个错误,需要判定这个被发现的错误是否是一个可被利用的安全漏洞。这种判定过程既可以由模糊测试的执行者来进行,也可以交给安全测试专家来进行。
模糊测试技术的应用十分广泛, 可以测试的对象种类繁多, 比如环境变量和参数、 Web 应用程序、文件格式、网络协议、Web 浏览器和物联网系统等方面。
3.模糊测试工具: 半自动模糊测试工具burpsuite bed只能对协议的标准请求、标准头部进行模糊测试,对http的post等自定义的主体的各项是没法进行模糊测的,但其实这部份才是我们要测试的主要部分,所以单依靠bed是不行的。
burpsuite的intruder就是一个高度可配置的模糊测试功能,intruder只要设置好变量然后在payloads中设置好测试用例,即可进行模糊测试。
全自动模糊测试工具backfuzz 工具下载 https://github.com/localh0t/backfuzz
详细运行结果见案例分析
手动编写模糊测试工具boofuzz 一个小姑娘照片,很可爱的boofuzz工具
工具下载 https://github.com/jtpereyda/boofuzz
WEB管理界面:http://192.168.56.113:26000
详细运行结果见案例分析
分析 1、模糊测试的优点
与传统漏洞挖掘方法相比, 模糊测试技术有其无法比拟的优势。模糊测试的测试目标是二进制可执行代码, 比基于源代码的白盒测试适用范围更广;模糊测试是动态实际执行的,不存在静态分析技术中存在的大量误报问题;模糊测试的原理简单,没有大量的理论推导和公式计算,不存在符号执行技术中的路径状态爆炸问题;模糊测试自动化程度高,不需要逆向工程中大量的人工参与。模糊测试技术的优点使它成为一种应用范围广泛的漏洞挖掘技术。
2、模糊测试的局限性
(1) 对访问控制漏洞无能为力,因为模糊测试系统无法理解程序的逻辑,所以如一些违反权限控制的安全漏洞难以发现。
(2) 受制于糟糕的设计逻辑。糟糕的设计逻辑并不会导致程序崩溃,而模糊测试发现漏洞一个主要依据是监控目标系统的异常和错误信息,因此模糊测试难以发现这类漏洞。
(3) 无法识别多点触发漏洞,当前的模糊测试技术往往只能挖掘出由单个因素引起的漏洞,而对于需要多条件才能触发的漏洞却无能为力。
建议 1、目前,Web应用中存在大量拒绝服务(Dos)、跨站脚本(XSS)、SQL注入(SQL injection)等漏洞,Web应用模糊测试不仅可以发现Web应用本身的漏洞,还可以发现Web服务器和数据库服务器的漏洞。建议通过模糊测试的方法和工具,对Web应用进行漏洞挖掘。
2、Android在手机的市场上占有率很高,通过模糊测试不但可以发现钓鱼欺诈、拒绝服务和权限提升等Android的常见漏洞,而且可以对App的稳定性进行分析验证。建议通过模糊测试的方法和工具,对App的Android版进行漏洞挖掘。
3、随着智能手机、可穿戴设备、活动追踪器、无线网络、智能汽车、智能家居等终端设备和网络设备的迅速发展和普及利用,针对物联网设备的网络攻击事件比例呈上升趋势,攻击者利用物联网设备漏洞可入侵设备,获取设备控制权,通过控制大量物联网设备,黑客可以发起分布式拒绝服务网络攻击(DDoS)。建议利用模糊测试,对物联网的网络协议和设备进行漏洞挖掘。
4、随着业务发展和技术升级需要,会引入一些开源软件或者免费软件,而据Google的报告,开源软件或者免费软件的安全漏洞还是非常多,建议通过模糊测试的方法和工具,在引入开源软件或者免费软件的过程,做安全风险评估。
5、针对业务特点和系统特征,构造模糊测试数据知识库,提升模糊测试数据的针对性,通过人工智能优化模糊测试数据生成和自动化执行过程,构建模糊测试平台,提供安全测试的服务给分行或者行外客户使用。
Vector graphic
A vector graphic file contains a drawing list.The list contains a command for each object included in the imageThe objects are defined by geometrical formula and associated properties, such as line color and style.When a vector graphic need to be magnified, the file is read, the appropriate calculations are made and the objects are redrawn to a suitable scale.This means that vector graphic is scalable. The image would not get blur or distorted when magnified.
首先放效果图:
# -*- coding: utf-8 -*- import numpy as np import tensorflow as tf from matplotlib.path import Path from matplotlib.patches import PathPatch import matplotlib.pyplot as plt import matplotlib from matplotlib.animation import FuncAnimation import matplotlib as mpl import datetime import time import re import urllib.request np.set_printoptions(suppress=True) mpl.rcParams['font.sans-serif'] = ['SimHei'] #指定默认字体 SimHei为黑体 mpl.rcParams['axes.unicode_minus'] = False #用来正常显示负 import requests import re import hashlib #测试数据 osm的点线面数据 #测试主机 8G 4核 1T机械盘 #mysql 5.7.23 #postgresql 12 #dameng 7 #oracle 19c 19.
遇到协定:比如电商数据,不想被百度收录,所以做了声明,你别爬,如果爬取,我就告你,并且在其网站有着相关的协定页面,比如“https://www.taobao.com/robots.txt”。(办法:别去冒犯有协定的页面。)header读取:通过读取你的header信息,看看你是不是真浏览器,看你的各种参数是否符合正常用户,如果不符合,就禁止你访问数据。(办法:我们可以在请求时模仿header。)用户登录后才能访问:有些数据是只有登录后才能访问的,一般网站把登录数据都记录在session中。(办法:先用一个用户登录一下,然后请求的时候带上cookie,在客户端其实session信息也是写在cookie里面的。)限制ip:爬数据时,因为访问网站的评率过高,所以网站把你的ip放入了黑名单,导致你当前ip的客户端无法访问它的数据。(办法:用多个ip( adsl拨号 / 代理IP ) 。)验证码:爬数据时,因为访问网站的评率过高,或者其它原因,网站会返回验证码,如果填写不正确,就无法继续访问数据。(办法:有开源组件做图片识别 / 打码平台)数据js动态加载:有些网页数据不是一次性全部加载,而是滚动条往下拉一下,加载一下,在这种情况下你无法直接爬取到全面的数据。比如vue的懒加载。(办法:根据js方法的特点来抓取数据。)文字转图片:有些网站为了不让你爬取数据,会把网页文字内容转成图片。(办法:用第三方的文字识别技术。)js收集用户操作辨识你是否真人:记录你鼠标移动的数据,然后传上去。如果你没有鼠标的移动,那么就不认可你是正常访问。(办法:跟踪它的js记录数据的方法,然后伪造相关参数。)用户控件(安装在浏览器上的插件):可以搜集客户端的更多信息,比如本地的硬件信息啥的,所以你换ip也没用了。(办法:暂时没有。)
1:首先看效果图
2::这里是使用的table表单组件,组件里面有一个 expandRow 属性需要使用,所以需要引入,我是只有一个组件需要这个属性,所以直接在组件中引入
import expandRow from "../modal/expandRow.vue"; 3:在根据render函数的方式使用
columns1: [ { type: "expand", width: "50px", render: (h, params) => { let list = params.row.train_data; return h(expandRow, { props: { row: list } }); } }, { 3.1这里官网也有说明
4:这个时候你就需要在新建新的组件,并在当前项目中引入,我新建了expandRow组件
5:在组件中写好自己需要的内容
<template> <div class="expand-row"> <Table :data="row" :columns="columns2" size="small" ref="table"> <template slot-scope="{row}" slot="audit_status"> <span v-if="row.audit_status==1" style="color:green">已通过</span> <span v-else-if="row.audit_status==0" style="color:orange">未审核</span> <span v-else-if="row.audit_status==-1" style="color:red">未通过</span> </template> <template slot-scope="{row}" slot="record_date" v-if="row.record_date" >{{row.record_date | dateFmt("YYYY-MM-DD") }}</template> </Table> </div> </template> <script> export default { props: { row: Array 子组件中需要通过props来接收父组件传来的值
制作视频录制功能时,经常遇到明明应用的图像播放时正常的,但录制出来的图像缺偏黑。
------原因:
这种情况一般发生在应用使用线性空间渲染的方式;即playersettings-》colorspace 是linear渲染模式。
graphics api 要使用 ipengles3;
视频录制一般采用RenderTexture 进行图像采样; 但因为线性空间渲染 会在OnRenderImage 后进行屏幕投射时进行一次gamma校正;即图像提亮;
这个时候的RenderTexture 的图像就是偏暗的设置。
------解决方法
在OnRenderImage 里面将src 用shader进行一个gamma处理,
private void OnRenderImage (RenderTexture src, RenderTexture dst) {
Graphics.Blit(src, frameTexture , recordingMaterial);
Graphics.Blit(src, dst);
}
---frameTexture 就是我们视频需要的RenderTexture
var frameTexture = RenderTexture.GetTemporary(
videoFormat.width,
videoFormat.height,
24,
RenderTextureFormat.ARGB32,
RenderTextureReadWrite.sRGB,
1
);
---shader:
fixed4 frag(v2f i) : COLOR
{
//从_MainTex中根据uv坐标进行采样
fixed4 renderTex = tex2D(_MainTex, i.uv)*i.color;
//brigtness亮度直接乘以一个系数,也就是RGB整体缩放,调整亮度
fixed3 finalColor = renderTex * _Brightness;
finalColor = pow(finalColor, 1.
前言 STM32F4xx系列是ST公司高性价比产品,由于可以很方便的移植RTX-RTOS系统,在多线程程序开发上有很多的优势,但是在多线程并发情况下,如何合理的进行线程切换与调度,充分发挥芯片性能,解决线程间冲突,是迫切需要解决的问题。MDK5.25版本以后提供了新的System analyzer,可以方便的跟踪和统计线程的工作情况,由于网上资料较少,花了一天时间终于弄明白了System analyzer的使用,共享给大家,个人的经验,高手请绕路。
实现 下面是基于HAL库的多线程工程建立以及多线程程序实现过程,每一步基本上都有截图和说明。
工程使用STM32CubeMx生成,没有STM32CubeMx软件的上官网下载,STM32CubeMx的优点太多了,将繁琐的芯片配置过程图形化了,强烈推荐。
打开软件,建立工程,选择一款芯片,本例选择STM32F405ZGTx,引脚配置如下图,首先配置调试端口为SWD,并切换系统时钟基准为任意一个TIM,这是由于RTOS要特殊使用SysTick时钟,此处选择了TIM14;
配置RCC为外部时钟,虽然芯片内部时钟也能工作,但是误差可能有些大,还是外部时钟比较保险,可以看到配置完后,右边芯片图上时钟引脚和调试口引脚已经是绿色的了;本例使用了两个LED作为输出显示,这两个LED连接在PF9和PF10两个IO上,因此配置这量IO为输出,具体配置方法为在芯片图中的具体IO管脚上点鼠标左键,选择GPIO_Outpu即可,为了方便使用,在IO管脚上点鼠标右键,设置UserLabel为LED1和LED2;
配置完后可以在左边列表中看到这两个IO,可以进一步设置上拉下拉,输出模式什么的,本例不用上下拉,是推挽输出;
切换到芯片的Clock Configuration配置系统时钟,由于使用了外部晶振,可以将芯片调整到最快工作频率,注意不要有红色的错误即可; 6. 切换到ProjectManager页配置工程属性,这里有两个需要注意的地方,一个是Project下面的Toolchain/IDE和版本,要按照安装的IDE设置,由于本例使用了MDK-ARM5.27,故如图设置即可,另一个是Code Generator页的Generated files下面的第一个选项决定了是否单独产生.c/.h文件,选上有各种设备都单独生成.c/.h,而不是生成在一起;
7. 保存工程后,点击最后的GENERATE CODE生成工程代码,主要工程位置在ProjectManager中指定了。生成代码后会提示是否打开工程,当然要打开了;
8. 打开工程如下图所示,可以展开各个文件夹看一下文件组织结构,并编译工程,工程很干净,初始化已经完成了,LED引脚定义在main.h中;
接下来添加RTOS支持,点击工具栏中的RTE按钮,如果找不到看下图中倒数第二个;
RTE是运行环境管理,可以很方便的加入各种组件,但是和STM32CubeMx有一些冲突,这也是为什么在STM32CubeMx中配置时没有选择Middleware中的FreeRTOS的缘故,FreeRTOS和CMSIS-RTOS还是有很大区别的,选择如下图中的组件,注意KeilRTX5一定要改成Source,就是加入源代码而不是直接使用库文件。主要是要选择Compiler下面的EventRecorder和KeilRTX5,如果有警告信息,可以点击左下角的Resolve按钮自动添加缺少的子组件;选择完成,点击OK后工程目录如下图所示,有三个绿色的运行环境,此时编译会出一大堆错误,是重复引用导致的; 12. 下面的工作是去除重复引用,在Device上点右键,选择Options for Component Class或者按Alt+F7,去掉Include in target build前的勾,在编译时不编译即可;
不再包括Device的启动代码的工程视图如下所示,Device部分变成灰色了,而且文件名上有一个红色的禁止编译符号;
13. 然后再注释掉stm32f4xx_it.c文件中的三个中断处理函数SVC_Handler,PendSV_Handler和SysTick_Handler,如下面三个图所示,再编译就没有错误了;
14. 在main.h中加入头文件,增加对RTOS2的引用,注意头文件位置,要写到USER CODE中,以便以后用STM32CubeMx更新代码时不破坏自己的代码;
#include “RTE_Components.h” // Component selection
#include “cmsis_os2.h” // ::CMSIS:RTOS2
15. 在main.c中增加两个线程句柄,用于线程操作,定义两个函数void thrLED1(void *argument)和void thrLED2(void *argument),这两个函数的具体实现放在USER CODE BEGIN 4后面,声明放在USER CODE BEGIN PFP后面,这两个线程就是我们需要使用的工作线程了;
另外再声明一个函数void app_main(void *argument)作为主线程,也将声明和实现分别放在USER CODE BEGIN PFP和USER CODE BEGIN 4部分;
16. 在USER CODE BEGIN 2部分调用OS的初始化和创建主线程的代码如下:
一:final 指定某个虚函数不能再子类中被覆盖,或者某个类不能被子类继承
解释:
当在虚函数声明或定义中使用时,final 确保函数为虚并指定其不可被派生类覆盖。若这么做则程序非良构(生成编译时错误)。
当在类定义中使用时,final 指定此类不可在另一类的定义中的 基类说明符列表
中出现(换言之,不能派生于它)。若这么做则程序非良构(生成编译时错误)。final 亦可用于联合体定义,此情况下它没有效果(除了
std::is_final 的输出结果),因为不能从联合体派生。
final 是在成员函数声明或类头部中使用时有特殊含义的标识符。其他语境中它未被保留,而且可用于命名对象或函数。
例子:
struct Base { virtual void foo(); }; struct A : Base { void foo() final; // Base::foo 被覆盖而 A::foo 是最终覆盖函数 void bar() final; // 错误:非虚函数不能被覆盖或是 final }; struct B final : A // struct B 为 final { void foo() override; // 错误:foo 不能被覆盖,因为它在 A 中是 final }; struct C : B // 错误:B 为 final { }; 二:override 指定一个虚函数覆盖另一个虚函数
准备
关闭防火墙
systemctl stop firewalld setenforce 0 1.安装squid
yum install -y squid 2.编辑squid配置文件
vim /etc/squid/squid.conf 添加 acl local src 0.0.0.0/24 #允许0.0.0.0/24网段内所有客户机访问代理服务器 http_access allow local #该记录一定要添在deny all之前,允许本地访问 3.启动squid服务
systemctl start squid systemctl enable squid 4、测试
linux客户端配置正向代理
export http_proxy=http://10.30.3.30:3128 #10.30.3.30是代理服务器ip,http
export https_proxy=http://10.30.3.30:443 #https
echo "export http_proxy=http://10.30.3.30:3128" >>/etc/profile echo "export https_proxy=http://10.30.3.30:3128" >>/etc/profile source /etc/profile yum -y install httpd wget https://codeload.github.com/gflags/gflags/tar.gz/v2.1.2 使用谷歌浏览器测试一下
点击设置
访问百度成功
一些常见配置,只是一些参数的解释,看下就可以
http_port 3128 (还可以只监听一个IP http_port 192.168.0.1:3128)
cache_mem 64MB #缓存占内存大小
JAVA环境添加
setx /M JAVA_HOME “D:\YM-cnmmm.com\bl20166\Java\jdk1.8.0_144”
setx /M CLASSPATH “.;%%JAVA_HOME%%\lib\dt.jar;%%JAVA_HOME%%\lib\tools.jar”
setx /M PATH “%PATH%;%%JAVA_HOME%%\bin”
游戏解压到D盘:D:\YM-CQ 解压完检查路径是否正确 服务端与客户端默认IP:YM-CQ
游戏架设启动必须安装【虚拟网卡】。百度下找到自己对应的系统,安装虚拟网卡.
按百度图文教程安装完毕即可,安装完成后无需任何其他操作。
注意:【[0].安装虚拟网卡(运行二次即可).vbs】这个WIN10系统无法使用,需要手工安装并修改虚拟网卡IP为YM-CQ
虚拟网卡安装完成以后,安装2个必备环境:
1.首次运行游戏需要打开一次【[99].java环境添加.bat】第一次需要,以后不需要了。
WIN10无法使用,需要手工添加环境,java地址:D:\YM-CQ\bl20166\Java\jdk1.8.0_144 参考教程:https://blog.csdn.net/qq_41343528/article/details/103802032
2.安装【[98]安装环境.exe】首次安装,以后就不需要了。
以上全部安装结束以后,开始启动游戏:
第一步:【[0].安装虚拟网卡(运行二次即可).vbs】【注意:QQ管家等会拦截,需要点击(允许),如果不愿意使用,需要手工修改虚拟网卡IP为YM-CQ】
第二步:【[02]启动数据】【打开之后,点击启动,正确为2个绿灯,如果出现红灯,请百度搜索解决办法,如:phpStudy红灯】
第三步:打开【[03]启动服务】
第四步:打开【[04]启动一区】【如有需要,可以启动完后再启动[05]启动二区】
第五步:打开【[06]启动跨服】
第六步:最后把【幽冥新版.apk】安装到安卓模拟器,就可以开始游戏了。
【游戏服务端启动时间约3-5分钟】
GM工具:http://YM-CQ:82/gm/ GM校验码:20166
注意:角色名字输入:S1.有分享幽冥 把【有分享幽冥】改成你自己的游戏名字。
游戏运营后台:http://IP:82/gameback/admin.php
运营后台帐号:admin
运营后台密码:admin
游戏外网修改:
服务端修改:
D:\YM-CQ\www\args.php和args_ios.php
D:\YM-CQ\www\api\notice.php
D:\YM-CQ\build_pub\Server\LogicServer\crossserver.txt
D:\YM-CQ\build_pub\Server2\LogicServer\crossserver.txt
D:\YM-CQ\build_pub\Server跨服\LogicServer\crossserver.txt
【推荐使用Notepad++修改把里面的ipYM-CQ为你服务器外网ip】
客户端修改:
安卓\assets\data\scripts\platform\platform_adapter.lua
苹果\Payload\cq.app\data\scripts\platform\platform_adapter.lua
【推荐使用Notepad++修改把里面的ipYM-CQ为你服务器外网ip】
游戏上线奖励修改:搜索服务端文件夹DefaultConfig.lua
本题的目标很简单,就是判断一个给定的正整数是否素数。
输入格式:
输入在第一行给出一个正整数N(≤ 10),随后N行,每行给出一个小于2^31 的需要判断的正整数。
输出格式:
对每个需要判断的正整数,如果它是素数,则在一行中输出Yes,否则输出No。
输入样例:
2 11 111 输出样例:
Yes No 模板题,直接写一个判断是否是素数的代码就可以了
代码:
#include<bits/stdc++.h> using namespace std; int isprime(int x) { if(x<2) return 0; for(int i=2;i<=sqrt(x);i++) if(x%i==0) return 0; return 1; } int main() { int n,x; cin>>n; while(n--) { cin>>x; if(isprime(x)) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
严格弱序
是二元谓词bool = f(x,y)的特性。
如果对于f(x,y),总是有以下三个条件满足:
1)非自反性
f(x,x) == false
2) 非对称性
f(x,y) == !f(y,x)
3) 传递性
若f(x,y)==true , f(y,z)==true; 则f(x,z)==true
我们称f(x,y)这个谓词是严格弱序的。
我们考察C++的操作符 < 。这个操作符有左右两个操作数,可以认为是一个二元谓词。
1<1 == false
1<2 == !(2<1)
若1<2, 2<3;则1<3
可见,<是严格弱序的
我们再考察C++的操作符 <= 。
1<=1 == true 违反性质1
1<=2 == 2<=1 违反性质2
可见,<= 不是严格弱序的
考察 大于运算符>,它是严格弱序的。
严格弱序的用途:
若 f(x,y)==true, 则x在y的"前面"
若 f(y,x)==true, 则x在y的"后面"
若 !f(x,y) && !f(y,x), 则x,y等价。或者x,y并列。
若 !f(x,y)==true, 则x在y的"后面"或者x,y并列。
若 !f(y,x)==true, 则x在y的"前面"或者x,y并列。
一个f(x,y)谓词能表达所有可能的前后关系计算方法。
STL容器和算法(例如map容器的key,sort算法的比较器。),需要用到比较器时,是假设了比较器是满足严格弱序的。
如果违反,则行为未定义(程序crash,破坏行为)。
报错 (error) DENIED Redis is running in protected mode because protected mode is enabled
注释掉绑定ip
# bind 127.0.0.1Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程,设置为no
daemonize no保护模式,关闭保护模式,否则外部ip无法连接
protected-mode no 然后重启redis就可以了
TkMapper的配置及使用 TkMapper主要是做单标查询,复杂的多表查询我们还得自己写sql。
官方文档:
点击查看使用的是Springboot框架使用的数据库表ums_permision: idpidnamevalueicontypeuristatuscreate_timesort10商品nullnull0null12018-09-29 16:15:14021商品列表pms:product:readnull1/pms/product/index12018-09-29 16:17:01031添加商品pms:product:createnull1/pms/product/add12018-09-29 16:18:510…………………… 对应的pojo对象: package com.sxykj.ymall.user.bean; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import java.util.Date; public class UmsPermission { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private Long pid; private String name; private String value; private String icon; private Integer type; private String uri; private Integer status; private Date createTime; private Integer sort; //省略getter和setter方法 } 一、TkMapper依赖及配置 1、在pom文件中引入TkMapper依赖:
<dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.0.2</version> </dependency> 2、在Application类上加注解@MapScan(“com.sxykj.ymall.user.mapper”),这个注解依赖的包一定是tk开头的(tk.mybatis.spring.annotation.MapperScan;)。
3、映射类extends 通用Mapper
自动化测试过程中,涉及到数据的增删改查操作,如果不对数据库进行备份和还原,那么无法进行自动化,例如,前端页面提交表单,使用脚本自动新增一条数据,新增成功之后,第二次及以后跑测试脚本就会失败,因为数据库已存在该数据,这个时候就需要在跑脚本之前先把数据库恢复到初始状态。
备份和还原实际就是把数据库下的数据和结构导出为sql文件,再把sql文件导入到数据库。
备份 sql语法:
全量备份(数据+结构):#mysqldump -uroot -p123456 -A > 备份文件路径
**
指定库备份(数据+结构):# mysqldump -uroot -p123456 库名 > 备份文件路径**
多个库备份(数据+结构):# mysqldump -uroot -p123456 --databases db1 db2 >
备份文件路径
shell备份脚本:
#!/bin/env bash date=$(date +'%s') bak_dir=/root/shell06/bak if [ ! -d $bak_dir ];then mkdir -p $bak_dir fi mysqldump -uroot -p123456 xianghuan > $bak_dir/$date.sql 还原 sql语法:
1.系统命令方法:mysql -uroot -p123456 库名 < 备份文件路径2.source方法:source 备份文件路径(该方法需要先登录数据库并指定数据库) shell还原脚本:
#!/bin/env bash lst=$(ls /root/shell06/bak) sql=0 for i in $lst do num=${i%.
《程序员》高展专栏——UML三大“硬伤”(2002年第5期) --------------------------------------------------------------------------------------------------------------------------------
UML三大“硬伤”
编者:此文在《程序员》发表后,引发了UML支持者的激烈讨论
讨论文章见:UML 谁的硬伤 http://www.csdn.net/develop/Article/13/13680.shtm
这种热烈的技术争论其实越多越好,但很重要的一点讨论者需要"独立思考并勇敢丢出论点。"
撰文/高展
本文从UML建模连贯性方面存在的问题,以管理软件开发为例,针对与UML模型衔接的上游、下游、模型内部关系三个方面,分析了采用UML建模造成的三大隔阂,希望与众多建模爱好者共同探讨。
在国内的公开报道中,几乎众口一致地充斥着对统一建模语言UML(Unified Modeling Language)的褒奖,即便有公开抱怨也只是怪自己无法理解三位UML创始人的深不可测,怪自己的水平不够,没有料到UML本身存在着种种问题。本文作者只在北京大学计算机系的同行那里发现了他们撰文对UML的有效性提出了质疑。与公开报道相左,业界私下流行观点形象地说明了UML存在问题为软件开发设置的障碍,那就是“上不着天、下不着地、一盘散沙”:
(1)“上不着天”这种隔阂使建模结果无法与用户沟通确认所谓的需求,埋下了软件危机的祸根;
(2)“下不着地”这种隔阂使千辛万苦得到的建模结果无法指挥程序员编码,最后得到的软件与用户期望的结果很远,返工、误工、烦恼无穷;
(3)“一盘散沙”这种隔阂让建模图形之间的关系凌乱不堪,建模过程千辛万苦,建模结果很难自圆其说。
这三大隔阂造成的建模硬伤使UML辜负了人们的殷切期望,“高不成、低不就”说明了UML建模在软件生命周期中步履蹒跚,“一盘散沙”说明了UML在建模内容中并未实现Unified的原旨,图 1是UML存在问题的可视化表达。
图 1 采用UML描述的建模结果“分崩离析”
诚然,掌握UML很容易谋到一份很好的系统分析员工作,但用它却很难做好系统分析员的分内工作,使用UML肯定可以100%蒙住用户,因为用户对满篇的建模图表只有招架之功,绝无理解反驳之力,使用UML也几乎可以100%蒙住软件公司老板,因为老板不是系统分析员,不知道使用UML进行建模的千辛万苦,系统分析员无法向老板反映UML存在的问题,因为这样很容易招致水平不高的责难。
一、UML上不着天——与用户/领域专家无法沟通获得真正的需求
所谓“上不着天”是指使用UML建模后很难与处于软件开发上游的企业用户沟通,因为UML的表达方式与上游用户的行业知识相差甚远,用户一看见满篇的软件工程术语与符号就发怵,根本无法理解使用UML所描述的业务流程,也难以真正理解UML所陈述的需求,与业务专家交流无工而返,导致软件大厦一开始就建立在沙子上,需求不清不楚,没完没了的胡子工程就此落下病根,这种情况造成了软件开中的第一个隔阂,是UML的第一大硬伤。
对企业用户来讲,他们关心的是如何在其组织结构、业务流程、业务信息的描述基础上,定位企业的宏观管理水平的需求和微观管理操作的需求。
1 UML难以完整全面地描述企业的分工结构
图 2是采用全程建模方法组成结构树描述的企业分工组成,它以直观、彻底、一目了然的方式将一个企业按层次地展现为部门、岗位、职责、步骤、直至原子步骤,如“核对数量、核对规格、签字、填写入库日期”等。
图 2 采用全程建模方法描述的分工组成结构可以细化到原子级工作步骤
图 3是采用UML的Use Case 图来描述组织结构,它只能描述到岗位职责,对岗位职责中的工作步骤无法描述。对业务的描述粗枝大叶,结果需求也是粗枝大叶,但用户往往不知道需要特别重视这一点,更不知道这种粗枝大叶会给项目带来灾难。这是纠缠不清的胡子工程问题点之一。
图 3 采用UML描述的分工组成结构至多只能描述到职责级
2 UML难以从宏观把控业务流程的完整与准确
图 4是用全程建模方法顺序图描述的业务协作流程——“采购”,它将业务事件序列与业务活动有机地集成在一个图形中,用户可以直观地判断软件开发人员描述的业务流程是否正确、完整。
图 4 采用全程建模方法的顺序图描述业务协作流程
图 5与图 6分别用UML顺序图和活动图描述的业务协作流程——“采购”,问题其一是用户需要左一眼、右一眼、上一眼、下一眼地对照两张图,费时费力,检查两种图时在所难免地会出现遗漏、不一致;问题其二是UML顺序图缺少条件分支的表达方法,表达内容不完整;问题其三是UML顺序图和活动图从形式上到内容上不存在等价关系。
使用UML描述业务流程很难让人放心,因为描述业务流程时产生的遗漏、不一致、不完整,同样会给项目带来灾难。这是纠缠不清的胡子工程问题点之二。
3 UML无法从微观把控业务信息的操作过程
图 7从微观上用全程建模方法PAD图描述了职责细化流程——库管员如何“入库”,它不仅描述了岗位职责展开的具体逻辑步骤,同时也描述了如何对业务信息进行操作,如对“入库单”的 “实际入库数量、入库日期”等栏目进行填写操作,对“入库单”的 “商品规格、采购数量”等栏目及“采购计划”的等“商品规格、计划采购数量”等栏目进行读取操作。
图 7 采用全程建模方法的PAD图描述的职责细化流程
UML根本无法从微观上描述业务信息的操作过程,只能等到编程时再由有经验、责任心强的程序员去了解,这无疑于边盖楼边考虑在哪里开窗户,最后各种问题盘根错节,摁倒葫芦起了瓢。软件公司练就了不少救火高手,但不容否认的是充满了救火队员项目常常意味着灭顶之灾。这是纠缠不清的胡子工程问题点之三。
4 UML无法彻底全面描述用户的需求
图 8是采用全程建模方法组成结构树进行功能定义,它可以细致到原子工作步骤级,比如“签字入库”仍然需要手工进行。
图 8 采用全程建模方法组成结构树进行功能定义
采用UML无法对这种功能需求直观地定位,结果是开发人员好心好意地实现了电子签名,而客户却毫不领情,应为中国用户不相信计算机的签名,去掉这个功能也是一件麻烦事。
另外常常发生的情况是开发软件遗漏了大量用户需要的功能,如用户需要计算机自动核对“采购计划”中的“计划采购数量”与“入库单”中的“计划采购数量”,如果需求定位没有细致到这种程度,程序员如果没有经验或责任心不强,自然会忘记这些,那么在测试阶段或者系统上线运行后用户肯定会发现要求修改,改来改去的麻烦又会特别多,反反复复修改的工作量极大地加大了软件公司的开发成本。这是纠缠不清的胡子工程问题点之三。
1. 题目来源 链接:旋转数组
来源:LeetCode
2. 题目说明 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
示例2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
3. 题目解析 此题可以采用头插法,一个一个的移动。但是有种更加简单的选择数组的方式。可以采用翻转的方式,比如12345经过翻转就变成了54321,这样已经做到了把前面的数字放到后面去,但是还没有完全达到要求,比如,只需要把12放在后面去,目标数组就是34512,与54321对比发现我们就只需要在把分界线前后数组再进行翻转一次就可得到目标数组了。所以此题只需要采取三次翻转的方式就可以得到目标数组,首先翻转分界线前后数组,再整体翻转一次即可。此题面试常考,大家可以记一下此方法。
三重反转
把一个数组的右边一部分移动到左边相当于:
把左部分翻转
把右部分翻转
最后把整体翻转 或是,直接调用算法头文件< algrorithm>中的函数rotate,函数原型可在CSDN上自行查找相关内容,最好能看看STL源码,或是《STL源码剖析》侯捷著。
4. 代码展示 class Solution { public: void rotate(vector<int>& nums, int k) { // std::rotate(nums.
【时间】2020.01.14
【题目】SRM滤波器与双线性池化
在【CVPR 2018】Learning Rich Features for Image Manipulation Detection(图像篡改检测)中,提到了通过SRM滤波获得噪声图片,以及最后通过双线性池化(Bilinear pool)融合两条支路。
1、SRM滤波器
SRM指是《 Rich models for steganalysis of digital images》中提出来的,所以应该是Steganalysis Rich Model的缩写,富隐写分析模型的意思。论文中使用下面3个滤波器获得噪声图片:
输入RGB图片,通过上面的 3个滤波器获得通道数依旧为3的特征。在keras中通过Conv层实现如下:
def SRMLayer(x): q = [4.0, 12.0, 2.0] filter1 = [[0, 0, 0, 0, 0], [0, -1, 2, -1, 0], [0, 2, -4, 2, 0], [0, -1, 2, -1, 0], [0, 0, 0, 0, 0]] filter2 = [[-1, 2, -2, 2, -1], [2, -6, 8, -6, 2], [-2, 8, -12, 8, -2], [2, -6, 8, -6, 2], [-1, 2, -2, 2, -1]] filter3 = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, -2, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] filter1 = np.
今天想kill -9redis
杀不掉
然后发现
这个是属于服务器方法,可以了解一下supervisor,将需要自启动的程序加入到supervisor的启动配置,只要supervisor不停止,那么监控进程就会一直运行,并且如果出现关闭情况也会被立即重启。
微信小程序 框架(MINA) 小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生APP体验的服务。
框架提供了自己的视图层描述语言WXML和WXSS,以及基于JavaScript的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,可以让开发者可以方便的聚焦于数据与逻辑上。
主体文件
在每个小程序框架中最关键也是必不可少的文件就是 app.js、app.json、app.wxss 这三个。其中,.js后缀的是脚本文件,.json后缀的文件是配置文件,.wxss后缀的是样式表文件。微信小程序会读取这些文件,并生成小程序实例。
app.js是小程序的脚本代码。我们可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量。调用框架提供的丰富的 API,如本例的同步存储及同步读取本地数据。
//app.js App({ onLaunch: function () { //调用API从本地缓存中获取数据 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) }, getUserInfo:function(cb){ var that = this; if(this.globalData.userInfo){ typeof cb == "function" && cb(this.globalData.userInfo) }else{ //调用登录接口 wx.login({ success: function () { wx.getUserInfo({ success: function (res) { that.globalData.userInfo = res.userInfo; typeof cb == "function" && cb(that.globalData.userInfo) } }) } }); } }, globalData:{ userInfo:null } }) app.
1. hybrid是什么,为何用hybrid? (1)hybrid文字解释
hybrid即“混合”,即前端和客户端的混合开发需前端开发人员和客户端开发 人员配合完成某些环节也可能涉及到server端 (2)存在价值,为何会用hybrid?
可以快速迭代更新,无需app审核,(需审核因为客户端代码会有访问手机隐私的信息,比如地理位置,开启相机等),很关键!体验流畅(和Native的体验基本类似)减少开发和沟通成本,双端公用一套代码 (3)webview
是app中的一个组件(app可以有webview,也可以没有)用于加载h5页面,即一个小型的浏览器内核 (4)file://协议
file协议加载本地的资源,断网也可以加载,非常快http(s)协议是加载远程的资源,断网不可以,慢 (5)hybrid实现流程
不是所有场景都适合hybrid:
使用native:体验要求极致,变化不频繁(如头条的首页)使用hybrid:体验要求高,变化频繁(如头条的新闻详情页)使用h5:体验无要求,不常用(如举报、反馈等页面) 具体实现:
前端做好静态页面(html,js,css),将文件交给客户端客户端拿到前端静态页面,以文件形式存储在app中客户端在一个webview中,使用file协议加载静态页面 2. 介绍一下hybrid更新和上线的流程? 分版本,有版本号,如201803211015将静态文件压缩成zip包,上传到服务端客户端每次启动,都去服务端检查版本号如果服务端版本号大于客户端版本号,就去下载最新的zip包下载完之后解压包,然后将现有文件覆盖 3. hybrid和h5的主要区别? (1)优点:
体验更好,跟Native体验基本一致可快速迭代,无需app审核 (2)缺点:
开发成本高。联调、测试、查bug都比较麻烦运维成本高。参考更新上线流程 (3)适用场景
hybrid:产品的稳定功能,体验要求高,迭代频繁(产品型)h5:单词的运营活动(如红包)或不常用功能(运营型) 4. 前端JS和客户端如何通讯? 新闻详情页适用于hybrid,前端如何获取新闻内容? - 不能用ajax获取。第一,跨域;第二,速度慢 - 客户端获取新闻内容,然后JS通讯拿到内容,再渲染 (1)JS和客户端通讯的基本形式
JS访问客户端能力,传递参数和回调函数客户端通过回调函数返回内容 (2)schema协议简介和使用
schema协议是前端和客户端通讯的约定 例如微信schema协议: weixin://dl/scan 扫一扫 var iframe = document.createELement('iframe'); iframe.style.display = 'none'; iframe.src = 'weixin://dl/scan'; // iframe访问schema var body = document.body || document.getElementsByTagName('body')[0]; body.appendChild(iframe); setTimeout(function(){ body.removeChild(iframe); // 销毁iframe iframe = null; }) // 如果要加上参数和callback,那么就要这么写 window['_weixin_scan_callback'] = function(result){ alert(result) } // .
一、版本说明 本机系统: Windows 10 (64位) nginx: v1.16.1 (64位) # nginx -v 查看 二、出现问题 2.1、使用 Windows PowerShell 窗口,提示错误: nginx : 无法将“nginx”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 三、切换为 cmd 命令窗运行命令即可 3.1、什么都不用改动,直接切换成 cmd 命令窗运行 写给自己的随笔,有问题欢迎指出ψ(*`ー´)ψ
mysql 8.0.18下载安装 1、下载地址(现在下载貌似需要注册oracle账号)
https://dev.mysql.com/downloads/mysql/
2、下载后解压:
解压文件放置到你想要的位置:
3、配置初始化的my.ini文件的文件
解压后的目录并没有的my.ini文件,没关系可以自行创建在安装根目录下添加的my.ini(新建文本文件,将文件类型改为的.ini),写入基本配置:
[mysqld] # 设置3306端口 port=3306 # 设置mysql的安装目录 basedir=D:\Program Files\mysql-8.0.18-winx64 # 设置mysql数据库的数据的存放目录 datadir=D:\Program Files\mysql-8.0.18-winx64\Data # 允许最大连接数 max-connections=200 # 允许连接失败的次数。 max_connect_errors=10 # 服务端使用的字符集默认为utf8mb4 character-set-server=utf8mb4 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB # 默认使用“mysql_native_password”插件认证 #mysql_native_password default_authentication_plugin=mysql_native_password [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8mb4 [client] # 设置mysql客户端连接服务端时默认使用的端口 port=3306 default-character-set=utf8mb4 4、初始化MySQL
在安装时,避免出错我们尽量全部使用管理员身份运行CMD,否则在安装时会报错,会导致安装失败的情况
C:\Windows\System32
打开后进入mysql的bin目录:
在MySQL目录下的bin目录下执行命令:
mysqld --initialize --console 注意![注意] [MY-010454] [服务器]为root @ localhost生成临时密码:aYZ=4.2,JwWU,其中root @ localhost:后面的aYZ=4.2,JwWU就是初始密码(不含首位空格)。在没有更改密码前,需要记住这个密码,后续登录需要用到。复制密码先保存起来!!!
5、安装MySQL服务 + 启动MySQL 服务
安装mysql服务
执行下面的命令:
mysqld --install [服务名](服务名可以不加默认为mysql) 成功了。
1、我的调用程序接口
2、当我在执行FreeLibrary之前,内存是这样的
3、当执行FreeLibrary之后:
遇到这种无厘头的错误也是醉了,具体原因还不清楚,问题崩溃在Cstring的Release中
4、dll并没有改动,只是将CString mm的声明和赋值分开,然后就没事了
有图有真想 回头研究下CString
List<Car> catList = new ArrayList<>(); //加入4个对象 Car car1 = new Car(); car1.setTestFiled(1.02); Car car2 = new Car(); car2.setTestFiled(null); Car car3 = new Car(); car3.setTestFiled(1.04); Car car4 = new Car(); car4.setTestFiled(1.05); catList.add(car1); catList.add(car2); catList.add(car3); catList.add(car4); catList.sort(Comparator.comparing(Car::getTestFiled,Comparator.nullsLast(Double::compareTo))); System.out.println("正序:"); System.out.println(catList); catList.sort(Comparator.comparing(Car::getTestFiled,Comparator.nullsFirst(Double::compareTo)).reversed()); System.out.println("倒序:");
工程项目管理模
Gongcheng xiangmu guanli
moshi
工程总承包 是指从事工程总承包的企业(以下简称工程总承包企业)受业主委托,
按照合同约定对工程项目的勘察、设计、采购、施工、试运行(竣工验收)等实行全过程或
若干阶段的承包。工程总承包主要有如下方式:
1.设计—采购—施工 (Engineering Procurement Construction,简称EPC)/ 交钥匙总承包 (Lump Sum Key,简称 LSTK )设计—采购—施工总承包 是指工程总承包企业按照合同约定,承担工程项目的设计、采购、施工、试运行服务等工作,并对承包工程的质量、安全、工期、成本全面负责。交钥匙总承包 是设计采购施工总承包业务和责任的延伸, 最终是向业主提交一个满足使用功能、具备使用条件的工程项目。
2.设计—施工总承包( Design-Build,简称 D-B)
设计—施工总承包 是指工程总承包企业按照合同约定,承担工程项目设计和施工,并对承包工程的质量、安全、工期、成本全面负责。根据工程项目的不同规模、类型和业主要求,工程总承包还可采用设计—采购总承包(Engineering-Procurement, 简称 E-P)、采购—施工总承包( Procurement-Construction,简称P-C)等方式。工程项目管理 是指从事工程项目管理的企业(以下简称工程项目管理企业)受业主委托,按照合同规定,代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。工程项目管理主要有如下方式:
1.项目管理承包( Project Management Contractor,简称 PMC )
项目管理承包是指工程项目管理企业对工程项目建设提供全过程服务。即在工程项目决
策阶段,为业主进行规划咨询、项目策划、融资、编制项目建议书和可行性研究报告、进行
可行性分析;在工程项目准备阶段,为业主编制招标文件、编制和审查标底、对投标单位资
格进行预审、起草合同文本、协助业主与中标单位签订合同等;在工程项目实施阶段,为业
主提供工程设计、采购管理、施工管理、初步设计和概预算审查等服务;在工程项目竣工阶
段,为业主提供财务决算审核、质量鉴定、试运行、竣工验收和后评价等服务;代表业主对
工程项目的质量、安全、工期、成本、合同、信息等进行管理和控制。项目管理承包企业一
般应当按照合同约定获得相应的劳酬、奖励以及承担相应的管理风险和经济责任。
2.项目管理服务( Project Management,简称 PM )
项目管理服务是指工程项目管理企业按照合同约定完成项目管理某个阶段或 PMC 若干
内容组合的咨询服务。项目管理服务企业只承担合同约定的管理责任并获得相应的劳酬。
建设—经营—转让模式 (Build Operate transfer,简称 BOT)是政府将一个基础
设施项目的特许权授予承包商 (一般为国际财团)。承包商在特许期内负责项目设计、融资、
建设和运营,并回收成本、偿还债务、赚取利润,特许期结束后将项目所有权移交政府。
在实际运作过程中, BOT 方式产生了许多变形,比如, BOO(建设—拥有—运营),
BTO(建设—转让—经营), BOOS(建设—拥有—运营—出售), BT(建设—转让), OT
时间同步
Autosar就是让ECUs的软件架构标准化:
1.让软件和硬件分的清清楚楚
2.让不同功能的软件模块分的清清楚楚
3. 非常方便模块再利用
4. 减少开发成本,提高质量和效率
就像是统一了手机充电接口一样,管你三星苹果还是华为,随便插拔,随心所欲的充电,这就是标准化的力量。Autosar可以让主机厂(OEM, 比如大众宝马奥迪等),供应商(大陆,博世,Nvidia, Renesas等),开发工具供应商(Matlab, Vector, Electrobit等),以及新入市场的朋友(各路创业公司们),都可以收益。因为任何人都可以很方便的根据规范标准,开发自己的专长的功能或者工具,而不必浪费大量的人力物力去匹配那些根本没有意义的接口或者平台。类似于你开发一个简单实用的手机APP,你真的没有必要去开发苹果版本,安卓版本,太费神了,开发一次就够了,你的价值在于创意,而不是写代码!
AUTOSAR standardizes two software platforms –Classic and Adaptive
随着时代变迁,Autosar也不能落后于,过去主要是比较死板的Classic Autosar, 如今新的更灵活的Adaptive Autosar也横空出世。因为目前趋势是多核多Soc的硬件结构,所以基于性能和安全需求的考量,可以混合两种Autosar架构。
基于以上特点,Autosar注定不会只能在汽车上应用,电动车,无轨交通,游艇,轮船等等等等,都能用。但是注意,核电站,Autosar不宜,毕竟付不起那个责任。
吹了半天牛逼,该来点干货了,那么我试着从基于Autosar的时间同步功能,讲讲,Autosar到底是怎么标准化软件架构的。
~~~~~干货分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
师出有名,讲的就是做任何事情之前都要讲一个好的motivation。软件也是同样的道理。事实上,时间同步是非常重要的一个概念。可以想象,一首优美的交响乐,各种不同的乐器以及乐手要非常默契在节拍内准确的演奏自己的乐章,快一拍或者慢一拍都是非常刺耳的,甚至可能会扰乱整场演奏会。这其实就是智能驾驶实时系统的真实写照,各个模块及算法要准时准点的按照节奏执行自己的功能,不能快,也不能慢。所以,时间同步显得尤为重要,大家要有一个一致的时钟,这就是传说中的Global Time (GT).
为了统一控制时间,我们就需要一个全局时间软件模块(StbM, Synchronized Time-base Manager)。
功能只有两个:1. 同步各个软件模块实体,2. 提供绝对时间值。
它的功能显而易见就是作为一个中介,统一大家的时钟,已达到同步各个软件及算法模块。
啥都不说了,先来一张图体会一下StbM的作用对象们:
StbM就是一个中介,来传递同步时钟信号
StbM要能提供同步时钟信息给Triggered Customer, 比如操作系统。操作系统就好比乐队指挥,也需要看着表来指挥乐队演奏。StbM要能提供同步时钟信息给Active Customer, 比如有些算法或传感器。StbM要能提供同步时钟信息给Notification Customer, 想象一下国内浮夸的摩托车里面绚丽的内饰灯,他们可能要按照节奏闪动。StbM要能通过总线提供同步时钟信息,比如CAN, FlexRay或者Ethernet. 全局时间如何通过CAN,FlexRay和ETH来传播
其实时间同步的难点在于,硬件时钟信号存在偏差。也就是说不同公司不同产品,即使产品说明书上写着相同的时钟频率,但实际上由于公差或者物理热效应,事实上是在时间维度上是存在偏差的。下图就是说真正的时钟信息是如何产生并且传递的:
从下往上看
从下往上看上面这幅图。右下角就是硬件时钟,也是整个同步系统的基石。但是因为隔一段时间超过最大值后就会溢出,所以需要一个Software Counter来记录这种溢出,然后一起产生了一个虚拟本地时间 (Virtual Local Time). 这个时间就没有溢出和跳跃了,也就是说很平稳的表达时间的流逝。接下来就是技术核心,如何进行时间的矫正,这个下面会细讲(durchsprechen, 复习一下德语)。接下来就可以产生一个同步的本地时间信号,之后就可以传递给其他的软件模块了。
~~~~~干货中的干货分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
干货中的干货: 时间矫正算法
先上图,横轴代表全局时间,纵轴代表本地时间。虚线代表理想的时间关系,蓝线代表实际的时间关系。显而易见,实际上,是有偏差的。其中斜率代表时钟频率偏差,红色箭头代表绝对时间的偏差。
Time Deviations Rate Correction
接下来注意了:
时间的矫正过程,并不改变各个在本地的运行时钟,而是动态改变本地时钟的实体变量。
Apache Impala 概述 Impala直接对存储在HDFS,HBase或Amazon Simple Storage Service(S3)中的Apache Hadoop数据提供快速,交互式SQL查询。除了使用相同的统一存储平台之外,Impala还使用与Apache Hive相同的元数据,SQL语法(Hive SQL),ODBC驱动程序和用户界面(Hue中的Impala查询UI)。这为实时或面向批处理的查询提供了一个熟悉且统一的平台。 Impala是可用于查询大数据的工具的补充。 Impala不会替代基于MapReduce构建的批处理框架,例如Hive。基于MapReduce构建的Hive和其他框架最适合长时间运行的批处理作业,例如涉及对Extract,Transform和Load(ETL)类型的作业进行批处理的框架。
Note: Impala于2017年11月15日从Apache Incubator毕业。在文档以前称为“ Cloudera Impala”的地方,现在的正式名称是“ Apache Impala”。
Impala优势 数据科学家和分析师已经知道的熟悉的SQL接口。能够查询Apache Hadoop中的大量数据(“大数据”)。集群环境中的分布式查询,可方便地扩展并利用具有成本效益的商品硬件。无需复制或导出/导入步骤即可在不同组件之间共享数据文件;例如,使用Pig编写,使用Hive进行转换以及使用Impala进行查询。 Impala可以读写Hive表,从而可以使用Impala对Hive生成的数据进行分析,从而实现简单的数据交换。用于大数据处理和分析的单一系统,因此客户可以避免仅用于分析的昂贵建模和ETL。 Impala执行原理 Impala服务器是一个分布式的大规模并行处理(MPP)数据库引擎。它由运行在群集内特定主机上的不同守护进程组成。Impala解决方案由以下组件组成:
Impala Daemon
Impala的核心组件是Impala守护程序,由impalad进程物理表示。Impala守护程序与StateStore保持持续通信,以确认哪些守护程序是健康的并且可以接受新工作。每当集群中的任何Impala守护程序创建,更改或删除任何类型的对象,或者通过Impala处理INSERT或LOAD DATA语句时,它们还从catalogd daemon(在Impala 1.2中引入)接收广播消息。这种后台通信最大程度地减少了在Impala 1.2之前的跨Impala守护程序协调元数据所需的REFRESH或INVALIDATE METADATA语句的需要。在Impala 2.9和更高版本中,您可以控制哪些主机充当查询协调器,哪些主机充当查询执行器,以提高大型集群上高并发工作负载的可伸缩性。 Impala守护程序执行的一些关键功能是:
Reads and writes to data files.Accepts queries transmitted from the impala-shell command, Hue, JDBC, or ODBC.Parallelizes the queries and distributes work across the cluster.Transmits intermediate query results back to the central coordinator. Impala Statestore
目录 介绍使用tutorials(教程)学习thymeleafthymeleaf可以处理哪种模板类型标准表达语法 集成thymeleaf进入Articles(文章) 介绍 thymeleaf翻译软件有的将它翻译为"百叶香"有的将它翻译为胸腺
官网: https://www.thymeleaf.org/index.html
home页面有三句话介绍了它
Thymeleaf is a modern server-side Java template engine for both web and standalone environments.
讲的是thymeleaf是适用于web和独立环境的现代服务器端java模板引擎
它代替了java传统的jsp
Thymeleaf’s main goal is to bring elegant natural templates to your development workflow — HTML that can be correctly displayed in browsers and also work as static prototypes, allowing for stronger collaboration in development teams.
thymeleaf主要的目的是给你的开发流程带来一个优雅自然的模板,html可以在浏览器中正确的显示,也可以作为静态原型工作
With modules for Spring Framework, a host of integrations with your favourite tools, and the ability to plug in your own functionality, Thymeleaf is ideal for modern-day HTML5 JVM web development — although there is much more it can do.
升级到指定版本
pip install --upgrade keras==2.2.4 安装指定版本
pip install keras==2.2.4
list切片和.split()分割 (1)list切片
(2).split( )
(1)list切片 list切片的格式:list(start,end,step)
list:是某一个列表名
start:是起始元素的下标
end:是结束位置元素的下标
step:步长,通俗来说就是想每隔几个元素获取
#直接获取 list = [12,33,9,'hello python',43,'see',88,11,56] #直接获取下标为3的元素 print(list[3]) #输出:hello python #获取列表下标为3的后面的所有元素(包含3) print(list[3:]) #输出:['hello python',43,'see',88,11,56] #获取列表下标为20之前的所有元素(包含20,当然该列表没有下标为20的元素,所有就没有了) print(list[:20]) #输出:[12,33,9,'hello python',43,'see',88,11,56] #获取下标为2至下标为8之间的元素,注意:这种写法step默认等于1 (包含2,8) print(list[2:8]) #输出:[9,'hello python',43,'see',88,11] #获取下标为2至下标为8之间的元素,步长为1 (包含2,8) print(list[2:8:1]) #输出:[9,'hello python',43,'see',88,11] #获取下标为2至下标为8之间的元素,步长为2 (包含2,8) print(list[2:8:2]) #输出:[9,43,88] #获取下标为2至下标为8之间的元素,步长为-1 print(list[2:8:-1]) #输出:[] 这是为什么呢? 接着往下看 print(list[2:8:-2]) #输出: [] #获取所有元素,步长为-2,-2表示倒着获取,还要每隔2个获取一次 print(list[::-2]) #print(list[2:8:-1]) #输出:[] #为什么输出是空的呢 #答:2~8代表从左到右的查找,-1代表反向获取,因为代码是可以运行的,但方向不同,所以获取的是一个空的列表 代码运行结果:
(2) .split( ) 表示分割 .split(‘分割符’)
分割符可以为任何符号,例如,!,@,#,$,%,&等等
str = "I am a Universety and very python"
问题思考 在自动化测试过程中,由于有些数据库操作并不是安全的,比如 DELETE 类型,上一次请求之后下一次再请求结果就不一样了。甚至有时接口之间的数据还会相互干扰, 导致接口断言失败时不能断定到底是接口程序引起的错误,还是测试数据变化引起的错误,那么该如何有效解决这个问题呢?
解决思路 通过测试数据库,每轮测试之前将数据初始化,这样避免数据干扰。
一、准备数据 将初始化数据使用 Yaml 来封装,可以将数据与代码分离,方便测试数据的维护。
api_user: - username: xianghuan email: 1788345@qq.com groups: http://127.0.0.1:8000/groups/1/ - username: jack email: 86962483@qq.com groups: http://127.0.0.1:8000/groups/2/ api_group: - name: tester - name: developer 二、封装初始化操作 数据初始化操作主要包括:数据库连接,数据清除、数据插入、关闭数据库。
import pymysql import yaml class DB(object): def __init__(self): """ 连接数据库,创建连接,创建游标 """ host = '127.0.0.1' port = 3306 database = 'django_restful' username = 'root' password = 'root' charset = 'utf8' self.conn = pymysql.Connect(host=host, port=port, database=database, user=username, password=password, charset=charset) self.
Java连接Mysql时报错 Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone valu
详细信息: java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support. FATAL ERROR in native method: JDWP on checking for an interface, jvmtiError=JVMTI_ERROR_WRONG_PHASE(112) at com.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> var arr = [1,1,2,3,4,4,'a','d','a'] var arr2 = [1,1,2,3,4,4,'a','d','a'] /* 双重for循环 */ function quChong(elements){ for (let i = 0; i < elements.length; i++) { for (let j = i+1; j < elements.length; j++) { //前一个元素和后一个元素相比较 如果相同,删除后一个 if(arr[i] === arr[j]){ elements.splice(j,1) //方便下一次循环 找得到后一个元素 j--; } } } return elements; } console.log(arr) console.log(quChong(arr)) /* 利用对象key的唯一性 */ function quchong2(elements){ var newArr = []; var obj = {}; for (let i = 0; i < elements.
uniapp 中经常出现类似这样的问题 Cannot set property 'list' of undefined
就是单单 this.list = res.data.content 都报错 可能是es6的写法
改用es6的写法就能正常传参了
比如 success: (res) => {
this.list = res.data.content
}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> span{ display: inline-block; width: 80px; height: 40px; line-height: 40px; background-color: lightgreen; /* margin: 5px; */ border: 1px solid #ccc; text-align: center; } </style> </head> <body> <div></div> <script> var div = document.getElementsByTagName('div')[0]; for(var i=1;i<=9;i++){ for(var j=1;j<=i;j++){ div.innerHTML += "<span>"+i+"*"+j+"="+i*j+"</span>" } div.innerHTML += "</br>" </script> </body> </html>
电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
Input
多组数据。对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。
n=0表示数据结束。
Output
对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。
Sample Input
1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0
Sample Output
-45
32
题目思路:输入饭卡余额首先要先判定饭卡内的钱是否大于等于5,否则输出此时饭卡余额。是的话用01背包思想第二个for循环递减并且在赋初值的时候要减去5。
输出时也要注意用饭卡内的初始额度减去饭菜中最贵的,并且判定在初始额度减5之后所能花的最多的钱。
ac代码;
#include<stdio.h>
#include
#include
using namespace std;
int v[1015],f[1015];
int main()
{
int n,m;
while(~scanf("%d",&n))
{
if(n==0) break;
memset(f,0,sizeof(f));
memset(v,0,sizeof(v));
for(int i=0;i<n;i++)
{
scanf("%d",&v[i]);
}
scanf("%d",&m);
if(m<5)
{
printf("%d\n",m);
continue;
}
sort(v,v+n);
for(int i=0;i<n-1;i++)
{
目录
1. 将时间字符串转化为时间戳
2. 设置索引列
3. 读取文件columns细节处理
3.1 csv默认将第一行设置为columns
3.2 想要换一个别的列名(原来有)
3.3 想加列名,原来没有
3.4 不想加列名,原来也没有
4. groupby
4.1 agg聚合操作
4.2 apply操作
1. 将时间字符串转化为时间戳 原始数据: 观测时间 经度 纬度 强度 陡度
0 2012-02-22 12:14:52.0 118.6845 31.6724 55.66 5.02
1 2012-02-22 12:21:55.0 118.6875 31.7405 72.99 62.28
2 2012-02-22 12:27:46.0 118.6998 31.7565 77.46 8.93
3 2012-02-22 12:35:34.0 118.9438 31.4310 -29.47 -17.97
4 2012-02-22 12:35:34.0 118.9416 31.4422 -13.43 -6.88
代码: data['观测时间']=data['观测时间'].apply(lambda x:time.mktime(time.strptime(x,'%Y-%m-%d %H:%M:%S.0'))) 效果:
前言:
下载安装 Nexus Repository Manager 默认账号/密码 : admin/admin123 视版本而定,这里安装不做深究,主要对如何配置maven 私仓 和 idea 中 deploy jar 包 进行记录。
0.首先创建 四个Repository 对应的各个Repository 的 type 需要注意。 group(仓库组)、hosted(宿主仓库)、proxy(代理仓库)
1.maven-central: type 为 proxy 意为 仓库中没有对应的jar 包是需要去远程 仓库下载。我这在创建的时候 proxy 填的是阿里的 http://maven.aliyun.com/nexus/content/groups/public/ 国内仓库快些。 2.maven-public: type 为 group 其中包含一些其他的仓库配置时可选 选定想要的仓库组组成。 3.maven-releases 和 maven-snapshots type 为 host 他们俩的区别在于 里边的权限分别为 之后就需要配置maven 的settings.xml 1.配置私仓地址 <mirror> <id>nexus</id> <mirrorOf>*</mirrorOf> <name>Nexus saic</name> <url>http://localhost:8081/repository/*-public/</url> </mirror> 2.配置私仓的用户名密码 。这里需要记住这个id 之后的maven 项目中的pom.xml 需要使用
<server> <id>nexus</id> <username>admin</username> <password>admin123</password> </server> 这里需要记住这个id
如
果能点个赞就更好啦,不用会员也能看的
iTOP4412开发板介绍 https://www.bilibili.com/video/av74453392
iTOP4412开发板系统编程前言https://www.bilibili.com/video/av75754003
iTOP4412-fastboot烧写Android https://www.bilibili.com/video/av76115803
iTOP4412-安装虚拟机软件https://www.bilibili.com/video/av75881580
iTOP4412-创建和配置虚拟机https://www.bilibili.com/video/av75881653
iTOP4412-获取并安装ubuntu操作系统https://www.bilibili.com/video/av75881774
iTOP-4412驱动教程一 https://www.bilibili.com/video/av74131033
iTOP-4412驱动教程二 https://www.bilibili.com/video/av74131033?p=2
iTOP-4412驱动教程三 https://www.bilibili.com/video/av74131033?p=3 iTOP-4412开发板之如何扩展不同规格LCD屏幕 https://www.bilibili.com/video/av75870604
itop4412-编译4412对应的uboot https://www.bilibili.com/video/av76737204
项目实战-GPS定位简介 https://www.bilibili.com/video/av78601887
项目实战-迅为实战教程介绍 https://www.bilibili.com/video/av78601813
项目实战-机车导航-机车导航项目演示 https://www.bilibili.com/video/av78601986
项目实战-机车导航-定制内核显示logo https://www.bilibili.com/video/av78729131
项目实战-机车导航-修改安卓开机启动动画 https://www.bilibili.com/video/av78972262
项目实战-智能家居-简介 https://www.bilibili.com/video/av80835403
1.问题 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
说明 :m 和 n 的值均不超过 100。
示例 1:
输入: m = 3, n = 2 输出: 3 解释: 从左上角开始,总共有 3 条路径可以到达右下角。 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下 -> 向右 3. 向下 -> 向右 -> 向右 来源:力扣(LeetCode);
2.解答 动态规划,容易找到(x,y)可以由,(x-1,y) 和(x,y-1)到达。由于,这里只有向右和向左两个方向,可以直接进行逐行遍历。
class Solution { public int uniquePaths(int m, int n) { int[][] dp=new int[m][n]; for(int x=0;x<m;x++){ for(int y=0;y<n;y++){ if(x==0&&y==0){ dp[x][y]=1; } else if(y==0){ dp[x][y]=dp[x-1][y]; } else if(x==0){ dp[x][y]=dp[x][y-1]; } else{ dp[x][y]=dp[x-1][y]+dp[x][y-1]; } } } return dp[m-1][n-1]; } } 当时,想的不够通彻,觉得,应该是按照对角线进行遍历。
文章目录 系数矩阵、增广系数矩阵、方程组的矩阵与向量表示形式结论判断方程组有无解的步骤求线性方程组的一般思路例题 参考 系数矩阵、增广系数矩阵、方程组的矩阵与向量表示形式 求解方程组就是对增广矩阵做初等行变换将系数矩阵化为行简化阶梯型。
下面是方程组有唯一解、无穷多解、无解的情况
结论 判断方程组有无解,关键是看系数矩阵与增广矩阵是否相等。
(使用n代表未知量的个数,m代表方程个数)
判断方程组有无解的步骤 求线性方程组的一般思路 例题 最后求出来的一般解组成的方程组为同解方程组。
对于有参数的例题,参数不能放在分母上
参考 以上图片均摘自宋浩老师视频,以方便以后自己查阅,感谢宋老师。
视频传送门
linux终端能显示中文,但是不能输入中文的解决方法 linux终端能显示中文,但是不能输入中文的解决方法第一种方法:修改用户目录下的.inputrc文件允许 8bit 输入即可第二种方法(不建议使用)总结 linux终端能显示中文,但是不能输入中文的解决方法 首先,终端能显示中文,说明系统有中文语言包,网上看的那些安装中文语言包,设置默认语言等那些方法在这样的系统上就都不管用了,接下来试试这个方法,很简单的
第一种方法:修改用户目录下的.inputrc文件允许 8bit 输入即可 没错,解决办法就是修改用户目录下的.inputrc文件,允许 8bit 输入即可
inputrc 文件为特定的情况处理键盘映射,这个文件被 Readline 用作启动文件,Readline 是 Bash 和其它大多数 shell 使用的与输入相关的库。
大多数人并不需要自定义键盘映射,所以可以修改或者创建一个适用于所有登陆用户的全局 /etc/inputrc 文件。如果你需要为某个用户覆盖默认的设置,你可以在该用户的主目录中创建一个包含自定义键盘映射的 .inputrc 文件。
当前用户目录下可能没有.inputrc文件,如果没有,则新建一个
root@orangepi:~# vim .inputrc set meta-flag on set convert-meta off set input-meta on set output-meta on 在.inputrc文件里添加以上四行内容即可。
不知道为什么 source .inputrc在这里不管用,不过没关系,重开一个终端你就发现能愉快地输入中文了。
第二种方法(不建议使用) 简单说明一下,下面的命令将创建一个适用于所有登陆用户的全局 /etc/inputrc 文件,但是一般不建议这么做:
下面是一个基本的全局 inputrc 文件,那些选项的注释也一起包括在文件里。请注意,注释不能和命令放在同一行里。
cat > /etc/inputrc << "EOF" # 开始 /etc/inputrc # 允许命令行提示符转到下一行 set horizontal-scroll-mode Off # 允许 8bit 输入 set meta-flag On set input-meta On # 禁止第8位(最高位)剔除 set convert-meta Off # 允许显示第8位(最高位) set output-meta On # bell-style的取值范围是:none, visible, audible set bell-style none ##################################################################### # 下面将包含在第一个参数中的转义序列值映射到 readline 的特定功能 "
一 、SAP系统图片
1.1上传图片
TCODE: SMW0 上传本地图片到SAP系统
1.2 设置为登录首页的背景。
TCODE: SM30 打开表视图维护功能。
输入表名 SSM_CUST,这是 SAP 提供的修改登录后主界面的设置表。然后点击“Maintain(维护)”,这时会出现一个提示,说明它是个跨 Client 的表,就是说对它所做的修改会应用于所有 Client。
HIDE_START_IMAGE,值为“YES”表示登录后不显示背景图片,“NO”表示登录后显示背景图片。
RESIZE_IMAGE,值为“YES”表示自动缩放图片以适应窗口大小,“NO”表示图片尺寸保持原始值不变。
START_IMAGE,就填入我们刚才第一步所建立的对象名字。
二、ABAP屏幕图片 2.1 使用图片处理类 CL_GUI_PICTURE
调用方法 LOAD_PTCTURE_FROM_URL 使用路径加载图片
SET_DISPLAY_MODE 设置图片自适应容器
SET_3D_BORDER 设置图片框
属性 ADUST_DESIGN_TRUE 'X' ,自适应
DATA CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER. DATA PICTURE TYPE REF TO CL_GUI_PICTURE. CREATE OBJECT CONTAINER EXPORTING CONTAINER_NAME = 'CON1' . CREATE OBJECT PICTURE EXPORTING PARENT = CONTAINER EXCEPTIONS ERROR = 1 . CALL METHOD PICTURE->SET_DISPLAY_MODE EXPORTING DISPLAY_MODE = CL_GUI_PICTURE=>ADUST_DESIGN_TURE EXCEPTIONS ERROR = 1 OTHERS = 2 .
请求头中的Accept、Content-Type、User-Agent、Cookie分别代表什么含义? Accept:告诉服务器返回指定的数据格式
Content-Type:服务器指明返回数据的类型
User-Agent(客户端类型):标识客户端身份,即客户端告诉服务器自己的身份,用户使用的操作系统及版本,浏览器及版本信息。
Cookie:网站为了辨别用户进行会话跟踪而存储在用户本地的数据,用于维持当前访问会话
响应头中的Content-Type、Set-Cookie分别代表什么含义? Content-Type:服务端发送响应结果的类型及采用的编码方式
Set-Cookie:服务器返回的响应头用来在浏览器种cookie,一旦被种下,当浏览器访问符合条件的url地址时,会自动带上这个cookie
什么是session认证? http协议是一无状态协议,所以如果用户向后台应用提供了用户名和密码来进行认证,下一次请求时,用户还是要带上用户名和密码进行用户认证。为了使后台应用能识别是哪个用户发出的请求,只能在后台服务器存储一份用户登陆信息,这份信息也会在响应前端请求时返回给浏览器(前端),前端将其保存为cookie,下次请求时前端发送给后端应用,后端应用就可以识别这个请求是来自哪个用户了,这就是传统的session认证
session认证的过程是怎样的? 浏览器第一次访问服务器,服务器会创建一个session,然后同时为该session生成一个唯一的会话的key,也就是sessionid,然后,将sessionid及对应的session分别作为key和value保存到缓存中,也可以持久化到数据库中,然后服务器再把sessionid,以cookie的形式发送给客户端。这样浏览器下次再访问时,会直接带着cookie中的sessionid。然后服务器根据sessionid找到对应的session进行匹配;
还有一种是浏览器禁用了cookie或不支持cookie,这种可以通过URL重写的方式发到服务器;
什么是token认证? token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。
当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。
token认证与session认证的区别? token和session其实都是为了身份验证,session一般翻译为会话,而token更多的时候是翻译为令牌;
session服务器会保存一份,可能保存到缓存,文件,数据库;同样,session和token都是有过期时间一说,都需要去管理过期时间;
其实token与session的问题是一种时间与空间的博弈问题,session是空间换时间,而token是时间换空间。两者的选择要看具体情况而定。
虽然确实都是“客户端记录,每次访问携带”,但 token 很容易设计为自包含的,也就是说,后端不需要记录什么东西,每次一个无状态请求,每次解密验证,每次当场得出合法 /非法的结论。这一切判断依据,除了固化在 CS 两端的一些逻辑之外,整个信息是自包含的。这才是真正的无状态。
而 sessionid ,一般都是一段随机字符串,需要到后端去检索 id 的有效性。万一服务器重启导致内存里的 session 没了呢?万一 redis 服务器挂了呢?
方案 A :我发给你一张身份证,但只是一张写着身份证号码的纸片。你每次来办事,我去后台查一下你的 id 是不是有效。
方案 B :我发给你一张加密的身份证,以后你只要出示这张卡片,我就知道你一定是自己人。
就这么个差别。
一、afc_ps.sh为什么只能用afc用户执行
在root用户下,执行脚本,无内容输出。
root肯定有权限执行。
查看变量$?,输出为0,说明执行成功了。
看脚本,脚本在筛选主程序进程前,筛选了定义值为“whoami”的环境变量。所以root无内容输出。
二、afc_start.sh为什么不能用root执行
首先,系统安全上下文原则其一:启动为进程之后,其进程属主为发起者,进程属组同发起者属组。
当以root用户运行afc_start.sh后,启动的进程属主就不再是afc,而是root。此时afc用户若不在root属组下有权限,便会影响afc对root进程的读写操作。
但现在的脚本来看,脚本前加了用户判断
所以,理论上要想在root用户下启动afc_start.sh,启动不了。
1:什么是ajax?ajax作用是什么? • AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 是一种用于创建快速动态网页的技术
• AJAX可以在不刷新整个浏览器页面的情况下,通过与服务器进行少量数据交换,对网页的某一部分进行更新
• 用于在Web页面中实现异步数据交互,实现页面局部刷新。
• XMLHttpRequest 对象用于在后台,与服务器交换数据,他可以:
在不重新加载页面的情况下更新网页
在页面已加载后从服务器请求数据
在页面已加载后从服务器接收数据
在后台向服务器发送数据
所有现代的浏览器都支持 XMLHttpRequest 对象。
2.AJAX的优缺点? • AJAX的最大特点:页面局部刷新
• ajax的缺点:
1、ajax不支持浏览器back按钮(要实现ajax下的前后退功能成本较大)。
2、安全问题: AJAX暴露了与服务器交互的细节。
3、对搜索引擎的支持比较弱。
4、破坏了程序的异常机制。
• 有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。
3:原生js ajax请求有几个步骤?分别是什么 简述ajax的过程:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>02.XMLHttpRequest兼容性问题</title> </head> <body> <h2>AJAX</h2> <button type="button" onclick="loadXMLDoc()">请求数据</button> <div id="myDiv"></div> <script> function loadXMLDoc() { var xmlhttp; if(XMLHttpRequest){ // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else{ // code for IE6, IE5 xmlhttp=new ActiveXObject('Microsoft.
电快速瞬变脉冲群 平时我们在机械开关切换电感性负载时看到的电弧放电,实际上是在供电线路中产生一连串的高压窄脉冲。这里,供电线路的分布电感起到阻挡脉冲、不被电源短路的作用。下图是实测的开关断开过程中的瞬变干扰的形成情况。可见“尖刺”电压一次比一次大,“尖刺”的间隔时间一次比一次长,与分析中提到开关触点距离在逐渐拉大的解释是一致的。
要求 设备基本性能应可抵御± 2 kV的电源线脉冲以及超过3米长度的信号电缆和互连电缆± 1kV的脉冲。患者耦合电缆不直接测试。然而,应考虑直接试验电缆和直接试验电缆间的任何耦合。 试验要点: 小于3m的信号电缆和互连电缆以及患者耦合电缆不进行直接试验。耦合电缆虽不直接试验,但在其它受试电缆的试验期间应连上患者耦合电缆。患者耦合点应端接模拟手。【电阻和电容串联到大地】有内部备用电池的设备,应在试验后验证设备仅在网电源供电时继续工作的能力。 解决方法 利用高频铁氧体对高频干扰呈阻性,能直接吸收高频干扰并转化为热能的特性,来吸收此类干扰增加磁环,封闭磁环比对扣磁环效果好。信号线用屏蔽双绞线,两端加装磁环。在电源线入口处安装电源线滤波器,阻止干扰进入设备。信号线安装共模滤波电容,或共模扼流圈(低通滤波器)敏感电路屏蔽。
WebAPI是什么? WebAPI 是一种用来开发系统间接口、设备接口 API 的技术,基于 Http 协议,请求和返 回格式结果默认是 json 格式。比 WCF 更简单、更通用,比 WebService 更节省流量、更简洁。
预设应用场景:
比如下面的接口 http://msg.jiyuwu.com “可以”使用 WebAPI 来开发。 WebAPI 是开发接口的技术,用户不会直接和 WebAPI 打交道,因此 WebAPI 也不会生成 界面,这是 WebAPI 和普通 ASP.Net MVC 的区别。
虽然完全使用普通 ASP.Net MVC 甚至 HttpHandler 也可以开发这样的接口,但是 WebAPI 是专门做这个的,更专业。
特点:
因为 ASP.Net WebAPI 专注于接口开发,所有有如下特点:
1)webapi 的 Action 方法返回 值直接返回对象,专注于数据。
2)webapi 更符合 Restful 的风格。
3)有利于独立于 IIS 部署 (selfhost、winform、windows service、控制台)。
4)Action 可以直接声明为 async。
总结:就是给前端提供数据的框架,不管其他任何事情没不管界面,业务,逻辑,有Restful格式的数据提供方式
Post(增)提交数据Get(查)得到数据Put(改)推送数据Delete(删)删除数据
ps:在一些情况下Post也算在增删改里面 创建WebApi项目 创建Asp.net Web应用程序
选择创建WebApi
#!/bin/bash id="" if test -f ".id" then id=$(cat .id) else while [[ ! $id =~ [0-9]{8} ]] do read -p "Plz input hr id: " id done echo $id > ".id" fi MAIN_PROJ=ssh://${id}@gerrit.xxx.com.cn:29418/xxx(远端地址) SUB_PROJ=(proj1, proj2, proj3) CMD=$1 for PROJ in ${SUB_PROJ[@]}; do echo "========${PROJ}========" case $CMD in clone) git clone ${MAIN_PROJ}/${PROJ} ;; *) (cd $PROJ && git $*) ;; esac done
无迹卡尔曼滤波算法用于解决系统方程非线性的情况。无迹卡尔曼滤波算法采用无迹变换对状态值进行采样,采样2n+1个sigma点用于计算均值与协方差。相比于EKF对系统方程线性化,无迹卡尔曼滤波近似程度更高。
系统方程: 状态预测:
观测量计算:
状态更新:
过程推导: 无迹变换:一般用离散采样点恢复一种分布,采样点越多,近似度越高,但计算量也越大,比如蒙特卡洛算法。无迹变换利用2n+1个sigma采样点计算均值与协方差,近似原分布,同时计算量较小。
无迹变换需要满足权值之和为1,均值与协方差加权计算如下公式:
权值和状态计算如下:
权重相关参数计算如下式:
然后计算高斯得到步骤4、5,得到状态的预测值与预测协方差值。利用预测值与预测协方差值计算观测量的计算值与观测量的协方差值得到6-10。
滤波增益类比EKF计算如下: