《体温监测与报警——基于C++ & QT》——开源

项目背景: 在本次“新冠疫情”的冲击下,小区需要监控人员体温,现新进了一批可以采集人体体温的智能体温计,但是小区有三个门:正门,侧门,后门,每个门都会有人员流动,物业希望能够在监控室查看相关人员的体温,可以做匹配记录。 项目需求: (1)每个智能体温计都能采集体温数据并自动上传该数据到监控平台。 (2)监控平台可以实时查看各门,各人员的体温。 (3)对于出现异常体温(超过37.3°C)监控平台会发出报警。 项目开发环境: (1)QT 5.14.2。 (2)SSokit网络调试助手。 技术支持: (1)C语言。 (2)C++。 (3)QT界面开发。 (4)TCP协议。 :具体的项目流程与实现,我用脑图的方式展示给大家。 TCP客户端核心代码: /******************************************************* * * Function name :makeTemp * Description :产生一个16位的数据:高8位整数+低8位小数 * Parameter :NULL * Return :NULL * **********************************************************/ short makeTemp() { // 配置随机种子:根据系统的节拍取 srand(clock()); short temp = 0; char high = 0; char low = 0; while(1) { // 以100ms的时间间隔 usleep(100 * 1000); // 正常体温范围:34-43 // 体温整数部分随机数产生 high = 34 + rand() % 9; // 体温小数部分随机数产生 low = rand() % 100; // 将产生的数值传递给temp中:位运算处理 temp = high; temp = temp << 8; // 最终产生的模拟体温数值 temp += low; gTemp = temp; } } // 全局变量:存储产生的体温数据 short gTemp; int main(int argc, char *argv[]) { // 开启多线程:将数据的产生,放在线程中 QThread::create([](){ makeTemp(); })->start(); // 连接到TCP服务器端 QTcpSocket *client = new QTcpSocket; QHostAddress address("

xargs命令常用参数和常见用法

xargs命令的作用,是将标准输入转为命令行参数。 xargs命令的格式如下。 xargs [-options] [command] 真正执行的命令,紧跟在xargs后面,接受xargs传来的参数。 之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中又有这个必要,所以就有了 xargs 命令, 通过 xargs 的处理,换行和空白将被空格取代。 xargs完成了两个行为:处理管道传输过来的stdin;将处理后的内容传递到正确的位置上。 常用的xargs参数主要分几类: 一)分割选项(xargs、 xargs -d、 xargs -0) 二)分批选项(xargs -n、 xargs -L、 xargs -i),其中-i也能传递替换 三)交互式处理(-p选项)和预先打印一遍命令的执行情况(-t选项) 四)传递终止符(-E选项) xargs处理的优先级顺序:先分割,再分批,然后传递到参数位。 一)分割选项(xargs、 xargs -d、 xargs -0) 1)xargs后面的命令默认是echo cat test.txt |xargs # 等同于 cat test.txt |xargs echo 2)xargs -d选项 默认情况下,xargs将换行符和空格作为分隔符,把标准输入分解成一个个命令行参数 -d参数可以更改分隔符 echo -e "a\tb\tc" | xargs -d "\t" echo 当处理有空格的文件名有时,可用其他非文件名中的字符来分隔,比如\n,\0 cd /tmp && ls |xargs -d"\n" rm -rf 3)xargs -0选项 由于xargs默认将空格作为分隔符,所以不太适合处理包含空格的文件名。 find命令有一个特别的参数-print0,指定输出的文件列表以ASCII码NUL ('\0')分隔。然后,xargs命令的-0参数表示用ASCII码NUL ('\0')当作分隔符。

开发经理的感受(一)

文章目录 背景介绍身份的转变程序猿开发经理 开发过程管理工作的安排工作的跟进工作的提交、测试 其它方面 背景介绍 当上开发经理不到半年时间。团队共5个人。团队主要负责混合云相关的一款公有云产品的优化和维护。 身份的转变 程序猿 如期完成开发经理安排的开发工作。遇到一些解决不了的问题,可以说:完不成了,抛给开发经理。对小组内的其它同事的工作可以不关心不过问。 开发经理 不再过多关心自己写了多少漂亮代码,完成了多么优秀的一些事情;而是以整个团队的整体输出为主要目标。接到需求了,首要考虑的问题是:1.什么时候完成。2.谁来完成比较合适(关于合适,考虑的维度会比较多)。而不是我要如何来做完这个事情。方向一定是:管理。需要清楚团队每个成员的性格以及工作能力,有针对性的安排任务。需要保持比较合理的产品迭代进度,让团队成员觉得比较合适;也就是必须要有阶段目标,而且是一直要有;谁没事干了,那就是你的责任。时刻要有自己的想法,当前阶段需要做什么,未来应该做什么;不要等领导或者产品经理提需求,然后才去做,没有需求的时候,团队做什么(这个可能得看团队或者产品,暂时我没有经历过一直有需求的时候)。上对部门领导,下对团队成员,左对产品经理,右对测试人员,面对多种角色,沟通一定要到位。团队的每一件事情,都和你有关系,要对每一件事情负责。 开发过程管理 工作的安排 安排工作的一些基本内容: 以合适的迭代进度来安排任务,比如一周或者两周;每个迭代都要有对应的里程碑,比如公有云产品的上线,小版本的升级,或者重大功能的完成,最好能有阶段性总结。每个任务都得有开始时间以及deadline,一定要具体到个人。一件事情,我们的需求是什么,现状是什么,目标是什么,以及要达成这个目标的话,接下来可能需要关注哪些重点(这个视情况而定,有时间有必要的情况下,可以做一些说明),上面这些点,在安排任务的时候就得全部说清楚;或者其实是要求开发经理,要先想明白,否则根本无法落实。不一定任何事情,开发经理都知道怎么去做,没有关系,只要说明白你想要什么,并且这个目标是可实现的,然后让同事去自由发挥就行了。工作中肯定会处理一些需要相互协作(团队内部的协作)的工作,所以一定要在安排的时候想清楚每个人负责的边界,不能含糊不清。坚决不允许出现:本身被划分得很细的一件事情同时由多人去做的情况。 安排工作中一些关于个人成长的内容: 知人善任,给什么样的人安排什么样的活,说起来挺简单的,做起来不容易。考虑这几个因素: 个人能力属于哪个层次------决定了安排什么复杂程度的工作。个人所喜欢做的事情以及不喜欢做的事情------安排做喜欢的事情当然很乐意,不喜欢做的事情难免有一些抵触情绪(工作嘛,当然不是喜欢不喜欢,但得知道)。个人较强的方面以及稍弱的方面------较强的方面,可以把一些紧急的任务安排下去,也能够保证进度;稍弱的方面,就是你来负责提升的点,适当的时候应该给予机会去让其锻炼和成长(前提是对方愿意,这个从侧面了解或者正面直接沟通就行了)。个人对待工作的态度、做事情的方式------这个决定了工作中如何沟通吧,最难的一个吧。 安排工作的时候,一定要给同事留一定的发挥空间;把自己该做的做了,剩下的相信他们,让他们去做。有挑战性的,或者无聊的搬运工作,相互兼顾着来吧。适当的时候,安排一些超过个人能力本身的工作,其实就是把本来应该自己做的事情安排下去,比如一些设计或者调研工作;或者一些个人没有做过的工作。 工作的跟进 工作安排出去了,那到底做得怎么样,什么时候才能够让你看一下效果,什么时候能够开发完成,什么时候测试就可以介入测试,能不能按照预期的做完,这些事情,你都必须要清楚。 简单来讲,你需要一个:任务看板。 任务看板的具体形式的话,根据情况而定吧,一般情况下,公司内部会有有关开发过程管理的工具,比如jira,或者更简单的一些,就是excel表格了,最好能够共享的那种。 不管是什么样的形式,一个任务看板中要能够包含下述基本内容: 每一个迭代中所包含的所有任务。每个人手中目前有多少个任务。每个任务当前处于什么样的阶段:未开始、开发中、开发完成自测中、测试介入等等。阶段的话,主要是以你所关心的阶段为主。最重要的一点:每个人要主动实时的更新任务的状态;被迫更新的话,可能就只是单纯的做一些面子工程了,也起不到开发过程的管理效果了。 但是实际上,小团队的开发过程往往都是敏捷开发,而且加上小团队本身的特点(人数少,迭代快,距离近交流方便),如果非得用任务看板来推进的话,可能会浪费一定时间而且效果也不少,距离这么近,一句话就能说明白,还非得用看板? 可能对于一个事业部老大而已,几十或者几百人,那他们肯定只能看任务看板了,然后到了每个部门的话,有大概10-30人左右,对于部门经理,没有办法详细跟进每个任务,那也只能看面板。但是到了每个开发小组的话,就那么点人,再继续用的话,可能就不是特别合适了。 所以一定要根据实际的情况,有针对性的使用一些过程管理工具来提高开发效率。 我这边目前的一些做法就是: 使用jira来记录跟踪一些比较大的特征。使用协同文档excel来细化每一个开发特征,列出具体的开发任务、负责人、迭代结束的日期等。(目前我们这边开发过程管理工具更多的是从产品层面来使用的,但是从开发角度来说的话,还差那么点意思,比如可能要关注哪些方面,要重构哪些代码等等,所以就用表格了,感觉更能满足我的需求)发现的bug,用Jira来记录,这个可以上传图片、附件等,完成了打个关闭,然后自己去验证,可以验证通过或者不通过。 使用什么样的工具或者方式来进行开发过程的管理,不重要,重要的是我们保证开发任务的正常迭代,所以根据实际的情况找出合理的方式才是最重要的,而且要不断升级优化自己的管理迭代方式。 另一方面,跟同事说任务进度的时候,可能需要注意的点: 可以一次性安排很多任务,在不着急的情况下,可以让他们自由安排,按照自己的想法去执行就行了。但是得说一个整体的截止日期,或者针对某个任务的截止日期。一些任务变得紧急了,立即告诉同事,直接调整安排的进度。一些任务眼看着要完不成了,要适当地说一些比较重要,必须完成之类的话,要想办法促进任务的迭代速度,有一些适当的鼓励措施,对个人,对团队。充分沟通之后,要是还是做不完的话,就得及时提前和相关人员沟通好延期问题。 工作的提交、测试 前面说到安排和跟进,完成了以后,那就要提交了。 需要一个清单,这个可能和开发任务或者特征有所不同;这个清单是给产品和测试人员看的,所以更多的是功能清单,以及需要注意的点,影响的范围,基本的测试方案。用这个清单,和测试人员交流一次,然后去测试。测试完全通过以后,让测试把所有的测试用例整理出来,再过一波,看看有没有遗漏的;然后用这份测试用例用于后面的迭代上线。列一份上线流程,在预发、灰度等环境就直接使用此流程上线。需要额外记录一下在预发环境、灰度环境遇到的所有问题,彻底分析问题如何产生的,怎么解决,以及如何在正式环境避免。上线结束后,做一份上线总结,总结做的好的地方,进行鼓励和表扬;但是对做的不好的地方,仍然需要指出来,责任自己先背了,但是怎么处理以及后续避免的方式,让相关的责任去完成。 其它方面 上面主要分享了身份转变以及开发过程管理的一些感受吧,要说的话,还有其它的一些方面: 团队工作氛围的营造,工作方式的规范。开发经理的持续成长。如何成为开发经理。 后面再分享吧,就先说这么多。

sqlloader用法案例

介绍 Oracle 的sql loader可以将外部数据加载到数据库表中 ,使用sqlldr可以在短时间内向数据库中加载大量的数据 。本文仅以一个案例介绍sqlldr的用法。 用法举例 sql loader的命令 sqlldr userid=用户名/密码@sid control=/file/control/dept.ctrl log=/log/control/dept.log data=/file/data/dept-2020-06-11.txt ctrl控制文件 dept.ctrl Load data characterset ZHS16GBK Append into table dept TRAILING NULLCOLS ( dept_id CHAR terminated by "|", dept_name CHAR terminated by "|", dept_create Date "YYYY-MM-DD HH24:MI:SS" terminated by "|" ) 其中dept为表名,dept_id、dept_name、dept_create为表中字段名,文件中的内容以|分隔,行如 dept-2020-06-11.txt 1|人事部|20100611 2|网络部|20140612 TRAILING NULLCOLS属性允许导入的列字段值为空,如果没有该属性,为空时则报错 官网 http://psoug.org/reference/sqlloader.html

万能命令

在日常工作生活中下载文档资料、网上购物、看电影追剧,早已成为生活的中的一部分,在面对这些生活工作必要内容你是是怎么办的呢?还在花钱下载文档?追剧开会员吗?今天就教你无需任何工具,只需要几个简单的命令就能让你在浏览器上直接白嫖各种免费资源。 文章目录 1. VVV—免费下载百度文库文档2. VVV — 淘宝、京东 商品历史价格查询3. 365 — 豆丁文库免费下载4. wn.run/ — 万能命令无需开会员观看影视 1. VVV—免费下载百度文库文档 百度文库的共享文档作为获取资料重要选择,在下载的时候往往都是需要下载券才开可以下载。现在只需要用到三个字母“vvv”就可以免费下载百度文库文档。 在需要下载的文档地址栏中的baidu域名后加上vvv之后,然后点击回车就会直接跳转到下载页面。点击下载按钮即可下载。 2. VVV — 淘宝、京东 商品历史价格查询 通过对比商品的历史价格我们可以摸索到商品的降价规律,让你在最合适的时间买到最便宜的商品。以京东为例! 打开需要查看历史价格的商品页面,然后在域名jd后面加上vvv,回车之后就可以直接看到你要购买商品的历史价格。以折线图的形式显示出商品近几个的价格走势。 3. 365 — 豆丁文库免费下载 豆丁文库同样是大家常用下载文档的网站,只需要在下载文档域名后面加上365三个数字,然后点击回车按钮直接可以跳转到下载界面! 目前跳转到豆丁文库下载界面之后还需要,填写下载口令,下载口令可以直接在下载界面获取。目前口令为:6666 4. wn.run/ — 万能命令无需开会员观看影视 万能命令是一个在线工具效率平台,通过在网站地址前面增加wn.run/命令的方式,就可以让你用最方便的方式寻找和使用各类在线工具。 比如我们打开某奇艺视频网站,在需要观看视频页面地址栏最前面加上 wn.run/命令,然后回车。就会直接跳转到万能命令网站页面,并为你寻找可以播放解析此视频的网站,直接点击下方的网站就可以直接观看了。 万能命令,并不是局限于视频网站解析,任何网站你都可以通过此命令去尝试。 万能命令官网:https://wn.run/cn/

动态规划问题

淘宝的“双十一”购物节有各种促销活动,比如“满 200 元减 50 元”。假设你女朋友的购物车中有 n 个(n>100)想买的商品,她希望从里面选几个,在凑够满减条件的前提下,让选出来的商品价格总和最大程度地接近满减条件(200 元),这样就可以极大限度地“薅羊毛”。 作为程序员的你,能不能编个代码来帮她搞定呢?要想高效地解决这个问题,就要用到我们今天讲的动态规划(Dynamic Programming)。 动态规划比较适合用来求解最优问题,比如求最大值、最小值等等。它可以非常显著地降低时间复杂度,提高代码的执行效率。不过,它也是出了名的难学。它的主要学习难点跟递归类似,那就是,求解问题的过程不太符合人类常规的思维方式。对于新手来说,要想入门确实不容易。不过,等你掌握了之后,你会发现,实际上并没有想象中那么难 1.动态规划——"一个模型三个特征"理论 什么样的问题适合用动态规划来解决呢?换句话说,动态规划能解决的问题有什么规律可循呢?实际上,动态规划作为一个非常成熟的算法思想,很多人对此已经做了非常全面的总结。我把这部分理论总结为“一个模型三个特征”。 首先,我们来看,什么是“一个模型”?它指的是动态规划适合解决的问题的模型。我把这个模型定义为“多阶段决策最优解模型”。下面我具体来给你讲讲。 我们一般是用动态规划来解决最优问题。而解决问题的过程,需要经历多个决策阶段。每个决策阶段都对应着一组状态。然后我们寻找一组决策序列,经过这组决策序列,能够产生最终期望求解的最优值。 现在,我们再来看,什么是“三个特征”?它们分别是最优子结构、无后效性和重复子问题。这三个概念比较抽象,我来逐一详细解释一下。 最优子结构 我们可以理解为,后面阶段的状态可以通过前面阶段的状态推导出来。 无后效性 无后效性有两层含义,第一层含义是,在推导后面阶段的状态的时候,我们只关心前面阶段的状态值,不关心这个状态是怎么一步一步推导出来的。第二层含义是,某阶段状态一旦确定,就不受之后阶段的决策影响。前面阶段的状态确定之后,不会被后面阶段的决策所改变。可以理解为不可后退性。 重复子问题 不同的决策序列,到达某个相同的阶段时,可能会产生重复的状态。 当然,我们可以使用实例对“一个模型三个特征进行剖析”。 假设我们有一个 n 乘以 n 的矩阵 w[n][n]。矩阵存储的都是正整数。棋子起始位置在左上角,终止位置在右下角。我们将棋子从左上角移动到右下角。每次只能向右或者向下移动一位。从左上角到右下角,会有很多不同的路径可以走。我们把每条路径经过的数字加起来看作路径的长度。那从左上角移动到右下角的最短路径长度是多少呢? 我们先看看,这个问题是否符合“一个模型”? 从 (0, 0) 走到 (n-1, n-1),总共要走 2*(n-1) 步,也就对应着 2*(n-1) 个阶段。每个阶段都有向右走或者向下走两种决策,并且每个阶段都会对应一个状态集合。 我们把状态定义为 min_dist(i, j),其中 i 表示行,j 表示列。min_dist 表达式的值表示从 (0, 0) 到达 (i, j) 的最短路径长度。所以,这个问题是一个多阶段决策最优解问题,符合动态规划的模型。 我们再来看,这个问题是否符合“三个特征”?我们可以用回溯算法来解决这个问题。如果你自己写一下代码,画一下递归树,就会发现,递归树中有重复的节点。重复的节点表示,从左上角到节点对应的位置,有多种路线,这也能说明这个问题中存在重复子问题。 如果我们走到 (i, j) 这个位置,我们只能通过 (i-1, j),(i, j-1) 这两个位置移动过来,也就是说,我们想要计算 (i, j) 位置对应的状态,只需要关心 (i-1, j),(i, j-1) 两个位置对应的状态,并不关心棋子是通过什么样的路线到达这两个位置的。而且,我们仅仅允许往下和往右移动,不允许后退,所以,前面阶段的状态确定之后,不会被后面阶段的决策所改变,所以,这个问题符合“无后效性”这一特征(即不能回退)。

vue学习-element-ui全部导入与按需加载

vue学习-element-ui全部导入与按需加载 目录 文章目录 1、版本简介1、element-ui安装2、全部导入3、按需加载4、全部导入与按需加载比较***后记*** : 内容 1、版本简介 版本简介@vue/cli4.4.6vue脚手架,搭建vue项目vue2.6.11vue框架核心element-ui2.13.2UI框架babel-plugin-component1.1.1element-ui按需加载组件 1、element-ui安装 npm i element-ui -S 解析: i:install 安装-S:本地项目依赖安装 2、全部导入 在main.js中导入: import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import App from './App.vue'; Vue.use(ElementUI); new Vue({ el: '#app', render: h => h(App) }); 3、按需加载 首先,安装babel-plugin-component: npm install babel-plugin-component -D 其次,配置babel.config.js文件 "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ] 完整.babel.comfig.js如下,前面部分为默认 module.exports = { presets: [ '@vue/cli-plugin-babel/preset' ], "

深信服(scsa认证)学习过程

深信服scsa认证 考试大纲:满分为120分,一共60道选择题,每小题2分,答对40道选择题为及格,才能参加下面的实验考试。 考试内容: 网络基础知识考点: 1.osi七层模型:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层 TCP/IP模型:网络接入层(物理层,数据链路层),internet层(网络层),传输层(传输层),应用层(会话层,表示层,应用层) 2.数据封装(data encapsulation):将数据放置在每层头的后面以及尾之前的概念 第5,6,7层:data(数据),bytes(字节流) 第4层:segment(段) 第2层:frame(帧) 第1层:bits(比特流) 3.数据分装如何确定上层协议: 帧头中:用protocol type 如 ip 为ox0800 包头中;用protocol 号,如 udp(17) ospf(89)icmp(1) 段头中:用TCp 或者udp端口号,TCP:http(80)https(443)udp:ripv2(520)dns(53) 以太网帧结构: 支持4种各不兼容的帧的封装类型,Ethernet II(Type2)用于IP,IEEE 802.3用于其它。 以太网寻址: 用MAC地址,48位的二进制,通常表示成十六进制的12位,全球唯一 总结: 1.网路设备如何确定以太网数据帧的上层协议? 以太网帧中包含一个type字段,表示帧中的数据应该发送到上层的哪个协议处理。比如,IP协议对应的type值为0X0800,arp协议对应的type值为0X0806 2.终端设备接收到数据帧时,会如何处理? 主机检测帧头中的mac地址,如果说目的mac地址不是本机的mac地址,也不是本机侦听的组播或者广播mac地址,那么主机就会丢弃收到的帧。如果目的mac地址是本机的mac资质,这时候接受该数据帧,检测数据帧校验序列(FCs)字段,并且与本机计算的值来做对比用来确认数据帧在传输过程中是否保持了完整性。如果检测通过,就会剥离帧头和帧尾,然后根据数据帧头中的type字段来来决定是否把数据发送到那个上层协议进行后续处理。 IP寻址(IP Addressing) IP地址 A、结构:32位的二进制数 前为网络ID,后为主机ID 网络ID:标识某个网段,即网络ID的相同的主机在同一个网段 主机ID:在网段内标识一个TCP/IP节点。 B、表示:四段(Octet) 主机ID都是0.0.0.0表示网络地址(网络号) 主机ID都是1.1.1.1表示本网的广播地址 子网掩码(Subnet Mask. SM) 作用:分开网络ID和主机ID,是一个32位的二进制数,由两部分组成, 前一部分,为连续的1,用来识别网络ID。 后一部分,为连续的0,用来识别主机ID。 工作原理:用目标IP地址与子网掩码进行布尔的"and(与)"运算。求出网络地址(网络号) a. 如果目标网络地址与本机网络地址相等(在同一网段)直接将包发给目标主机。 b. 如果目标网络地址与本机网络地址不相等(不在同一网段)则把包发给路由器(默认网关)。 ICMP(Internet Control Message Protocol): 协议号=1,用Type和Code定义。Type表示ICMP消息类型,Code表示同一消息类型中的不同消息。 ICMP重定向(ICMP Redirect):可用于路由功能,不安全! ICMP差错检测:用ICMP ECHO,发送ECHO Request(Type 8),接收ECHO Replay(Type 0)。例如ping命令。

四种引用类型(强引用、软引用、弱引用、虚引用)的简单介绍

四种引用类型 JDK1.2 之前,一个对象只有“已被引用”和"未被引用"两种状态,这将无法描述某些特殊情况下的对象,比如,当内存充足时需要保留,而内存紧张时才需要被抛弃的一类对象。 所以在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱。 一,强引用 Object obj = new Object(); //只要obj还指向Object对象,Object对象就不会被回收 obj = null; //手动置null 只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了 二,软引用 软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。 在 JDK1.2 之后,用java.lang.ref.SoftReference类来表示软引用。 三,弱引用 弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。在 JDK1.2 之后,用 java.lang.ref.WeakReference 来表示弱引用。 四,虚引用 虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。

数据库中转化为3NF的几个分解算法

【例】 关系模型R<U,F>,U={A,B,C,D,E},F={A→BC,ABD→CE,E→D} 算法一:将关系R转化3NF的保持函数依赖的分解 第一步:首先计算处F的最小函数依赖集(算法详见最小函数依赖),得到F‘= {A→BC,AD→E,E→D}。 第二步:观察U中是否有属性不再F’中的出现,如果有,则这个属性组成一对关系R,并在原来的U中删除这些属性。而例子中U的属性都出现在F中,则可以跳过这一步。 第三步:对F‘中的函数依赖,把左边的相同分为一组,一组中出现的所有属性为一个关系。如F={A→B,A→C,……},左边都为A的分为一组,得出项的所有属性组为也给关系R{A,B,C,…}例题中左边都不相同,所以一个函数依赖组为一个关系得到转化为3NF的保持依赖分解R1{A,B,C},R2{A,D,E},R3{E,D}。 算法二:将关系R转化为3NF的既有无损连接有保持函数依赖的分解 第一步:先将R转化为3NF的保持函数依赖的分解,由算法一的出R1{A,B,C},R2{A,D,E},R3{E,D}。 第二步:求出F的候选码(算法见候选码算法)得出候选码X为AD和AE。 第三步:将候选码单独组成关系得R4{A,D}和R5{A,E},然后与保持函数依赖后得分解取并集。得R1{A,B,C},R2{A,D,E},R3{E,D},R4{A,D},R5{A,E}。。、 第四步:观察新组成得分解模式中,是否存在包含关系,有责去掉被包含得。如R3{E,D},R4{A,D},R5{A,E}都包含于R2{A,D,E},则删除,最终得到转化为3NF的既有无损链接有保持函数依赖的分解R1{A,B,C},R2{A,D,E}。

【Leetcode刷题】【155】最小栈

题目描述 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 push(x) —— 将元素 x 推入栈中。 pop() —— 删除栈顶的元素。 top() —— 获取栈顶元素。 getMin() —— 检索栈中的最小元素。 标题 借用一个辅助栈min_stack,用于存获取stack中最小值。 算法流程: 1.push()方法: 每当push()新值进来时,如果 小于等于 min_stack栈顶值,则一起push()到min_stack,即更新了栈顶最小值; 2.pop()方法: 判断将pop()出去的元素值是否是min_stack栈顶元素值(即最小值),如果是则将min_stack栈顶元素一起pop(),这样可以保证min_stack栈顶元素始终是stack中的最小值。 3.getMin()方法: 返回min_stack栈顶即可。 min_stack作用分析: min_stack等价于遍历stack所有元素,把升序的数字都删除掉,留下一个从栈底到栈顶降序的栈。 相当于给stack中的降序元素做了标记,每当pop()这些降序元素,min_stack会将**相应的栈顶元素pop()**出去,保证其栈顶元素始终是stack中的最小元素。 class MinStack { private Stack<Integer> stack; private Stack<Integer> min_stack; public MinStack() { stack = new Stack<>(); min_stack = new Stack<>(); } public void push(int x) { stack.push(x); if(min_stack.isEmpty() || x <= min_stack.peek()) min_stack.push(x); } public void pop() { if(stack.

SpringBoot第一谈(第一个SpringBoot项目、核心配置文件properties(yml、yaml)、集成jsp)

本人是一名在医学院校学习计算机的学生,即将进入大三,写博客即是为了记录自己的学习历程,又希望能够帮助到很多和自己一样处于起步阶段的萌新。临渊羡鱼,不如退而结网。一起加油! 博客主页:https://blog.csdn.net/qq_44895397 SpringBoot简介及国内关注度 SpringBoot简介: 它用来简化 Spring 应用程序的创建和开发过程,也可以说 Spring Boot 能简化我们之前采用 SpringMVC +Spring + MyBatis 框架进行开发的过程。在以往我们采用 SpringMVC + Spring + MyBatis 框架进行开发的时候,搭建和整合三大框架,我们需要做很多工作,比如配置 web.xml,配置 Spring,配置 MyBatis,并将它们整合在一起等,而 Spring Boot 框架对此开发过程进行了革命性的颠覆,完全抛弃了繁琐的 xml 配置过程,采用大量的默认配置简化我们的开发过程。所以采用 Spring Boot 可以非常容易和快速地创建基于 Spring 框架的应用程序,它让编码变简单了,配置变简单了,部署变简单了,监控变简单了。 国内关注度 Spring Boot 的特性 能够快速创建基于 Spring 的应用程序能够直接使用 java main 方法启动内嵌的 Tomcat 服务器运行 Spring Boot 程序,不需要部署 war 包文件提供约定的 starter POM 来简化 Maven 配置,让 Maven 的配置变得简单自动化配置,根据项目的 Maven 依赖配置,Spring boot 自动配置 Spring、Spring mvc等提供了程序的健康检查等功能基本可以完全不使用 XML 配置文件,采用注解配置 第一个 SpringBoot 项目 1、创建一个 Module 2、设置 GAV 坐标及 pom 配置信息 3、选择 Spring Boot 版本及依赖 4、设置模块名称、Content Root 路径及模块文件的目录 5、项目结构 mvn|mvnw|mvnw.

【Leetcode刷题】【15】三数之和

题目描述 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ] 暴力法 输入的数组元素过多时,处理的时间会很长,超出时间限制,不推荐 private List<List<Integer>> directlySolution(int[] nums) { if (nums == null || nums.length <= 2) { return Collections.emptyList(); } Arrays.sort(nums); Set<List<Integer>> result = new LinkedHashSet<>();//这里用set集合存放结果 for (int i = 0; i < nums.length; i++) { for (int j = i+1; j < nums.

java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合

java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 java stream toArray() 发现 java 使用 stream 时,经常会将 map 后的数据输入到数组中,这时一般在 stream 语句后面 加上 toArray(). 若是对象数组,则要在 toArray 里面加上 生产对象数组的方法引用。 例如: Integer 数组: toArray(Integer[] :: new). person 数组: toArray(person[] :: new). String[] Addr = instancesList.stream().map(x->x.getIp()).toArray(String[]::new);

Filebeat收集服务端日志

一、什么是Filebeat? Filebeat是轻量级本地文件的日志数据采集器,可监控日志目录或特定日志文件,并将它们转发给Elasticsearch或Logstatsh进行索引、kafka等。带有内部模块(auditd,Apache,Nginx,System和MySQL),可通过一个指定命令来简化通用日志格式的收集、解析和可视化,能做到实时收集日志,延迟在秒级,配置非常简单方便,占用资源少。 二、业务背景? 公司后端服务都是使用Golang开发的,服务部署在多台节点上,日志没有统一收集,异常问题排查困难,根据以往经验,首先想到EKL这一套日志系统。整个日志链路是这样的:Filebeat收集日志——> Elasticsearch 存储日志——> Kibana日志可视化查询。 三、安装Filebeat step1: 官网下载对应版本的安装包 https://elasticsearch.cn/download 采坑记录:一开始下载的是tar.gz的安装包,配置完之后,使用nohup ./filebeat -e -c filebeat.yml >/dev/null 2>&1 & 方式启动,运行一段时间后进程总是自动停止了,查阅各种资料之后,得到解决方案,下载rpm包安装。 step2.安装 rpm -ivh filebeat-7.6.0-x86_64.rpm 3.修改主配置文件该步骤同tar包,查询配置文件的路径可通过: rpm -ql filebeat | more 配置文件目录: /etc/filebea/filebeat.yml 修改配置文件 4.以系统服务方式启动filebeat systemctl enable filebeat.service --设置服务开机自启动 systemctl start filebeat.service --启动服务 5.查看状态: service filebeat status 三、重点Filebeat配置filebeat.yml filebeat.inputs: # 多个后端服务,每个后端服务日志目录不同,给不同的日志目录设置不同的tag enabled: true paths: - /data/es/aaa.log tags: ["aaa-test"] fields: index: 'aaa-log' - type: log # Change to true to enable this input configuration.

git 常用指令(含公司常用分支操作)

git 基本指令 git add . git commit -m"msg" git push 公司常用分支操作 一般大家开发,都会用自己分支开发,然后mr到master分支,那么master分支有可能被别的分支更新过了,就会造成本地master和远程不一致,如果解决这个问题, 步骤: 先切换到master分支同步远程master代码切到自己分支merge master到自己分支commit 自己分支,然后在gitlab等提MR,别人codereview就可以合入了。 指令: git checkout master git pull git checkout 自己分支 git merge master (可能会有冲突,手动解决即可) git add . //这步可能是赘余 git commit -m"msg" git push gitlab提MR,别人review 某些情况下,需要拉取指定的远程分支,可以用如下指令: git fetch origin 分支名 git checkout -b 分支名 origin/分支名 如果自己分支是新建的话 git checkout -b 分支名 注意这样的话,push要加--set-upstream,一般git会提示 删除分支操作 git checkout master git branch -D 分支名 //删除时候需要切到别的分支

sqlachemy查询集转化字典或者json格式的方法

方法一 在model中加入 def to_dict(self): return {c.name: getattr(self, c.name) for c in self.__table__.columns} 在服务中调用 def all_to_json(all_vendors): v = [ven.to_dict() for ven in all_vendors] return v # 查询结果调用 item = all_to_json(objs) # 或者直接调用to_dict() item = [] for obj in objs: item.append(obj.to_dict()) 方法二 在model中加入 def to_json(self): dict = self.__dict__ if "_sa_instance_state" in dict: del dict["_sa_instance_state"] return dict 在服务中调用同上 json的坑 TypeError: datetime.datetime(2020, 6, 24, 10, 11, 32) is not JSON serializable 解决方法 import json import datetime # 使json支持datetime json.

macbook中 Navicat Premium连接数据库出现2003错误 如何解决

macbook Navicat Premium 连接数据库中出现2003 - Can’t connect to MySQL server on ‘127.0.0.1’ (61 “Connection refused”) 如何解决 折磨了好久,跟解决重启一个套路,思路混乱 原文地址:https://www.cnblogs.com/Jokerguigui/p/11724356.html 第一步 关闭mysql服务: 苹果->系统偏好设置->最下边点mysql 在弹出页面中 关闭mysql服务(点击stop mysql server) 如果这种方法没有成功: 可以使用命令行关闭mysql: ~$ sudo /usr/local/mysql/support-files/mysql.server stop 第二步 1、进入终端输入: cd /usr/local/mysql/bin 2、回车后 登录管理员权限 sudo su (输入你电脑的密码) 3、回车后输入以下命令来禁止mysql验证功能 ./mysqld_safe --skip-grant-tables (注意是mysqld) 4、回车后mysql会自动重启(偏好设置中mysql的状态会变成running) 第三步 1、输入命令 ./mysql 2、回车后,输入命令 FLUSH PRIVILEGES; 3、回车后,输入命令 ALTER user 'root'@'localhost' IDENTIFIED BY '123456' (123456,这是新密码随意写一个记住的) 第四步 重启mysql: ~$ sudo /usr/local/mysql/support-files/mysql.server restart 这就OK了,OK了!!!!!

layui 表单组件(form)支持手动触发校验

文章目录 前言webjar方式引入通过文件引入通过源码编译源码 前言 在使用layui v2.5.6 的表单组件时,原生表单组件的校验事件,需要绑定到按钮,在提交时自动触发。 在只需要做校验操作的情况,由于没有提供表单校验方法,处理比较复杂,这里对源码进行了修改,抽离了表单校验逻辑,封装为 form.doVerify(filter) ,校验通过返回true,否则返回false webjar方式引入 设置maven仓库 <repositories> <repository> <id>rdc-releases</id> <url>https://repo.rdc.aliyun.com/repository/130254-release-UtHk7a/</url> </repository> <repository> <id>rdc-snapshots</id> <url>https://repo.rdc.aliyun.com/repository/130254-snapshot-X1tQyc/</url> </repository> </repositories> 替换layui依赖 <dependency> <groupId>org.webjars.bowergithub.jaychoufans</groupId> <artifactId>layui-plus</artifactId> <version>2.5.6-SNAPSHOT</version> </dependency> 使用校验 if(form.doVerify('lay-filter')){ // 校验通过执行 } 校验通过返回true,否则返回false 功能稳定,打包为快照版本,是为了其他功能的优化考虑 通过文件引入 地址:https://github.com/JayChouFans/layui-plus/tree/v2.5.6 拉取代码,layui文件夹为修改后全部文件 通过源码编译 源码地址:https://github.com/ly641921791/layui-plus/tree/v2.5.6.plus 拉取代码, 搭建环境,进行编译,环境搭建方法省略 源码 功能代码查看 点击查看全部源码

lombok不区分大小写引起的问题

import lombok.Data; @Data public class TestDTO { private Integer pId; } 如上代码所示,在这个DTO中,传递如下参数,但是后端无法接收 { "pId":1 } 原因:使用lombok的@Data注解后,生成的get/set方法如下 // 参数名的首字母和第二个字母都变成了大写 getPId(); setPId() 而在JavaBean规范中,有如下规范,所以这里方法名应为getpId和setpId 如果属性名的第二个字母大写,那么该属性名直接用作 getter/setter 方法中 get/set 的后部分,就是说大小写不变。例如属性名为uName,方法是getuName/setuName。 在用实体接收get请求参数时,首字母会变大写,在post接收实体时,第二个字母大小写有问题 解决办法: 自己生成get/set方法

torch.multinomial使用

在Word2vec中使用到了非相关数据的降采样方法, 其中用到了torch.multinomial方法, 这里记录一下: multinomial(input, num_samples, replacement=False) 该方法主要有三个参数, 分别是输入的张量, 采样的个数, 是否有重复的数据, 采样的时候是根据输入张量的数值当做权重来进行抽样的, 数值越大, 抽到的可能性越大, 越小抽到的可能性越小, 如果是0 则不会抽到 由案例可知, 输出的是出入的张量的索引值, 当非零数据只有4个时, 要输出5个不重复的数据会报错 而可以重复数据时, 即使去很多值, 也不会取到, 索引值为0的, 因为其权重是0

MacOS常用设置

MacOS常用设置 一、访达显示文件路径 (一)描述 在苹果访达上有时需要像Windows那样能看到当前在访达位置,特别在进入特别多层打开多个访达窗口。 (二)设置 访达->显示->显示路径栏(打钩) 设置完效果 二、禁止创建.DS_Store (一)描述 .DS_Store(Desktop Services Store)在Mac OS上用于存储目录的自定义属性,本来这个也没有什么问题,但使用NAS时Mac OS会在所有已查看目录下面创建.DS_Store这就比较恶心了。查了下Mac OS是可以禁止创建.DS_Store,还看到为.DS_Store创建.DS_Store的情况。 (二)设置 1.终端执行 defaults write com.apple.desktopservices DSDontWriteNetworkStores true 2.重启计算机 (三)参考 Mac OS X v10.4 and later: How to prevent .DS_Store file creation over network connections

MAC安装MySQL不能启动,更改方式

Mac系统,安装MySQL 8.0.20版本 ,突然启动不了 一、在系统偏好设置中没办法停止服务,只能强制退出,用command+空格,输入activity monitor,进入运行进程中,关闭mysql. 二、终端输入: cd /usr/local/mysql/bin sudo su 安全模式启动,然后输入: ./mysqld_safe --skip-grant-tables & 三、新开一个窗口登入更改密码: mysql -u -root user mysql; update user set authentication_string="" where user='root'; ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码'; 重启mysql,就OK

用自己话了解Ajax的基本使用

ajax优点:异步局部刷新,不打断用户的操作,增强B/S架构的体验性 B/S:浏览器对服务器 C/S:客户端与服务器 ajax获取文本框中的值:$("文本框id").val(); 实例:function a1(){ $.ajax({//ajax默认get提交 url:"${pageContext.request.contextPath}/控制器里的路径", //url:提交的路径 data:{"控制器中方法的变量名":$("文本框ID").val()},//data:要传给控制器的参数:获取到文本框中的值 success:function(data){ //success:载入成功回调的函数 console.log(data);//data:封装了服务器返回的数据 console.log(status)//status:状态 } }) } 遍历一个list数据显示: $(function(){ $("点击按钮的ID").click(function(){ $.post("${pageContext.request.contextPath}/提交的路径地址"),function(data){ conaole.log(data); var html = ""; for(var i= 0;i<data.lenght;i++){ html +="<tr>"+ "<td>"+data[i].pojo类中的变量名+"</td>"+"</tr>" } $("#context").html(html); } }) }) Ajax编写三部曲: 编写对应处理的Controller(控制器),方悔消息或者字符床或者JSON格式编写$.ajax请求: URl:Controller中的方法访问路径data:要传给Controller的参数success:返回的函数显示给后端或者客户看 给Ajax绑定事件,点击click,失去焦点onblur,键盘弹起keyup Ajax中get请求与Post请求的区别: 安全方面:Get是不安全的,因为他传的参数可以在浏览器中的Url上可见,Post他是不可见的别人获取不到所以说Post比Get安全请求路径的长度:Get的长度是有限制的、他的限定长度根据浏览器的不同而不同而Post没有长度限制速度方面:Get比Ajax速度要快,Get在发送请求后的到浏览器的回复就直接完成操作了但是Post在发送请求后要等到浏览器确认后它才会继续去提交数据给浏览器

使用 Visual Studio Code 运行 Elasticsearch queries

今天我发现我们实际上可以使用 VSCode 运行 Elasticsearch DSL queries。如下是我采用的步骤: 创建一个 .es 文件 sample.es GET _cat/indices 使用 VScode 打开这个文件 code sample.es 我们选择 elasticsearch 语言 我们选择 localhost:9200 作为 Elasticsearch 的地址。我们点击 enter 键确认。 安装上面的工具。 我们在刚才的 .es 文件的目录中创建一个叫做 default.esenv 的文件: default.esenv { "host": "http://localhost:9200", "name": "dev" } 它的内容是如上所示。 $ pwd /Users/liuxg/data/vcode liuxg:vcode liuxg$ ls default.esenv sample.es 我们在 VSCode 里打开这个文件夹。 我们选择上面的文件进行测试。如果没有问题的话,会在屏幕的下方显示OK 的信息。 我们接着把这个 sample.esenv 设置为目标环境: 一旦设置完毕,我们就可以打开 sample.es 文件,并执行命令: 我们可以接着打入新的命令:

kafka日志被异常清理导致进程频繁挂掉

项目中使用到了kafka作为消息中间件,但是部署到服务器上之后kafka进程不定期挂掉,zookeeper却无任何影响。 1.错误日志 最近一次项目中kafka挂掉,查看日志文件kafkaServer.out看到了如下的错误: [2020-06-21 17:35:04,919] ERROR Failed to clean up log for __consumer_offsets-30 in dir /tmp/kafka-logs due to IOException (kafka.server.LogDirFailureChannel) java.nio.file.NoSuchFileException: /tmp/kafka-logs/__consumer_offsets-30/00000000000000000074.index at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86) at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) at sun.nio.fs.UnixCopyFile.move(UnixCopyFile.java:409) at sun.nio.fs.UnixFileSystemProvider.move(UnixFileSystemProvider.java:262) at java.nio.file.Files.move(Files.java:1395) at org.apache.kafka.common.utils.Utils.atomicMoveWithFallback(Utils.java:815) at kafka.log.AbstractIndex.renameTo(AbstractIndex.scala:209) at kafka.log.LogSegment.changeFileSuffixes(LogSegment.scala:509) at kafka.log.Log.asyncDeleteSegment(Log.scala:1962) at kafka.log.Log.$anonfun$replaceSegments$6(Log.scala:2025) at kafka.log.Log.$anonfun$replaceSegments$6$adapted(Log.scala:2020) at scala.collection.immutable.List.foreach(List.scala:392) at kafka.log.Log.replaceSegments(Log.scala:2020) at kafka.log.Cleaner.cleanSegments(LogCleaner.scala:602) at kafka.log.Cleaner.$anonfun$doClean$6(LogCleaner.scala:528) at kafka.log.Cleaner.$anonfun$doClean$6$adapted(LogCleaner.scala:527) at scala.collection.immutable.List.foreach(List.scala:392) at kafka.log.Cleaner.doClean(LogCleaner.scala:527) at kafka.log.Cleaner.clean(LogCleaner.scala:501) at kafka.log.LogCleaner$CleanerThread.cleanLog(LogCleaner.scala:359) at kafka.log.LogCleaner$CleanerThread.cleanFilthiestLog(LogCleaner.scala:328) at kafka.log.LogCleaner$CleanerThread.doWork(LogCleaner.scala:307) at kafka.

ROS初始化 sudo rosdep init失败

(1) 安装完ROS后,初始化指令sudo rosdep init失败,提示: sudo: rosdep:command not found 按照以下方式解决: sudo apt install rospack-tools 之后运行 sudo rosdep init 即可 (2)安装完ROS后,初始sudo rosdep init,显示: ERROR: cannot download default sources list from: https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list Website may be down. 如下图: 解决办法: 首先 /etc 目录下打开终端,输入以下命令以更改hosts文件权限 cd /etc sudo chmod a+rw hosts 接着打开hosts文件,在文件末尾添加以下内容,并保存后退出 151.101.84.133 raw.githubusercontent.com 如果还不行,在IPAddress网站中(https://www.ipaddress.com),输入raw.githubusercontent.com查询到真实IP地址,替换 以上的IP

AOP-通用的API日志实例

AOP-通用的API日志实例 序分析方案AOP实现最后 序 最近项目里整了一个通用的API日志。感觉挺不错的,整理一下分享出来。 接口大概时间图如下: 分析 除了【业务处理】,其它的处理都与业务无关。可以考虑把通用的部分抽离出来,【业务处理】单独处理。可以用两种方案去处理。 方案 **1:**使用抽象类。提供一个方法,从【开始】处理到【结束】。【业务处理】设一个抽像方法(无实现)。每个接口都继承抽象类。接口类重写抽业务处理抽象方法。 **2:**使用AOP,开发人员只管【业务处理】。通过AOP的方式在【业务处理】包面包一层日志记录。 对比两种方案觉得AOP的方案更好。 1:AOP的方案,在前期不需要做写日志的扩展考虑,后期调整不需要调整原来的代码。 2:AOP的方案,写的代码更优美,可扩展性更强。 AOP实现 1: 注解,优美的代码当然离不开注解,对注解情有独钟。 package com.ly.mp.swcas.main.config; import java.lang.annotation.*; @Documented @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ApiTag { String apiCode(); //接口编号 String apiName(); //接口描述 } 2:AOP package com.ly.mp.swcas.main.config; import com.google.gson.Gson; import com.ly.mp.common.entities.RestResult; import com.ly.mp.common.utils.BigDecimalUtils; import com.ly.mp.swcas.main.entities.ApiLog; import com.ly.mp.swcas.main.ibiz.IApiLogBiz; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.StopWatch; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.

FPGA AD7606数据采集心得

在最近项目里,需要使用AD7606与FPGA来进行四通道AD数据的采集,配置好AD7606后,开始进行数据采集。测试得出的数据与datasheet中的转换算法得出的数据存在一定的误差,于是慢慢开始排除问题。 首先AD7606的datasheet中算法如图 因为AD7606的数据线为DB[0:15],所以ADC CODE相当于有16位,所以实际得出来的值的范围位0~32767,再根据你的RANGE 脚来选择输入电压的范围,根据图中转换算法得出AD实际测量电压值。 在测试中,发现当输入电压从0~2.5V变化时,AD7606采集到的值经过转换还是挺准的,但是超过2.5V后,比如说实际电压2.6V,但是AD7606采集到的值转换后只有0.1V,实际电压2.7V,测量值为0.2V,以此类推。 以RANGE=±5V为例,按照datasheet的转换算法,转换应该如下图 电压值AD7606理论值2.5V163842.6V170392.7V17695 但是实际测量如下图所示 电压值AD7606测量值2.5V163842.6V6552.7V1311 根据上面两幅图的结果,判断出测量电压超过2.5V以后AD7606测量值与理论值存在较大误差,发现误差为16384,二进制为0100 0000 0000 0000,初步判断为DB14存在问题,于是用示波器首先抓了一下AD7606的DB14,发现会有高低电平跳变,说明AD7606输出DB14没问题。于是怀疑FPGA引脚虚焊,于是用风枪重新吹了下FPGA,然后测试,发现所测数据与理论值相同,问题解决。 第一次发博客,做个纪念,有不足的地方欢迎大家留言指教。

打印一个集合中所有的子集数据

思路: 在数学中,一个集合所有子集个数为2的n次方 以3个字母为例,它的子集个数或组合有8种,非空子集个数有7种。 解题方法: 我们可以用2进制Bit位来标记集合中的某个元素是否被选中,1代表选中,0代表未选中。则字母a、b、c三个字母所组成的集合的所有子集可如下表示: 0 0 0–>空集 0 0 1–>[c] 0 1 0–>[b] 1 0 0–>[a] 0 1 1–>[b,c] 1 0 1–>[a,c] 1 1 0–>[a,b] 1 1 1–>[a,b,c] 此题有26个字母,它所有的组合有2的26次方,计算的结果为67108864种组合,通过下列代码,得到所有组合的具体内容 /** * 有26个字母a-z,找出所有字母的组合,a、b、C、 ab、abc、a~z 都是一个组合(顺序无关) * * @author hf * */ public class Blogs5 { public static void main(String[] args) { int n = 26;// 自定以数组的长度,即多少个字母 int[] arr = new int[n]; diGui(arr, 0, arr.length); // System.out.println(count);//打印结果 } // public static double count = 0;//统计组合数量 /** * 递归全排列 得到数组存放二进制码的所有情况 * * @param arr * @param k * @param end */ public static void diGui(int[] arr, int k, int end) { if (k == end) { // count++;//每一次排列都是一个组合 System.

七大基本排序算法图文详解

文章目录 冒泡排序算法描述 选择排序算法描述 插入排序算法描述 希尔排序算法描述 快速排序算法描述 归并排序算法描述 基数排序(桶排序算法描述思路 冒泡排序 算法描述 1.i从0开始,i与i+1比较,如果i>i+1,那么就互换。 2.i不断增加,直到最后一个元素,一趟比较下来,最大的元素就放到了数组最后。 3.接着开始第二趟,第二趟完后倒数第二位也是第二大的数。 4.以此类推,5个数的数组就需要4趟比较,然后第⼀趟需要⽐较4次,第⼆趟需要⽐较3次,第三趟需要⽐较2次,第四躺需要⽐较1次。 5.我们在比较过程中可能第二趟就排好序了,之后的比较也是多余的,所以我们可以设置一个变量,在比较数据过程里如果发生置换该变量为1,最后每趟结束之前查看该变量,得知该趟是否发生置换,不发生置换就可以结束循环,说明已经排好序了。 代码实现: public class Main { public static void sort(int []arrays){ //装载临时变量 int temp; //记录是否发⽣了置换, 0 表示没有发⽣置换、 1 表示发⽣了置换 int isChange; //外层循环是排序的趟数 for (int i = 0; i < arrays.length - 1; i++) { //每⽐较⼀趟就重新初始化为0 isChange = 0; //内层循环是当前趟数需要⽐较的次数 for (int j = 0; j < arrays.length - i - 1; j++) { //前⼀位与后⼀位与前⼀位⽐较,如果前⼀位⽐后⼀位要⼤,那么交换 if (arrays[j] > arrays[j + 1]) { temp = arrays[j]; arrays[j] = arrays[j + 1]; arrays[j + 1] = temp; //如果进到这⾥⾯了,说明发⽣置换了 isChange = 1; } } //如果⽐较完⼀趟没有发⽣置换,那么说明已经排好序了,不需要再执⾏下去了 if (isChange == 0) { break; } } } public static void main(String[] args) { int [] arr=new int[]{1,44,3,66,7,578,34,88,98}; sort(arr); for (int a:arr){ System.

Pandas根据字段(列)查看具体有哪些重复的数据

1.场景描述 近日,在进行数据整理时,需要根据某些列来找出具体重复的数据有哪些,废话不多说,先把图放上先。 import pandas as pd test_df=pd.DataFrame({'name':['张三','李四','王五','张三','李四','王五','张三'], 'level':[10,3,8,14,2,3,18], 'info':['吵闹','安静','中等','吵闹','安静','安静','吵闹'], 'change_times':[1,2,3,1,2,4,9] }) test_df 数据截图: 需要根据name和info两个字段,找出重复的数据,结果如下: 2.实现方法 2.1 方法1 利用groupby查看重复情况,然后进行merge操作.该方法可以查看具体重复的个数,还可以灵活更改重复次数来筛选数据。 df1=test_df.groupby(["name","info"]).size() col=df1[df1>1].reset_index()[["name","info"]] pd.merge(col,test_df,on=["name","info"]) 输出结果如下: 2.2 方法2 先取出重复的字段,然后生成唯一的name列和info列,再进行merge。 df1=test_df[test_df.duplicated(subset=cols)].drop_duplicates(cols)[cols] pd.merge(df1,test_df,on=cols,how="left") 实现截图: 2.3 方法3 获取重复索引,然后取交集,然后筛选出来。该方法保留了原来的索引,缺点是数据原索引不能有重复。 index1=test_df[test_df[["name","info"]].duplicated(keep="last")].index index2=test_df[test_df[["name","info"]].duplicated(keep="first")].index test_df.loc[index1 | index2,:] 截图如下: 2.4 方法4 先获取所有索引,然后去除不重复的索引,即差集,然后筛选出来。该方法也可以保留原来的索引,缺点也是数据原索引不能有重复。 test_df.loc[set(test_df.index) -set(test_df.drop_duplicates(subset=["name","info"],keep=False).index),:] 结果如下: 2.5 方法5 网友提供的方法,该方法可以保存原始索引,在数据原索引重复的情况下也可以使用。 #写法1 test_df[test_df[["name","info"]].duplicated(keep=False)] #写法2 test_df[test_df.duplicated(subset=["name","info"],keep=False)] 完整代码如下: import pandas as pd test_df=pd.DataFrame({'name':['张三','李四','王五','张三','李四','王五','张三'], 'level':[10,3,8,14,2,3,18], 'info':['吵闹','安静','中等','吵闹','安静','安静','吵闹'], 'change_times':[1,2,3,1,2,4,9] }) test_df #方法1 cols=["name","info"] df1=test_df.groupby(cols).size() col=df1[df1>1].reset_index()[cols] pd.merge(col,test_df,on=cols) #方法2 df1=test_df[test_df.duplicated(subset=cols)].drop_duplicates(cols)[cols] pd.merge(df1,test_df,on=cols,how="left") #方法3 index1=test_df[test_df[cols].

tf中线程与graph读取的关系

def import_graph_fun(pb_model_name): output_graph_def = tf.GraphDef() with open(pb_model_name, "rb") as f: output_graph_def.ParseFromString(f.read()) tf.import_graph_def(output_graph_def, name="") sess = tf.Session() # other code 当我们训练好模型之后,将模型存储成pb格式,然后上面这段代码是读取该文件,一直以来都没有问题,直到有一天当我们需要在一个线程中运行多个模型的时候报错,报错的内容大概就是在预测阶段,不能从graph中找到对应节点。 之前我们都知道在tf框架中:1. 所有的graph都要在session中运行,并且一个session中只能运行一个graph,但是同样的graph可以在不同的session中运行; 2. 如果没有指定graph,框架会为我们生成默认的graph;3. 所有的op操作都会添加到模型的graph上。 其实进行到了这里,基本就能解开上面说的报错的原因:如果我们在一个线程中跑多个graph,我们就必须要有多个session,并且要给每个session绑定它对应的graph,之所以在一个线程中只跑一个图一直没出错是因为就一个图,默认这个图就是绑定了这个session的,不存在歧义。 其实我当时在写这里的时候有个疑问:这条语句graph_def.ParseFromString(f.read())是从pb文件中将序列化的graph解析出来,然后根据这条语句tf.import_graph_def(graph_def, name=“”)将这个graph_def导入,那么问题是这个导入是导入到了哪里?该接口并没有将graph return回来,它去了哪里,我们怎么拿到它?答案是:该接口直接将import出来的graph中所有的op添加到了它对应的上下文的graph中,想要获取它,就要先构造一个上下文环境,然后才能拿到这个graph,具体代码为: def import_graph_fun(pb_model_name): output_graph_def = tf.GraphDef() with open(pb_model_name, "rb") as f: output_graph_def.ParseFromString(f.read()) # 注意:这条语句非常重要,通过接口as_default()构建了一个上下文环境,此时tf.import_graph_def就是将op添加到了这个环境所对应的graph中,也就是g_ with tf.Graph().as_default() as g_: tf.import_graph_def(output_graph_def, name="") # 这里指定一下这个sess1绑定的是g_ sess1 = tf.Session(graph=g_) # other code 如此,就可以work了。 总结:graph是跟线程相关的。

一文搞定实现存储过程的解法(入门)

摘要:全网【三桥君】 网上资料一大堆,但是基本都是照本宣科。如果有会的人讲解或者会了以后去看,那么能够理解。但是对于初学者来说,很费解,甚至完全没明白什么意思,即使看了之后也实践不了。我们初学时,最主要的是入门!入门!入门!能让我们理解这个知识点和能够操作定义存储过程,才是最重要的,哪怕是定义最基础的题目。针对这个现象,我用自己总结的最简单明了的方式来去解释这个知识点,我不按套路出牌,争取同学们一看就明白了。 一、什么是存储过程 1、存储过程的概念看这篇:第9章 数据库完整性与安全—2 2、存储过程的在软件中的解释看这篇:sql server 创建存储过程 存储过程在SQL Server软件中可以查看到: 二、如何编写存储过程的代码 我总结的定义存储过程最基础的代码方式,这是存储过程代码的框架。 CREATE PROC [存储表名] @[虚拟列名] [数据类型], @[虚拟列名] [数据类型] OUTPUT AS [T-SQL 语句] (提示:中括号“[ ]”这个代码位置该填什么内容,具体内容括号里说明了。) 我把这框架分为3部分,只要填满了3部分,就能实现存储过程的功能! 已实现存储过程代码样式: --定义存储过程proCourseAvg CREATE PROC proCourseAvg @CouName VARCHAR(20), @CouNum INT OUTPUT, @AVG INT OUTPUT AS SELECT @CouNum=COUNT(xsgl_course.course_no),@AVG=AVG(score_score) FROM xsgl_course,xsgl_score WHERE xsgl_course.course_no=xsgl_score.course_no AND xsgl_course.course_name=@CouName GROUP BY xsgl_course.course_no 这样的存储过程代码框架,你看明白了吗? 那么,关于这存储过程的代码的编写,有几个地方还是要强调下。 1、定义存储过程时,先把CREATE PROC [存储表名] ...AS这个框架写好。 2、虚拟表名题目没要求的话可以自己定义,不影响的。 3、数据类型跟创建基本表一样,用VARCHAR、INT等。 4、为什么有的数据类型后面有OUTPUT,有的没有? 有OUTPUT,意思是题目要求需要输出什么数据,然后我们先定义一个虚拟列名来当作它,到时要用它来输出,所以要OUTPUT。 没有OUTPUT,意思是题目要求需要输入什么数据,然后我们先定义一个虚拟列名来当作它,到时要用它来输入,但是不需要输出,所以不用OUTPUT。 通常来说,一个输入,多个输出。 5、第二部分的逗号需要注意下,当有两行时,第一行后面加逗号即可,以此类推。 6、第三部分的SQL语句查询怎么写? 之前SQL语句查询规则怎么写,这里就怎么写,逻辑规则一样的。区别就是,要跟第二部分的虚拟列名相结合。 经过这里,相信大家对数据库的存储过程是什么鬼东西能够有了简单的理解。那么,该如何实现存储过程呢? 三、如何实现存储过程 (这里我用一个完整的例题来分析。)

Golang JSON-反序列化map,切片(slice),结构体(struct)

package main import ( "encoding/json" "fmt" ) /*{"addr":"beijing","age":123,"name":"typ"} {"name":"qqqq","age":12,"hobbit":"ttttt"} [{"addr":"beijing111","age":1231,"name":"typ111"},{"addr":"beijing222","age":1222,"name":"typ222"}]*/ type student struct { //tagjson序列化后是小写 Name string `json:"name"` Age int `json:"age"` Hobbit string `json:"hobbit"` } func unjsonStruct(){ var stu student fmt.Println("unjson before: ",stu) var str = "{\"name\":\"qqqq\",\"age\":12,\"hobbit\":\"ttttt\"}" err := json.Unmarshal([]byte(str), &stu) if err != nil { fmt.Println("unjson 失败") } fmt.Println("unjson after: ",stu) } func unjsonMap(){ testMap := make(map[string]interface{}) fmt.Println("unjson before: ",testMap) var str = "{\"addr\":\"beijing\",\"age\":123,\"name\":\"typ\"}" err := json.Unmarshal([]byte(str), &testMap) if err !

Golang JSON-序列化map,切片(slice),结构体(struct)

package main import ( "encoding/json" "fmt" ) func mapJson() { testMap := make(map[string]interface{}) testMap["name"] = "typ" testMap["age"] = 123 testMap["addr"] = "beijing" json01, err := json.Marshal(testMap) if err != nil { fmt.Println("json失败") } fmt.Println(string(json01)) } type stu struct { //tagjson序列化后是小写 Name string `json:"name"` Age int `json:"age"` Hobbit string `json:"hobbit"` } func structJson(){ stu := stu{ Name: "qqqq", Age: 12, Hobbit: "ttttt", } json01, err := json.Marshal(stu) if err != nil { fmt.

创建一个PHP登录表单

当我们要存储有关我们网站用户的信息时,用户登录和注册系统非常有用。 这适用于从可能存储课程进度和标记的教育网站到将存储有关客户过去购买信息的电子商务网站的所有内容。 创建登录和注册表格 我们的第一步将是创建登录表单和注册表单。 表格实际上将非常简单。 注册表仅要求提供用户名,电子邮件和密码。 用户名和电子邮件对于每个注册的人都是唯一的。 如果有人尝试使用相同的电子邮件地址创建两个帐户,我们将向他们显示一条错误消息,让他们知道该电子邮件已在使用中。 编写注册表 这是用于创建注册表HTML。 您必须将其放入名为register.php的文件中。 <form method="post" action="" name="signup-form"> <div class="form-element"> <label>Username</label> <input type="text" name="username" pattern="[a-zA-Z0-9]+" required /> </div> <div class="form-element"> <label>Email</label> <input type="email" name="email" required /> </div> <div class="form-element"> <label>Password</label> <input type="password" name="password" required /> </div> <button type="submit" name="register" value="register">Register</button> </form> 表单是非常基本的,但是我们确实使用HTML5来进行一些非常基本的输入验证。 例如,当用户输入的电子邮件地址格式不正确时,使用type="email"会警告用户。 类似地,在用户名上使用pattern属性将确保用户名仅包含字母数字字符。 编码登录表单 这是登录表单HTML。 您可以将其放在名为login.php的文件中。 <form method="post" action="" name="signin-form"> <div class="form-element"> <label>Username</label> <input type="text" name="username" pattern="[a-zA-Z0-9]+" required /> </div> <div class="

汇编语言8086CPU之寄存器总结

寄存器是什么呢? 其实很简单,寄存器就是个存储信息的单元或者说是器件又或者说是容器而已,就比如内存也是一个存储介质或者说是存储单元而已,其实寄存器从理解上来说和内存差不多,只不过寄存器(这里讨论的寄存器都是 CPU 中的寄存器,不包括外设上的寄存器)位于 CPU 内部,而内存位于 CPU 外部,而且,寄存器比内存可是珍贵得多啊,就拿内存和硬盘来比,肯定是内存在使用上珍贵得多,是 PC 中的稀有资源,而寄存器是 CPU 中的稀有资源,内存和寄存器相比就像硬盘和内存相比一样 。 而对于一个汇编程序员来说,CPU 中主要可以使用的也就是寄存器而已,汇编程序员可以使用指令来读写 CPU 中的寄存器,从而可以实现对于 CPU 的控制,当然,不同的 CPU ,寄存器的个数和结构都是不一样的。比如 8086 CPU 中,寄存器的个数也就 14 个而已,并且 8086 CPU 中所有的寄存器的结构为 16 位,即一个寄存器中可以存放下 2B 即 2 个字节。 8086 CPU 中寄存器总共为 14 个,且均为 16 位 。 即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES 共 14 个。 而这 14 个寄存器按照一定方式又分为了通用寄存器,控制寄存器和段寄存器。 寄存器种类 通用寄存器: AX,BX,CX,DX 称作为数据寄存器: AX (Accumulator):累加寄存器,也称之为累加器; BX (Base):基地址寄存器; CX (Count):计数器寄存器; DX (Data):数据寄存器; SP 和 BP 又称作为指针寄存器: SP (Stack Pointer):堆栈指针寄存器;

java读取配置文件路径问题

java打印classpath路径 System.out.println(System.getProperty("java.class.path"));//系统的classpaht路径 System.out.println(System.getProperty("user.dir"));//用户的当前路径 一.文件读取 1.利用java.util自带的Properties类读取 Properties类的load方法提供了两种读取文件的方式 (1)reader作为参数,以字符流方式读取 Properties properties = new Properties(); try { properties.load(new InputStreamReader(new FileInputStream(fileName),"utf-8")); } catch (IOException e) { e.printStackTrace(); } String url = properties.getProperty("url") 在load参数里面可以用任意的io装饰类去装饰文件输入流,只要最终装饰成字符流即可;InputStreamReader方法有编码参数,若读取含有中文的文件,文本文件默认编码为ANSI(在windows中就是GBK),所以将编码参数设置为GBK;或者我的idea系统设置为utf-8编码,所以只要先将文件转为utf-8编码即可 (2)inputStream作为参数,以字节流方式读取 Properties properties = new Properties(); try { properties.load(new FileInputStream(fileName)); } catch (IOException e) { e.printStackTrace(); } String url = properties.getProperty("url") 同理,load方法参数可以添加任意的装饰组件 2.利用java.util自带的ResourceBundle类读取 ResourceBundle bundle = ResourceBundle.getBundle("config"); String url = bundle.getString("url"); 该方法默认读取的是resources文件夹下的以.properties为后缀的文件,代码中的例子即为config.properties 二.文件路径 有几种方式 1.绝对路径,不赘述 2.相对路径 (1)利用System.getProperty方法 System.getProperty("user.dir")+"/src/main/resources/config.properties" System.getProperty("user.dir")会定位到项目的根目录,可以得到该工程项目所有文件的相关路径及环境配置信息 (2)利用类装载器

load_weight

keras中加载权重 有一个参数是 byname=true( or false) 如果是true那么加载会按照预先训练的的名字进行加载,也就是说在先前训练模型时必须要定义名字。 如果是false那么直接按照拓扑结构进行加载,还没有试过但是如果改变了模型可能会加载出错。 、 参考:https://www.jianshu.com/p/f79f96cb6f86

jsp 100以内偶数 5位换行 表格输出

<%@ page contentType="text/html; charset=GBK" %> <html> <head> <title> Text </title> </head> <body bgcolor="#ffffff"> <table border="1"> <% int i,j,k=0; %> <tr> <% for (i = 2; i <100; i=i+2) { %> <td><%=i %></td> <% k++; if(k%5==0) { %> <tr> <% } } %> </tr> </table> </body> </html>

解除百度文库复制限制

很多人想下载一些学习资料好不容易找到资料,发现在百度文库上想要复制,而百度文库复制需要充值VIP 对于这种问题,今天我给大家带来一个解除百度文库复制限制的方法,其实这个方法非常简单,而且不用下载任何软件。打开你的浏览器按F12或右键打开审查元素,点击Console,粘贴以下代码然后回车。 $('div.ie-fix').text 执行之后就可以进行复制了!不过这方法仅限于文字类的文档。如果想要下载有图片的,推荐使用冰点下载,下载为PDF格式,之后可以进行PDF转word文档,也是可以的!

计算机网络 华东理工大学 第3章测试

华东理工大学mooc通关攻略第1章测试第2章测试第3章测试第4章测试第5章测试(上)第5章测试(下)第6章测试第7章测试2020期末考试(慎重,答案不确定)推荐一位大哥的专栏,有我的部分题目的解析 1.系统采用带位填充的帧界标记法,收方从网络接收到一个字符串是 11101111100。那么,发送方发送的原始字符串是什么? 编号选项A111111110B1110111110C111011111000D11101111100 2.下列关于停-等ARQ协议,正确的描述是? 编号选项A帧和 ACKs没有必要携带序列号。B仅当当前帧的 ACK 落入 *sent *(发送窗口),发送方发送下一帧。C仅当当前帧的 ACK 落入 * received *(接收窗口),发送方发送下一帧。D超时可防止丢帧和丢失ACKs 3.若数据链路层的发送窗口尺寸W=4,在发送3号帧、并收到2号帧的确认帧后,发送方还可以连续发送多少个帧?(采用累计确认) 编号选项A4B3C1D2 4.在选择性重传协议中,当帧序号为4比特,并且发送窗口和接收窗口尺寸相同时,发送窗口的最大尺寸是多少? 编号选项A15B4C6D8 5.数据链路层采用了回退n帧协议(GBN),发送方已经发送了编号为0~7的帧,当计时器超时时,若发送方只收到0、2、3号帧的确认,则发送方需要重发多少帧? 编号选项A2B4C7D3 6.采用比特填充的比特标记法,对0111 1100 0111 1110 组帧后,对应的比特串是多少? 编号选项A01111100 00111110 10B01111100 01111110 01111101C01111100 01111101 01111110D01111100 01111101 0 7.数据链路层采用选择重传协议(SR)传输数据,发送方已发送了0~3号数据帧,现已收到1号帧的确认,而0、2号帧依次超时,则此时需要重传的帧数是多少? 编号选项A2B1C4D3 8.系统采用纠1位错的海明码,现在要传输的数据是7位,问需要的冗余位至少是几位? 编号选项A5B3C2D4 9.系统采用纠1位错的海明码,待传输的数据是:10101111,校验集合采用偶校验,编码后的码字是下面哪一个? 编号选项A101001011111B101001001111C101101001111D011101011111 10.主机甲和主机乙之间使用后退N帧协议(GBN)传输数据,甲的发送窗口尺寸为1000,数据帧长为1000字节,信道为100Mbps,乙每收到一个数据帧立即利用一个短帧(忽略其传输延迟)进行确认。若甲乙之间的单向传播延迟是50ms,则甲可以达到的最大平均传输速率约是哪一个? 编号选项A80MbpsB10MnpsC100MbpsD20Mbps 11.从滑动窗口的角度来看,当发送窗口SW=1,接收窗口RW=1的时候,相当于下面的哪种工作方式? 编号选项A选择性重传B回退n帧C连续工作D停-等工作 12.捎带确认的主要作用是:将确认嵌入到外发的数据帧中,而不需要单独发帧,提高了信道的利用率。 编号选项ATBF 13.点到点协议PPP的两种认证方式中,PAP不仅简单,而且也解决了拒绝服务攻击和明文传输的问题。 编号选项AFBT @Power By Exercises-Manager

DOM节点详解

DOM节点之Node详解 定义 DOM(文档对象模型) 是针对HTML和XML文档的一个API(应用程序编程接口) DOM描绘的是一个层次化的节点树,允许开发人员添加,修改和移除页面的某一部分 Node类型 属性:1、nodeType , 表示节点类型 规则: 1 -->Element类型 3 -->Text类型 8 -->Comment类型 9 -->Document类型 2、 childNodes ,表示子节点集合,可以使用slice方法将NodeList转换为数组 var arr = Array.prototype.slice.call(nodes,0);8 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dom核心概念</title> </head> <body> <div class="nav"> <ul class="msg"> <li>s</li> <li>f</li> <li>s</li> <li>c</li> <li>g</li> </ul> </div> <script> /* DOM(文档对象模型) 是针对HTML和XML文档的一个API(应用程序编程接口) DOM描绘的是一个层次化的节点树,允许开发人员添加,修改和移除页面的某一部分 */ let oNav=document.querySelector(".nav"); let oMsg=document.querySelector(".msg"); let oLi=document.querySelectorAll("li");//nodeList 只会包含元素 用oLi[0].childNodes还换包含换行符,数组下标就会变。 </script> </body> </html> window.onload = function(){ console.

产品经理之产品类题目

文章目录 一、设计类目1.1 题目举例1.2 题目拆解1)审题2)用户需求3)产品设计4)结构化表达 二、改进类题目2.1 题目举例2.2 题目拆解1)、用户维度2)、需求分析3)、产品设计4)、数据衡量 三、喜欢类题目3.1 题目举例3.2 问题拆解1)选择一款熟悉且能引起对方兴趣的产品2)对产品的分析能够到位3)展现自己对产品的热情和兴趣度 3.3 本节总结 四、分析类题目:4.1 题目举例4.2题目拆解:1)通过数据对比去看:2)从技术维度:3)、从市场维度看:4)细拆指标去看 五、行业类题目5.1 题目举例5.2 题目拆解1)市场占有率2)产品体验3)品类协作4)资源能力 产品类题目一般分为5种类型: 1、设计类:比如设计一款老人或者儿童专用的智能手机;2、改进类:说说微信的三个优化点;3、喜欢类:比如说说你最喜欢的一个APP?说说打动你的点。4、分析类:比如百度搜索下降20%,分析其原因。或者淘宝某一垂直类商品,如服饰,当季的销量下降了20%,试分析其原因。5、行业类:美团和饿了么的区别在哪里?如果你是美团外卖的产品经理,怎么来实现更好的产品突破。行业类的问题,需要你熟知面试公司的产品,并查看新的行业热点和行业竞品情况,这些要提前了解。 一、设计类目 1.1 题目举例 设计一款儿童电话手表。 这类题目算是主观类题目,在笔试和面试都有可能出现,在笔试出翔的可能性较高。 1.2 题目拆解 1)审题 看题目所表达的要点,你要能真正了解题目背后的含义,如果遇到模糊不清的地方,可以跟面试官询问,比如说童的年龄定义是什么,是指6到12岁年龄还是其他年龄段的小朋友。但刚才的题目其实并没有过多的歧义,你就按着题目的逻辑往下解答就行。 2)用户需求 你要判断所设计的产品针对的用户,之前也跟大家提到过,用户跟客户是有差异的。如果按儿童电话手表来看,那用户其实是小朋友,而最基础的诉求点能够有效通话(比如语音、视频等),也可以植入娱乐和社交性的版块,比如音乐、故事等。小朋友比较关注的点是更酷更好玩,视觉更时尚,这些也可以结合性别来做设置与展现。还有就是小朋友可能比较爱玩,手表本身的防水、防摔等功能也是必须的。客户是他/她的父母,所谓的付费客户。作为家长,除刚才提到小朋友需求外,会更加关心安全性和可靠性,比如通过电话手表可以查看小孩所处的方位,方便快捷地报警等功能。 3)产品设计 结合.上面的思考和分析,你做产品设计的时候,就会考虑到不同用户群体的功能差异,将所有的功能按优先级来排列。首先最为核心的就是保障通讯功能,这块功能需要支持语音、文本、视频等功能,且要保障比较长的使用时长,这就需要较强的待机能力和较短的充电时间。此外,娱乐性的需求比如前面提到故事会、音乐、自动问答等功能可作为辅助性功能,强化产品的卖点。还有提到的安全的需求,比如GPS定位、-键报警等,对家长来说非常重要,因为家长希望小朋友尽可能不要远离自己的视线,遇到问题能第一时间知道。至于锦上添花的,外表跟形式上更加贴近小朋友功能,比如说跟IP合作,小猪佩奇、蜘蛛侠型等风格的电话手表可以放到后面。 4)结构化表达 按照前面的信息,你才能够列出回答的要点,从用户、场景、竞品、功能等角度出发,回答此类的问题。这些上面或多或少都有提到,大家做下汇总就行。 二、改进类题目 2.1 题目举例 改进类:比如列举微信的三个优化点。 这类问题一般列举的都是你所熟知的产品或者面试官所在公司或所在业务部门的产品,这块大家平常要多加留意和积累。这边说下思路。 2.2 题目拆解 1)、用户维度 你要看到所在产品用户群体的属性和特征,或者说有没有比较好的拓展空间和细分维度。 比如微信用户量是11亿左右,用户规模其实非常大,已经覆盖到国内外用户,且跨越到各个年龄段。如果按细分维度去切,你可能针对某一个特定的群体,比如说海外用户或者说国内50岁以上的老年用户,若有这些用户的比例及发展趋势等定性数据,则可以辅助判断是否需要投入资源来优化这部分用户的需求,如果没有,则结合生活场景,看下这些用户在微信.上是否有需求,比如老爸老妈视力不好,对互联网的操作不熟悉,那是否可单独出老年版本功能的设置,强化字体和简化操作。 2)、需求分析 假设你瞄准老年用户群体,那这些用户会有什么样的痛点或者需求让你帮他去解决的。 回想到你生活中,老年人的日常生活,他们经常会聚集一起跳广场舞,那微信是否能够较好满足老年用户这块的需求。比如需要微信在召集群友时,信息通知机制做得更加完善,允许群组以模板消息的形式发送给各个群友,并且群里面公告信息可以置顶,通过这样的方式能够快速通知到各个群友。此外,上面提到的老年人视力不好,能否有自动将公告或者信息转成语音的功能,方便老年人查看信息。上面是从细分用户的场景出发,延伸出新的需求。 还可以从竞品维度来做,比如微信更多的是熟人社交,但介于陌生人和熟人之间的群体,难以满足他们交往或认识的需求,比如以兴趣组维度存在的产品。那这样的产品,在微信里面能否有一些好的体验和更好的优化,比如微信群以兴趣组来建立,但聊天的内容偏实时的,都是短时交流的刷屏内容,但这些内容是没办法沉淀的。那能不能群主自己或授权他人做内容的整理工作,并把这些精要的内容在群里面做展现。 3)、产品设计 通过这样的一些维度分析后,你可以开始列出产品设计的相关要点。 比如说三个优化点分别是,针对老年用户群体,微信的信息通知触达更加方便、允许信息以语音的形式在群里和模板消息里面做推送。此外,微信群的信息缺乏沉淀机制,适合即时的聊天,但里面以兴趣等维度建立的社群,缺乏有效的内容沉淀手段,这块微信可以设置群内容加星和置顶功能等等。这些都是你通过自己的思索得来的要点,不过要记住的是要能够自圆其说,有理有据就行。 4)、数据衡量 产品优化后,什么样的数据能够证明效果是0K的? 比如大家看微信里面增加搜索功能,那以什么样的数据来量化效果。 除搜索的UV和PV外,搜索后的结果列表如何评判? 比如现在的微信搜索是文本形式,并不是图文内容的展现,如果你要修改搜索的展现结果样式,评判的标准除看结果页的点击率外,还可以看下用户的主观反馈等来说明。这些要点跟我们刚才提到设计类产品问题是非常类似的,设计类产品更多是从0~1的阶段,而改进类的产品更多是已有功能或用户群的拓展,更多聚焦于现有功能点的优化和提升或者拓宽新的用户群。 三、喜欢类题目 3.1 题目举例 喜欢类问题的解答,这边有3个要点给到大家: . 3.2 问题拆解 1)选择一款熟悉且能引起对方兴趣的产品 你对自己喜欢的APP或产品要有一定的熟悉度,最好是你自己经常使用的产品,但原则上不要说非常大众化的产品,比如微信和淘宝等。最好是某种程度上是比较知名,但是又不是如微信都普遍知道的产品,比如印象笔记、曹操专车等。 另外如果跟公司的业务类似或者相匹配的产品,则是最好的,这样跟面试官有共同的话题。比如面试官是做社交的,那你这边提到职场社交软件脉脉或者陌生人社交陌陌等产品,那面试官肯定会想跟你深入聊一聊。还有就是不要拿出一个非常小众的,或者刚出来不久的(除非比较热火的),因为面试官没有听说过或者使用过,那没法形成共同的话题。 2)对产品的分析能够到位 比如大的角度可以从用户、竞品、收入、发展空间等来说明,小的角度从单一模块或功能入手,谈产品的体验。比如刚才提到的脉脉,我们说几个小点: 1)脉脉定位于职场上的社交软件,希望通过脉脉链接你职场内外的人脉。那对于这些用户来说,身份的认证就极为关键(因为是实名机制),因为大家都希望接触到公司真正的同事。通过实名的认证(包括你在公司的title), 用户就不会担心你身份不明朗的问题,这样的机制能够大大降低信任的i门槛,提升沟通效率。2)脉脉需要靠比较优质的内容来吸引用户传播和互动。脉脉里面的信息有专栏、观点,甚至匿名的职场信息,这些信息针对不同用户在不同场景的需求。比如专栏定位于长文本形式,更多是邀请达人或专家等来发布比较高质量的内容。而观点就是针对当下比较流行的热点,做下相关的讨论和传播。职言是公司上的匿名信息,虽然有部分吐槽和负面内容,但里面曝光出公司比较真实的一面,整个互动率比较高。3)再说社交。一是通过多个维度来拓展你的人脉情况,细分维度有公司、校友、老乡等等,可以吸引对方互相加为好友,但每天有数量限制,防止对用户的过度骚扰,二是有比较好的主题或者轻社区模式,就是希望能聚集兴趣相同的职场人士,加强大家的互动性。 3)展现自己对产品的热情和兴趣度 通过以上的分析,可以看得到你使用脉脉产品是比较深入的,有自己的想法和判断。对于面试官而言,可许会继续深入追问下去?

Android Studio基于zxing的第三方库zxing-android-embedded实现生成二维码与扫描二维码

为了在APP中添加扫码功能,需要用到相关的开源库,最常见的是zxing库和zbar库,zbar很多年前就已经不再维护了,xing还在维护,但是使用起来比较复杂。为了使用起来更方便,于是选择基于zxing集成的第三方库zxing-android-embedded。主要参考了第三方ZXing库zxing-android-embedded使用及自定义与安卓Zxing的简单使用-(生成二维码与扫一扫)这两篇博客,以及android和该库的官方文档。 步骤 配置依赖生成二维码步骤简单实践 扫描二维码自定义扫描二维码先给出结果自定义部分:横屏与竖屏(扫码)设置自定义部分:扫码框大小的设置自定义部分:其他(未实践) 分析与总结(很啰嗦) 配置依赖 在app/build.gradle中添加如下 dependencies { ...... implementation 'com.journeyapps:zxing-android-embedded:3.6.0' ...... } 点击如下图所示的 Sync Now,完成配置依赖。 生成二维码 步骤 生成二维码步骤如下: 申明一个QRCodeWriter对象QRCodeWriter类文档QRCodeWriter的encode方法(提供长、宽等参数,其余参数不太理解),返回一个BitMatrix对象。循环遍历BitMatrix对象,将其存储到矩阵中。(在上面的文档中可以看到Bitmatrix的get(i,j)方法中,i: 列,j:行)。为了将图像能够显示出来,需要转换成Bitmap对象, 调用Bitmap的createBitmap方法,将其转化成Bitmap对象。Bitmap类文档通过ImageView控件的setImageBitmap方法,显示二维码。 简单实践 在activity_main.xml添加布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/edit_input_string" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入需要转换的字符串"/> <Button android:id="@+id/button_generate_QRcode" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="生成二维码"/> <ImageView android:id="@+id/imageview_QRcode" android:layout_width="match_parent" android:layout_height="250dp" /> </LinearLayout> 效果如下: 在活动MainActivity.java中添加逻辑,其中generate_QRCode_Bitmap方法对应上述的步骤。 package com.example.myqrtest; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.graphics.Bitmap; import android.media.Image; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.

Redis基本原理

文章目录 一、简介二、Redis优缺点三、Redis缓存为什么要用 Redis 缓存?为什么要用 Redis 而不用 map/guava 做缓存?Redis性能高的原因redis的VM机制 三、Redis数据类型四、Redis的应用场景五、持久化什么是Redis持久化?Redis 的持久化机制是什么?各自的优缺点?Redis持久化数据和缓存怎么做扩容? 六、Redis的过期键的删除策略过期的数据怎么处理? 七、Redis的内存淘汰策略Redis主要消耗什么物理资源?Redis的内存用完了会发生什么?Redis如何做内存优化? 八、线程模型Redis线程模型 九、事务什么是事务?Redis事务的概念事务管理(ACID)概述Redis事务支持隔离性吗Redis事务保证原子性吗,支持回滚吗Redis事务其他实现 十、集群方案 一、简介 Redis(Remote Dictionary Server):C 语言编写,高性能非关系型(NoSQL)的键值对数据库。 键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合;数据存在内存中,读写速度快;应用于缓存、分布式锁、事务 、持久化,支持LUA脚本、LRU驱动事件、多种集群方案。 二、Redis优缺点 优点: 1)读写快; 2)支持数据持久化(AOF和RDB); 3)支持事务,Redis操作是原子性的,同时还支持对几个操作合并后的原子性执行; 4)数据结构丰富,除了支持string类型的value外还支持hash、set、zset、list等数据结构; 5)支持主从复制,主机会自动将数据同步到从机,可以进行读写分离; 缺点: 1)数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。 2)Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。 3)主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。 4)Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。 三、Redis缓存 为什么要用 Redis 缓存? 主要从“高性能”和“高并发”这两点来看待这个问题。 高性能: 操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据。高并发: 直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。 为什么要用 Redis 而不用 map/guava 做缓存? 缓存分为本地缓存和分布式缓存。 以 Java 为例,使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 jvm 的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。 使用 redis 或 memcached 之类的称为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性。缺点是需要保持 redis 或 memcached服务的高可用,整个程序架构上较为复杂。 Redis性能高的原因 1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1);

基本Spring Cloud的微服务架构搭建及应用(一)

1、Spring Cloud介绍 Spring Cloud家族有许多成员: Spring Cloud Config - 配置管理工具包,集中化管理集群配置,目前支持本地存储、Git 以及 Subversion; Spring Cloud Bus - 事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与 Spring Cloud Config 联合实现热部署; Spring Cloud Sleuth - 日志收集工具包,封装了 Dapper 和 log-based 追踪以及 Zipkin 和 HTrace 操作,为 SpringCloud 应用实现了一种分布式追踪解决方案; Spring Cloud Stream - Spring 数据流操作开发包,封装了与 Redis、Rabbit、Kafka 等发送接收消息; Spring Cloud OAuth2 - 基于 Spring Security 和 OAuth2 的安全工具包,为你的应用程序添加安全控制; Eureka,服务注册和发现,它提供了一个服务注册中心、服务发现的客户端,还有一个方便的查看所有注册的服务的界面; Zuul,网关,所有的客户端请求通过这个网关访问后台的服务; Ribbon,即负载均衡; Feign,服务客户端,服务之间如果需要相互访问,可以使用RestTemplate,也可以使用Feign客户端访问,它默认会使用Ribbon来实现负载均衡; Hystrix,监控和断路器; ...... 在当前文章中不会对这些组件的单个使用作很详细的介绍,这些资料网上都可以找到,读者可以根据自己的需要去网上查询,这里只是演示如何将其中一些常用的组件组合起来,搭建起一个可以运行的Spring Cloud应用架构。 Spring Cloud的有一些组件并不是都是完美的,有一些国产组件比它做得更好、更符合国人的使用习惯,如阿里用于微服务治理的Sentinel比Hystrix更好用(基于Sentinel的高可用限流系统设计及实现)、推程的Apollo比Spring Cloud Config更适合作配置中心、Skywalking的无侵入式调用链监控比Spring Cloud Sleuth更灵活更方便集成等等,可以根据自己的实际情况选择最合适的。 2、示例架构介绍 当前的示例应用中,不会把所有的组件都用完,只是拣选一些常用几个组件作为示例演示,其中Zuul with Ribbon作为网关、Eureka作为注册与发现中心、Feign为远程调用组件、spring-cloud-config-serverw作为配置中心并以Git作为配置存储中心,并且编写了两个基于Spring Boot的示例应用application-1和application-2用于演示,以下是本次示例的架构图:

基于Matlab的MIMO通信系统仿真_Simulink实现

瑞利衰落信道中使用空时分组码的BPSK调制的BER 1、2发1收 参数设置: 双极性信号元+1和-1,每符号含1bit; 采样时间=符号时间=1s; 采用基于数据帧的仿真计算模式,每帧中有2个采样值; 仿真时间=出现100个误码后停止仿真; 随机整数种子=22; Jakes衰落模型中每个信道上的多普勒频移=0.01Hz; 输人信号功率=2W; Alamouti码:两根发送天线,一根接收天线(分集阶= 2); 平均信道信噪比= 18dB; 仿真得出的误码率统计BER =0. 00017. 2、2发2收 参数设置: 双极性信号= +1和-1,每符号含1bit; 采样时间=符号时间=0.001s; 采用基于数据帧的仿真计算模式,每帧中有2个采样值; 仿真时间=出现100个误码后停止仿真; 随机整数种子=22; Jakes衰落模型中每个信道上的多普勒频移=3Hz; 输人信号功率=2W; Alamouti码:两根发送天线,两根接收天线(分集阶=4); 平均信道信噪比= 15dB; 仿真得出的误码率统计BER =2x10e-5.

深入理解 Lua 虚拟机

作者:nicochen,腾讯 IEG 游戏开发工程师 本文从一个简单示例入手,详细讲解 Lua 字节码文件的存储结构及各字段含义,进而引出 Lua 虚拟机指令集和运行时的核心数据结构 Lua State,最后解释 Lua 虚拟机的 47 条指令如何在 Lua State 上运作的。 为了达到较高的执行效率,lua 代码并不是直接被 Lua 解释器解释执行,而是会先编译为字节码,然后再交给 lua 虚拟机去执行。lua 代码称为 chunk,编译成的字节码则称为二进制 chunk(Binary chunk)。lua.exe、wlua.exe 解释器可直接执行 lua 代码(解释器内部会先将其编译成字节码),也可执行使用 luac.exe 将 lua 代码预编译(Precompiled)为字节码。使用预编译的字节码并不会加快脚本执行的速度,但可以加快脚本加载的速度,并在一定程度上保护源代码。luac.exe 可作为编译器,把 lua 代码编译成字节码,同时可作为反编译器,分析字节码的内容。 luac.exe -v // 显示luac的版本号 luac.exe Hello.lua // 在当前目录下,编译得到Hello.lua的二进制chunk文件luac.out(默认含调试符号) luac.exe -o Hello.out Hello1.lua Hello2.lua // 在当前目录下,编译得到Hello1.lua和Hello2.lua的二进制chunk文件Hello.out(默认含调试符号) luac.exe -s -o d:\\Hello.out Hello.lua // 编译得到Hello.lua的二进制chunk文件d:\\Hello.out(去掉调试符号) luac.exe -p Hello1.lua Hello2.lua // 对Hello1.lua和Hello2.lua只进行语法检测(注:只会检查语法规则,不会检查变量、函数等是否定义和实现,函数参数返回值是否合法) lua 编译器以函数为单位对源代码进行编译,每个函数会被编译成一个称之为原型(Prototype)的结构,原型主要包含 6 部分内容:函数基本信息(basic info,含参数数量、局部变量数量等信息)、字节码(bytecodes)、常量(constants)表、upvalue(闭包捕获的非局部变量)表、调试信息(debug info)、子函数原型列表(sub functions)。

相机靶面尺寸详解+工业相机选型

视觉项目管理过程中,发现单纯的算法知识是无法让项目落地的。所以开始了视觉硬件的学习,但是一直不明白的是“靶面尺寸”相关的内容,即使查了很多博客,甚至听了很多相机生产商的报告,还是没弄明白。今天终于搞清楚了,在此分享一下,希望能帮到跟我一样困惑的同行。 注: 1.相机的实际靶面尺寸=像元尺寸*相机分辨率 2.镜头的FOV计算,一般镜头用上述第一个公式;远心镜头用上述第二个公式 3.镜头参数中的放大倍率即计算公式中的光学倍率 4.正面打光,有效像素为1个像素;背面打光,有效像素为0.5个像素 ,即像素精度=FOV/分辨率*有效像素个数 当然关于相机的选型,上述步骤,只是个大体流程。具体项目,应根据具体情况,重新组合选型步骤。不过过程中会用到的数据计算方法,本文都已提及。希望可以帮到各位。 在此,分享两个写的非常好的博客给各位,也非常感谢这位博主的博客,让我受益匪浅。 工业相机镜头焦距、工作距离、视野等选型的计算 https://mp.weixin.qq.com/s/K1TtIH8EJcZxHVRrsIN4qQ

手机设置代理后无法上网

手机设置代理后无法上网,手机不通过Charles代理工具可以正常上网, 但一旦设代理就没法上网了(相关配置都是正确的), 后来发现是防火墙的问题;发射出来的wifi是公用网络, 会被防火墙给阻断通信, 这时可以选择“公用网络设置”--》“关闭Windows防火墙”, 之后再次Charles截包(使用代理),发现可以正常通信了。

ubuntu安装opencv遇到的问题

自己记录的问题及解决方法 完整的安装方法参考 [添加链接描述](https://www.jianshu.com/p/f646448da265) [添加链接描述](https://blog.csdn.net/qq_27278957/article/details/100674085) 问题1:Ubuntu 或者 Debian 系统显示窗口的时候遇到了这个问题 error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function ‘cvNamedWindow sudo apt-get install install libgtk2.0-dev pkg-config 安装成功后,重新编译opencv源码 问题2Package opencv was not found in the pkg-config search path. 查看opencv版本的指令 pkg-config opencv --libs pkg-config opencv --modversion 出现这个错误,缺失了opencv.

使用putty连接并上传和下载文件到linux服务器

目录 一、连接到linux 二、上传和下载文件 putty下载地址:https://putty.en.softonic.com/?ex=MOB-575.6 安装完后会看到如下的目录文件 一、连接到linux 点击putty.exe,弹出Configuration窗口,填写linux机器的IP地址、端口号等。 点击open按钮,输入用户名和密码。登陆成功后就可以操作linux服务器了 二、上传和下载文件 打开目录下的psftp 在弹出的窗口里输入open 用户名@IP地址,如 open user1@192.168.0.100。然后按照提示输入密码 通过cd切换linux服务器的路径,如 cd /temp;通过lcd可以切换本地Windows的路径,如 lcd /file;这两个路径的切换时相互不干扰的。 从本地Windows上传license.demo文件到Linux,使用命令:put 文件名,上传Http文件夹则使用命令:put -r 文件夹从linux上下载license.demo文件到本地,使用命令:get 文件名,下载Http文件夹使用命令:get -r 文件夹

不同路径(Java)

package leetCoder; /** * @author : zhaoliang * @program :newCoder * @description : 不同路径 * @create : 2020/06/19 09:32 */ public class LeetCode62 { /** * 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 * * 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 * * 问总共有多少条不同的路径? * @param m * @param n * @return */ public int uniquePaths(int m, int n) { int[][] dp = new int[m][n]; for (int i = 0; i <m ; i++) { dp[i][0]=1; } for (int j = 0; j <n ; j++) { dp[0][j]=1; } for (int i = 0; i <m ; i++) { for (int j = 0; j <n ; j++) { dp[i][j] = dp[i-1][j] + dp[i][j-1]; } } return dp[m-1][n-1]; } }

利用css3伪元素实现加号、减号、对号小图标效果

目前图标:加号、减号、对号、向下箭头、实心三角箭头 前两个图标都加了hover状态和禁用状态效果 1、加号 通过定位以及::before和::after相结合实现 效果: .addBtn{ display: inline-block; width: 16px; height: 16px; border-radius: 50%; background-color: #D4D7D7; position: relative; cursor: pointer; &:hover{ // hover状态 background-color: #00C8C8; } &.disabledBtn{ // 禁用状态 background-color: #E4E4E4; cursor: not-allowed; } } .addBtn::before{ // 加号的横线 content: ''; width: 8px; height: 2px; background-color: #fff; position: absolute; top: 7px; left: 4px; } .addBtn::after{ // 加号的竖线 content: ''; width: 2px; height: 8px; background-color: #fff; position: absolute; top: 4px; left: 7px; } 2、减号

vue跳转同一路由,导致页面函数没有执行,页面不刷新。

** vue跳转同一路由,页面函数无法刷新,看了不少解决方法还是无用,下面说说我的解决放。 话不多少,说方法,在使用$router.push跳路由的时候,第一次可以执行方法,第二次跳同一个页面就会使函数不在渲染。 第一种,网上说用 watch来监听,函数都没执行怎么可能数据会渲染新数据所以 watch是不行的。 第二种,router.push 用 query与params传参数,这个不会刷新页面,只是不同的传值方法而已。 第三种,加时间戳, var d=new Date(); this.$router.push({ name: “order_traveler”, query: {t:d.getTime()}, }); 这个方法还是不会使你的跳转的页面函数再次渲染,因为他会判断你的主键是同一个key,所以执行后不会渲染数据。 第四种,使用$route.fullPath加时间戳,他会判断组件和路由的属性都改变了吗,然后在去执行跳转的函数。 如下代码: <router-view ref="addEnterprise" :key="$route.fullPath"></router-view>//组件 var d=new Date(); //定义时间戳 this.$router.push({ name: "order_traveler", query: {t:d.getTime()}, }); 这样就可以跳同一个页面,并且刷新数据了,希望对大家有用!!!!!!!!!!!!!!!

String的面试知识点

String的变化历程 在java6之前,String对象主要有四个成员变量:char[]数组,offset偏移量,count字符数量,hash哈希值;通过offset和count两个属性可以定位char[]数组,共享数组对象,但是有可能会导致内存泄露。占用空间不被释放,比如源字符串很大,subString()一个字符,然后i只调用分割后的,那麽就会会共享原String对象,不会被GC,造成内存泄露。 泄露:调用String对象的substring方法后指向的对象地址并没有发生改变,只是改变的是偏移量,这样的话在GC阶段就有可能造成内存泄露了。 解决:这个里面是通过内存复制的方式重新指向了一个新的地址。 java7/8修复了内存泄漏问题。 java9中维护了一个新的属性coder,标识字符串的字节编码;char[]改成byte[],可以减少每一个字符的占用空间,由16字节减少为8字节。 不可变性的好处(final) 1.String被设计为不可变是因为String对象是缓存在字符串池中的, 因此这些缓存的字符串是可以被多个客户端访问的,如果一个客户端的访问影响了别的客户端的行为,这样就存在风险。例如一个客户端把"test"改为"TEST",其他所有的客户端都会跟着受影响。之所以把String进行了缓存处理,是出于性能的考虑。也就是说开发人员认为读比写次数多,索性就直接放方法区公用。因此这个风险只能通过把String设置为不可变来避免。同时,String类被声明为final的。是防止其他人通过继承String类,覆盖父类的方法,会破坏String的不可变性、缓存性以及hascode的计算方式 2.为了实现String可以创建HashCode不可变性 因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。否则hashcode不同,同一个字符串会导致不同entry。 3**.为了线程安全** 因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。 4.String的不可变性为Java的类加载机制的安全性提供了根本的保障。 如果String是可变的,一个加载"java.io.Writer" 类的请求,可以被改变为"mil.vogoon.DiskErasingWriter",这样安全就没有保障了。 双亲委派机制保证了string类不被重写,因为肯定是想看root加载类有没有,再往下看。 字符串的创建问题 String str = "abc"的方式会检查对象是否在字符串常量池中,如果在,就直接返回该对象的引用;否则新的字符串将在常量池中被创建。 2.str = new String(“abc”)每次都会在堆中新建一个对象。 字符串的性能优化 1.两个或者两个以上的字符串常量相加,在预编译的时候“+”会被优化,相当于把两个或者两个以上字符串常量自动合成一个字符串常量. 字符串常量相加,不会用到StringBuilder对象,有一点要注意的是:字符串常量和字符串是不同的概念,字符串常量储存于方法区(总之就常量池),而字符串储存于堆(heap)。2.而非纯常量的字符串相加 像是字符串相加表达式中带变量的那种的话,就是JVM会自动创建一个StringBuilder然后再调用append()方法最后再调用toString()方法返回的方式了,所以在堆中会有个String对象,引用指向的是堆中的对象的地址。 所以相加出来的结果,是不会被加到常量池中的。String s1 = new String("he")+new String("llo"); 1,这个代码中,首先,new String(“he”),先在常量池中看,发现没有这个"he"常量,于是建一个,然后再在堆中创建一个String的对象(但没引用,很快被gc的)。 2,加法**,暗中new了StringBuilder,调用append方法。** 3.new String(“llo”)一样的道理,堆中一个String对象,常量池中"llo"常量对象。 4.StringBuilder的append方法搞定后,调用toString()方法,具体是new一个String对象,也就是现在是一个堆中的String对象,内容是"hello",但注意这个hello没有在常量池中创建!!其实可以理解因为没有出现过一次"hello",拼接是通过StringBuilder的append方法完成的。 总之:对于所有包含new方式新建对象(包括null)和变量形式 的“+”连接表达式,它所产生的新对象都不会被加入字符串池中。 String str = "new String("he"); for(int i=0; i<10; i++) { str = str + i; } 自动优化成 String str = "haha"; for(int i=0; i<10; i++) { str = (new StringBuilder(String.

LCD基础概念(三):LCD RGB之PCLK、VS、HS、DE

RGB之PCLK、VS、HS、DE 1.Pixel clock像素时钟 Pixel clock,也叫RGB clock,也叫Dot clock,一般会简写为pclk。只要是数字信号处理电路,就必须有时钟信号。在液晶面板中,像素时钟是一个非常重要的时钟信号。像素时钟信号的频率与液晶面板的分辨率有关,分辨率越高,像素时钟信号的频率也越高。无论对TTL接口液晶面板,还是对LVDS接口面板,像素时钟信号都有两方面作用: 指挥RGB信号按顺序传输,数字RGB信号在像素时钟信号的作用下,按照一定的顺序,由驱动板传输到液晶面板中,使各电路按照一定的节拍协调地工作。确保数据传输的正确性。无论是驱动板电路,还是液晶面板电路,在读取数字RGB信号时,都是在像素时钟的作用与控制下进行的,各电路只有在像素时钟的下降沿(或上升沿)到来时才对数字RGB数据进行读取,以确保读取数据的正确性。 2.HS与VS同步脉冲信号 行同步信号(HS或HSYNC)和场同步信号(VS或VSYNC)行同步信号(HS)的作用是选择出液晶面板上有效行信号区间场同步信号(VS)的作用是选择出液晶面板上有效场信号区间行场同步信号的共同作用,可将选择出液晶面板上的有效视频信号区间。需注意:液晶显示器中使用的同步信号是一个不包含消隐信号的两电平信号,而CRT显示器彩电中的同步信号是一个包含消隐信号的三电平信号。这是因为液晶显示器处理的是数字信号,数字信号只能有两种电平,高电平1和低电平0。 3.DE信号 有效数据选通信号也称数据使能信号,在液晶显示器电路中其表示符号有多种,如DEN、DE等,一般称其为DE信号。 设立DE信号的意义 在输入到液晶显示器的视频信号中,有效视频信号(有效RGB信号)只占信号周期中的一部分,而信号的行消隐和场消隐期间并不包含有效的视频数据。因此,液晶显示器中的有关电路在处理视频信号时,必须将包含有效视频信号的区间和不包含有效视频信号的消隐区间区分开来。为了区分有效和无效视频信号,在液晶显示器电路中设置了DE信号。 DE信号及其产生 在液晶显示器中不能处理三电平的同步/消隐信号,因此,单独设立了一个DE信号。就是说在数字视频信号的电路,一般都需要DE信号。 DE与HS、VS的关系,以及前肩后肩的概念: DE与RGB数据信号之间的关系: DE信号与数据读取之间的关系: DE信号与在像素时钟DCLK的作用下读取RGB数据的示意图。从图上可看出,只有当DE信号在高电平期间,且在像素时钟DCLK为下降沿时(为啥是下降沿?待查),相关电路才能对RGB数据进行读取,以确保读取数据的正确性。 DE信号与显示画面之间的关系: (4)在液晶面板的TTL和LVDS接口中,包括的信号主要有RGB数据信号、像素时钟信号DCLK、行同步信号HS、场同步信号VS及有效显示数据选通信号DE。所有液晶面板都需要输入RGB数据和像素时钟DCLK,但其使用同步信号的方式却不同。 仅使用DE同步信号液晶面板 这种液晶面板不需要输入行同步信号HS和场同步信号VS,只需要输入DE作为同步信号使用即能正常工作。液晶面板的行同步信号输人端和场同步信号端一般都需要接低电平,否则不能正常工作。 同时使用DE/HS/VS同步信号液晶面板 这种液晶面板需要同时输入有效显示数据选通信号DE、行同步信号HS、场同步信号VS才能正常工作。 液晶面板单像素/奇偶像素数据输入模式及信号定时(不懂??待理解) 液晶显示器驱动板向液晶面板传送RGB数据信号的方式有两种:一种为单像素模式(单路方式);另一种为奇偶双像素模式(双路方式),将RGB数据分为奇数像素和偶数像素两路向液晶面板传送。 参考

E5 调用API续订程序:Microsoft 365 E5 Renew

Microsoft 365 E5 Renew Microsoft365 E5 Renew 已于2021-04-30结束生命周期,请下载Microsoft365 E5 Renew Plus 继续使用!!! Microsoft365 E5 Renew 系列详情 系列代号初代WebPlusX发布状态已发布已发布已发布已发布更新维护停止更新停止更新长期支持长期支持呈现方式桌面应用网页服务桌面应用网页服务运行平台Windows全平台Windows全平台程序下载已关闭已关闭可下载可下载代码开源计划开源闭源闭源闭源站点部署N/A可部署N/A可部署运行框架.Net Framework 4.5ASP.Net Core 3.1.Net 6.0ASP.Net Core 3.1发布时间2020-06-182020-11-012021-03-062021-08-16停止时间2021-04-302021-08-16N/AN/A 入群须知 使用本系列产品只是增加E5续订概率,并不能保证100%续订成功续订操作有些许技术门槛,且需要具备一定的自学能力每个人的时间都是宝贵的,遇到问题先查阅常见问题文档,实在无法解决时再发起提问(提问的艺术) QQ交流群:254058945 TG交流群:https://t.me/MS365E5Renew Microsoft 365 E5 Renew的由来 Microsoft 365 E5 Renew的前身为Microsoft 365 E5 API Evaluator,Microsoft 365 E5 API Evaluator其主要功能是评估Microsoft Graph REST API的通信稳定性,通过长期不定时的随机抽取测试来评估本机与Azure服务器之间的通信稳定度,其本质是使用Microsoft 365 E5开发者账号自动调用API。 Microsoft 365 E5开发者账号拥有Office 365桌面版和Onedirve 25TB空间,且微软政策表明只要保持开发活跃就可以续期E5开发者账户的使用期限,理论上是无限续期,而判定为开发活跃其中一种条件是调用Microsoft Graph REST API,Microsoft 365 E5 API Evaluator恰好满足其要求,因此Microsoft 365 E5 Renew应运而生。 主要功能 支持开机自启动后台调用:使用简单方便,无需购买服务器部署,本地应用程序即开即用两种可选的调用权限:用户未登录作为守护程序调用(需要客户端密码)、程序以登录用户身份直接调用(需要账户密码)API种类齐全:42个可选的Microsoft Graph REST API Beta中的API(未来可能会继续添加)完全随机的API调用模式:从已选定的API序列中随机抽取一个或几个进行调用(个数和API随机)完全随机的API调用时间间隔:随机区段500s-86400s自定义完全随机的API内容(仅部分API支持):发送邮件的内容随机 Onedirve上传文件的内容随机运行配置自动保存:程序会自动保存运行配置,无需反复设置支持无限制账户个数:理论上允许无限制个数账号后台自动调用 主界面 运行结果查看 使用教程(请勿开启账号的双重验证功能)

Golang 获取时间格式化

package main import ( "fmt" "time" ) func main(){ now := time.Now() fmt.Printf("%T %v",now,now) fmt.Println() fmt.Printf("年:%v 、",now.Year()) fmt.Printf("月:%v 、",int(now.Month())) fmt.Printf("月:%v 、",now.Month()) fmt.Printf("日:%v 、",now.Day()) fmt.Printf("时:%v 、",now.Hour()) fmt.Printf("分:%v 、",now.Minute()) fmt.Printf("秒:%v ",now.Second()) fmt.Println() //方式一:格式化时间 dateStr := fmt.Sprintf("%d-%d-%d %d:%d:%d",now.Year(),int(now.Month()), now.Day(),now.Hour(),now.Minute(),now.Second()) //2020-3-18 19:25:7 fmt.Printf("%s",dateStr) fmt.Println() dateStr1 := fmt.Sprintf("%02d-%02d-%02d %02d:%02d:%02d",now.Year(),int(now.Month()), now.Day(),now.Hour(),now.Minute(),now.Second()) //2020-03-18 19:25:07 fmt.Printf("%s",dateStr1) fmt.Println() //格式化方式二: //2020/03/18 19:30:29 fmt.Printf(now.Format("2006/01/02 15:04:05")) fmt.Println() //2020-03-18 19:30:29 fmt.Printf(now.Format("2006-01-02 15:04:05")) fmt.Println() //2020-03-18 fmt.Printf(now.Format("2006-01-02")) fmt.Println() //19:30:29 fmt.Printf(now.Format("15:04:05")) }

Pytorch学习(4)——自然语言分类模型

视频链接:https://www.bilibili.com/video/BV1vz4y1R7Mm?p=4 预先下载 https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.3.0/en_core_web_sm-2.3.0.tar.gz 然后将其解压 下面的tokenizer_language设置为 解压路径 + “en_core_web_sm-2.3.0\en_core_web_sm\en_core_web_sm-2.3.0” 预先使用迅雷下载 http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz 然后将文件移动到同级目录 ./data/imdb 中。 使用“解压到当前文件夹”进行解压 预先使用迅雷下载 https://apache-mxnet.s3.cn-north-1.amazonaws.com.cn/gluon/embeddings/glove/glove.6B.zip 然后移动到同级目录 .vector_cache 中。 import torch from torchtext import data SEED = 1 # 固定随机数种子 确保可复现 torch.manual_seed(SEED) torch.cuda.manual_seed(SEED) torch.backends.cudnn.deterministic = True # ?? text = data.Field(tokenize='spacy', tokenizer_language=r'F:\tmp\en_core_web_sm-2.3.0\en_core_web_sm\en_core_web_sm-2.3.0') label = data.LabelField(dtype=torch.float) from torchtext import datasets train_data_all, test_data = datasets.IMDB.splits(text, label) # 耗时较长 print(vars(train_data.examples[0])) {'text': ['Bromwell', 'High', 'is', 'a', 'cartoon', 'comedy', '.', 'It', 'ran', 'at', 'the', 'same', 'time', 'as', 'some', 'other', 'programs', 'about', 'school', 'life', ',', 'such', 'as', '"

服务器查看server manager的类型

display manager有很多种类型,比如lightdm,gdm等,具体的种类和安装命令可以参考https://wiki.manjaro.org/index.php/Install_Display_Managers。 如果要在命令行中查看当前服务器的display manager种类,可以使用命令 grep '/usr/s\?bin' /etc/systemd/system/display-manager.service 我的机器返回的结果是: ExecStart=/usr/sbin/lightdm 证明我的机器的display manager是lightdm。

单端信号和差分信号的区别

单端信号 单端信号是相对于差分信号而言的,单端输入指信号有一个参考端和一个信号端构成,参考端一般为地端。 差分信号 差分传输是一种信号传输的技术,区别于传统的一根信号线一根地线的做法(单端信号),差分传输在这两根线上都传输信号,这两个信号的振幅相等,相位相反。在这两根线上传输的信号就是差分信号。 差分与单端信号比较 差分信号与单端信号走线的做法相比,其优缺点分别是: 优点 1、抗干扰能力强。干扰噪声一般会等值、同时的被加载到两根信号线上,而其差值为0,即,噪声对信号的逻辑意义不产生影响。 2、能有效抑制电磁干扰(EMI)。由于两根线靠得很近且信号幅值相等,这两根线与地线之间的耦合电磁场的幅值也相等,同时他们的信号极性相反,其电磁场将相互抵消。因此对外界的电磁干扰也小。 3、时序定位准确。差分信号的接受端是两根线上的信号幅值之差发生正负跳变的点,作为判断逻辑0/1跳变的点的。而普通单端信号以阈值电压作为信号逻辑0/1的跳变点,受阈值电压与信号幅值电压之比的影响较大,不适合低幅度的信号。 缺点 若电路板的面积非常紧张,单端信号可以只有一根信号线,地线走地平面,而差分信号一定要走两根等长、等宽、紧密靠近、且在同一层面的线。这样的情况常常发生在芯片的管脚间距很小,以至于只能穿过一根走线的情况下。 基本区别 不说理论上的定义,说实际的。单端信号指的是用一个线传输的信号,一根线没参考点怎么会有信号呢?easy,参考点就是地啊。也就是说,单端信号是在一跟导线上传输的与地之间的电平差。那么当你把信号从A点传递到B点的时候,有一个前提就是A点和B点的地电势应该差不多是一样的,为啥说差不多呢,后面再详细说。 差分信号指的是用两根线传输的信号,传输的是两根信号之间的电平差。当你把信号从A点传递到B点的时候,A点和B点的地电势可以一样也可以不一样,但是A点和B点的地电势差有一个范围,超过这个范围就会出问题了。 二、传输上的差别 单端信号的优点是,省钱~方便~ 大部分的低频电平信号都是使用单端信号进行传输的。一个信号一根线,最后,把两边的地用一根线一连,完事。缺点在不同应用领域暴露的不一样,归结起来,最主要的一个方面就是,抗干扰能力差。 首先说最大的一个问题,地电势差以及地一致性。大家都认为地是0V,实际上,真正的应用中地是千奇百怪变化莫测的一个东西,我想我会专门写一些地方面的趣事。比如A点到B点之间,有那么一根线,用来连接两个系统之间的地,那么如果这根线上的电流很大时,两点间的地电势可能就不可忽略了,这样一个信号,从A的角度看起来是1V,从B的角度看起来可能只有0.8V了,这可不是一个什么好事情,这就是地电势差对单端信号的影响。接着说地一致性。实际上很多时候这个地上由于电流忽大忽小,布局结构远远近近, 地上会产生一定的电压波动,这也会影响单端信号的质量。 差分信号在这一点有优势,由于两个信号都是相对于地的 ,当地电势发生变化时,两个信号同时上下浮动(当然是理想状态下), 差分两根线之间的电压差却很少发生变化,这样信号质量不久高了吗?其次就是传输过程中的干扰,当一根导线穿过某个线圈时,且这根线圈上通着交流电时,这根导线上会产生感应电动势~~好简单的道理,实际上工业现场遇到的大部分。问题就是这么简单,可是你无法抗拒~ 如果是单端信号,产生多少,就是多少,这就是噪声你毫无办法。但是如果是差分信号,你就可以考虑拉,为啥呢,两根导线是平行传输的, 每根导线上产生的感应电动势不是一样吗,两个一减,他不久没了吗~ 确实,同样的情况下,传输距离较长时,差分信号具有更强的驱动能力、更强的抗干扰能力,同样的,当你传输的信号会对其他设备有干扰时,差分信号也比单端信号产生的信号相对小,也就是常说的EMI特性。 使用时需要注意的 由于差分比单端有不少好处,在模拟信号传输中很多人愿意使用差分信号,比如桥式应变片式力传感器,其输出信号满量程时有的也只有2mV,如果使用单端信号传输,那么这个信号只要电源的纹波就能把他吃光。所以实际上,都是用仪表运方进行放大后,再进行处理。而仪表运方正是处理差分信号最有力的几个工具之一。但是,使用差分信号时,一定要注意一个问题,共模电压范围。也就是说,这两根线上的电压,相对于系统的地,还是不能太大。你传输0.1V的信号没问题,但是如果一根是 1000.0 另外一根是 1000.1,那就不好玩了,问题在于,在很多场合下使用差分信号都是为了不让两个系统的地简单的共在一起,更不能把差分信号中的一根直接接在本地系统的地上,那不白费劲吗--又成单端了,那么如何抑制共模电压呢?其实也挺简单的,将两根线都通过一个足够大的电阻,连接到系统的地上。这就像一根拴在风筝上的线,我在地上跑跑跳跳,不会影响风筝的高度。 但是你永远逃不出我的视线,而我的视线,在电子行业,叫共模电压范围,回答一个网友的问题:单端转差分怎么转。单单将单端信号用反向跟随器跟随并不是不行,但是差分信号被平白的放大了2倍~~ 常见的用仪表运方+普通运方搭建的单端转差分是个很好的例子。 关于差分的五个常见误区 1、认为差分信号不需要地平面作为回流路径,或者认为差分走线彼此为对方提供回流途径。造成这种误区的原因是被表面现象迷惑,或者对高速信号传输的机理认识还不够深入。差分电路对于类似地弹以及其它可能存在于电源和地平面上的噪音信号是不敏感的。地平面的部分回流抵消并不代表差分电路就不以参考平面作为信号返回路径,其实在信号回流分析上,差分走线和普通的单端走线的机理是一致的,即高频信号总是沿着电感最小的回路进行回流,最大的区别在于差分线除了有对地的耦合之外,还存在相互之间的耦合,哪一种耦合强,那一种就成为主要的回流通路.在PCB电路设计中,一般差分走线之间的耦合较小,往往只占 10~20%的耦合度,更多的还是对地的耦合,所以差分走线的主要回流路径还是存在于地平面。当地平面发生不连续的时候,无参考平面的区域,差分走线之间的耦合才会提供主要的回流通路,尽管参考平面的不连续对差分走线的影响没有对普通的单端走线来的严重,但还是会降低差分信号的质量,增加 EMI,要尽量避免。也有些设计人员认为,可以去掉差分走线下方的参考平面,以抑制差分传输中的部分共模信号,但从理论上看这种做法是不可取的,阻抗如何控制?不给共模信号提供地阻抗回路,势必会造成 EMI 辐射,这种做法弊大于利。 2、认为保持等间距比匹配线长更重要。在实际的PCB布线中,往往不能同时满足差分设计的要求。由于管脚分布,过孔,以及走线空间等因素存在,必须通过适当的绕线才能达到线长匹配的目的,但带来的结果必然是差分对的部分区域无法平行。PCB 差分走线的设计中最重要的规则就是匹配线长,其它的规则都可以根据设计要求和实际应用进行灵活处理。 3、认为差分走线一定要靠的很近。让差分走线靠近无非是为了增强他们的耦合,既可以提高对噪声的免疫力,还能充分利用磁场的相反极性来抵消对外界的电磁干扰。虽说这种做法在大多数情况下是非常有利的,但不是绝对的,如果能保证让它们得到充分的屏蔽,不受外界干扰,那么我们也就不需要再让通过彼此的强耦合达到抗干扰和抑制 EMI 的目的了。如何才能保证差分走线具有良好的隔离和屏蔽呢?增大与其它信号走线的间距是最基本的途径之一,电磁场能量是随着距离呈平方关系递减的,一般线间距超过4 倍线宽时,它们之间的干扰就极其微弱了,基本可以忽略。此外,通过地平面的隔离也可以起到很好的屏蔽作用,这种结构在高频的(10G 以上)IC封装PCB 设计中经常会用采用,被称为CPW结构,可以保证严格的差分阻抗控制(2Z0)。 差分走线也可以走在不同的信号层中,但一般不建议这种走法,因为不同的层产生的诸如阻抗、过孔的差别会破坏差模传输的效果,引入共模噪声。此外,如果相邻两层耦合不够紧密的话,会降低差分走线抵抗噪声的能力,但如果能保持和周围走线适当的间距,串扰就不是个问题。在一般频率(GHz 以下),EMI 也不会是很严重的问题,实验表明,相距 500Mils 的差分走线,在3 米之外的辐射能量衰减已经达到 60dB,足以满足 FCC的电磁辐射标准,所以设计者根本不用过分担心差分线耦合不够而造成电磁不兼容问题。 4、差分曼切斯特编码并不是差分信号的一种,它指的是用在每一位开始时的电平跳变来表示逻辑状态“0”,不跳变来表示逻辑状态“1”。但每一位中间的跳变是用来做同步时钟,没有逻辑意义。 5、双绞线上面走的不一定是差分信号,单端信号在双绞线上的电磁辐射也比平行走线的辐射小。

ceph的一些学习过程

内容比较杂,个人学习ceph的一些理解。 集群运行图 Ceph 依赖于 Ceph 客户端和 OSD ,因为它们知道集群的拓扑,这个拓扑由 5 张图共同描述,统称为“集群运行图”: Montior Map: 包含集群的 fsid 、位置、名字、地址和端口,也包括当前版本、创建时间、最近修改时间。要查看监视器图,用 ceph mon dump 命令。OSD Map: 包含集群 fsid 、创建时间、最近修改时间、存储池列表、副本数量、归置组数量、 OSD 列表及其状态(如 up 、 in )。要查看OSD运行图,用 ceph osd dump 命令。PG Map::** 包含归置组版本、其时间戳、最新的 OSD 运行图版本、占满率、以及各归置组详情,像归置组 ID 、 up set 、 acting set 、 PG 状态(如 active+clean ),和各存储池的数据使用情况统计。CRUSH Map::** 包含存储设备列表、故障域树状结构(如设备、主机、机架、行、房间、等等)、和存储数据时如何利用此树状结构的规则。要查看 CRUSH 规则,执行 ceph osd getcrushmap -o {filename} 命令;然后用 crushtool -d {comp-crushmap-filename} -o {decomp-crushmap-filename} 反编译;然后就可以用 cat 或编辑器查看了。MDS Map: 包含当前 MDS 图的版本、创建时间、最近修改时间,还包含了存储元数据的存储池、元数据服务器列表、还有哪些元数据服务器是 up 且 in 的。要查看 MDS 图,执行 ceph mds dump 。 Ceph 监视器维护着集群运行图的主副本。一个监视器集群确保了当某个监视器失效时的高可用性。存储集群客户端向 Ceph 监视器索取集群运行图的最新副本。

mapnik 3.0.23 和python-mapnik-3.0.16 安装部署

源码安装部署:https://github.com/mapnik/mapnik/blob/master/INSTALL.md 安装相关的依赖,自己安装部署的过程中发现几个问题,是因为两个依赖没有安装好: 1.boost https://www.boost.org/users/download/ boost安装前要先删除旧版本,一般安装在/usr目录下,把这里相关的boost文件删除即可。 安装的版本是1.69.0 ./bootstrap.sh ./b2 成功即提示: The Boost C++ Libraries were successfully built! The following directory should be added to compiler include paths: /root/mapbox_tools/boost_1_69_0 The following directory should be added to linker library paths: /root/mapbox_tools/boost_1_69_0/stage/lib ./b2 install --prefix=/usr ##--prefix=/usr用来指定boost的安装目录,不加此参数的话默认的头文件在/usr/local/include/boost目录下, 库文件在/usr/local/lib/目录下。 这里把安装目录指定为--prefix=/usr则boost会直接安装到系统头文件目录和库文件目录下,可以省略配置环境变量。 2.mabox variant https://github.com/mapbox/variant 需要使用到这里面的头文件,不需要编译安装,直接把这个/variant-1.1.3/include/下的mapbox文件夹拷贝到操作系统的/usr/include文件夹里面即可。 3.其他依赖: cairo-1.16.0.tar.xz libwebp-1.1.0.tar.gz proj-4 sqlite-autoconf-3330000.tar.gz(源码安装完毕,它自动配置一些东西,导致gdal出问题,删除了它就可以) tiff-4.1.0.tar.gz mapnik-3.0.23 安装过程 第一次安装到这个位置: ./configure PREFIX=/pgs/usr/local/mapnik 重装到这个位置: ./configure PREFIX=/opt/mapnik make make install 因为安装在自定义路径,需要配置bin 、include、 lib的路径: ln -s /opt/mapnik/include/mapnik/ /usr/local/include/ ln -s /opt/mapnik/bin/* /usr/local/bin/ ln -s /opt/mapnik/lib/* /usr/local/lib/ 测试: mapnik-config mapnik-index mapnik-render 如果安装到默认位置,会遇到一些错误:

javaFX FXML 下拉框/选择框/choicebox 的 填充以及用enum/枚举填充 用法

1.普通地加载 <Label layoutX="18.0" layoutY="164.0" text="性别" /> <ChoiceBox fx:id="outBhEncodingCbx" layoutX="139.0" layoutY="160.0" prefWidth="150.0"> <items> <FXCollections fx:factory="observableArrayList"> <String fx:value="male" /> <String fx:value="female" /> <String fx:value="unknown" /> </FXCollections> </items> </ChoiceBox> 2.通过FXCollections.observableArrayList public class Main extends Application { ObservableList cursors = FXCollections.observableArrayList( Cursor.DEFAULT, Cursor.CROSSHAIR, Cursor.WAIT, Cursor.TEXT, Cursor.HAND, Cursor.MOVE, Cursor.N_RESIZE, Cursor.NE_RESIZE, Cursor.E_RESIZE, Cursor.SE_RESIZE, Cursor.S_RESIZE, Cursor.SW_RESIZE, Cursor.W_RESIZE, Cursor.NW_RESIZE, Cursor.NONE ); @Override public void start(Stage stage) { ChoiceBox choiceBoxRef = ChoiceBoxBuilder.create() .items(cursors) .build(); ...... 3.使用enum类枚举自动填充 需要在这个fxml的controller的初始化里使用: public void initialize(URL location, ResourceBundle resources) { gender.

利用cookie实现b站免账号密码登录

document.cookie ="SESSDATA=49d4147c%2C8957247677%2Cf295e641;domain=.bilibili.com;path=/"; 在一个没有保存b站cooki信息的网站上访问b站,然后f12打开控制台 将之前登录的cookie信息中对应的字段替换上面的对应的部分然后输入,回车刷新浏览器后即可生效

modelsim : module is not defined

问题:在使用modelsim对基于GW FPGA项目的仿真时,报错:module is not defined。提到的模块往往是调用的IP核中定义的模块。 原因:未添加prim_sim库。 解决:将preim_sim.v文件添加到仿真工程中,并编译,再仿真即可。

Nginx之location详解

root location中root指定的只是相对路径,需要和路径结合起来映射地址,比如 location ^~/static/ { ## 这里的root需要和路径结合使用,即是映射的文件位置为 /usr/alyingboy/static root /usr/alyingboy/; index index.html } 此时我们访问 IP/static/a.css ,那么就会找到 /usr/alyingboy/static/a.css alias alias指定的是绝对路径,不会和location中的路径结合使用,而是直接使用地址映射到文件,比如 location ^~/static/ { ## 不会路径结合映射地址,那么这里就会直接映射到/usr/alyingboy/文件夹下的文件 alias /usr/alyingboy/; index index.html } 如果定义的路径是文件夹,那么需要使用/结尾 一旦配置请求location映射到了指定的位置,那么下面全部的文件夹和文件都可以映射到,不需要在配置对其的映射,比如 ,但是如果使用其中的文件名重新映射了地址,那么这个路径将不能使用 # /usr/alyingboy/文件夹下的全部文件包括子文件夹和文件都可以使用指定的地址访问到,比如访问地址为 :# IP/static/a.txt ,那么这个地址访问的是/usr/alyingboy/static/a.txt文件location / { root /usr/alyingboy/; index index.html; } 路径匹配 = 开头表示精确匹配。如 A 中只匹配根目录结尾的请求,后面不能带任何字符串;^~ 开头表示uri以某个常规字符串开头,不是正则匹配;~ 开头表示区分大小写的正则匹配;~* 开头表示不区分大小写的正则匹配;/ 通用匹配, 如果没有其它匹配,任何请求都会匹配到。 一个location定义可以是一个前缀字符串,也可以是一个正则表达式。正则表达式使用的时候要在前面用“*”修饰符(用于不区分大小写匹配),或者“”修饰符(用于区分大小写)。为了找到请求匹配的location,nginx首先检查location定义,用前缀字符串(这些location成为前缀location)。其中,最长匹配前缀的location会被选中并记住。然后,检查正则表达式,按照它们在配置文件中出现的顺序。对正则表达式的搜索在第一次匹配时终止,并使用相应的配置。如果没有找到与正则表达式的匹配,则使用前面记住的前缀位置的配置。 1、用前缀字符串(前缀location)匹配URL,并且选中并记住最长匹配前缀的location(注意:是在匹配的里面记住最长的那个) 2、按照正则表达式在配置文件中出现的顺序依次去匹配,当匹配到第一个以后立即停止,并使用与之相应的那个location。如果没有一个正则表达式匹配,则使用之前记住的那个前缀location。 以上,我们可以得出一个结论:优先使用正则表达式,如果没有匹配的正则表达式发现,则使用匹配的最长前缀字符串location location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] }location / { # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 # 但是正则和最长字符串会优先匹配 [ configuration B ] }location /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration C ] }location ~ /documents/Abc { # 匹配任何以 /documents/Abc 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration CC ] }location ^~ /images/ { # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。 [ configuration D ] }location ~* \.

CentOS下GitLab的安装部署

转载来源 :https://mp.weixin.qq.com/s/kUwZja0xK1IfqGU6R2f1EA 一 GitLab Server的搭建 参考:https://about.gitlab.com/install/ 1.准备工作 以centos7为例,准备一台至少内存为4G的机器。 系统版本:CentOS Linux release 7.3.1611 (Core) 软件版本:Gitlab-ce-11.10.1 硬件要求:最低2核4GB,建议4核8GB 2.安装依赖软件 [root@localhost ~]# sudo yum install -y git vim gcc glibc-static telnet [root@localhost ~]# sudo yum install -y curl policycoreutiels-python openssh-server [root@localhost ~]# sudo systemctl enable sshd [root@localhost ~]# sudo systemctl start sshd [root@localhost ~]# sudo yum install postfix -y [root@localhost ~]# sudo systemctl enable postfix [root@localhost ~]# sudo systemctl start postfix => 启动SSH远程服务 [root@localhost ~]# systemctl stop firewalld => 停止Firewalld防火墙服务 [root@localhost ~]# systemctl disable firewalld => 禁用Firwalld防火墙服务开机自启 [root@localhost ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux => 关闭SeLinux(重启主机生效) [root@localhost ~]# setenforce 0 3.

数据结构的基本概念

1.什么是数据结构? 数据元素:是数据(集合)的一个个体,它是数据的基本单位。 数据项:用来描述数据元素,数据的最小单位。 数据对象:具有相同性质的若干个数据元素的集合,如整数数据对象是所有整数的集合。 eg.下表就是学生为数据对象,数据项包括学号、姓名,班级,性别,班号。而数据元素就是数据对象的基本单位,即每一个学生 的数据。比如“1号张斌,性别男,班号9901”,这就是一个数据元素。 数据对象:学生; 数据项:学号,姓名,性别,班号; 数据元素:一个学生的所有数据项下的所有数据的集合。 数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。(集合中的数据元素可按照数据项分类,数据元素的集合有构成了数据对象)。 数据结构=数据对象+数据元素结构 数据结构的构成:逻辑结构(面向程序员的数据之间的结构)、存储结构(面像机器存储的实际物理结构)、数据运算(施加在该数据的运算)。 2.数据结构的基本构成 2.1逻辑结构 主要类型:线性结构、树型结构、图型结构。 1.线性结构:开始元素和终端元素都是唯一的,除此之外,其余元素都有且仅有一个前趋元素和一个后继元素。 2.树型结构 3.图型结构:所有元素都可能有多个前趋元素和多个后继元素 数据的逻辑表示:二元组表示 例如,如下数据为一个矩阵: 对应的二元组表示为B=(D,R) ,其中: D={2,6,3,1,8,12,7,4,5,10,9,11} R={r1,r2} 其中,r1 表示行关系, ,r2表示列关系 r1={<2,6>,<6,3>,<3,1>,<8,12>,<12,7>,<7,4>,<5,10>, <10,9>,<9,11>} r2={<2,8>,<8,5>,<6,12>,<12,10>,<3,7>,<7,9>, <1,4>, <4,11>} 2.2存储结构(物理结构) 主要类型:顺序存储结构、链式存储结构、索引存储结构、哈希(散列)存储结构。 1.顺序存储结构(结构体):所有元素占用一整块内存空间,逻辑上相邻的元素、物理上也相邻。 2.链式存储结构(链表):一个逻辑元素用一个节点存储,每个节点单独分配,所有节点的地址不一定是连续的。用指针来表示 逻辑关系。 此外还有索引存储结构、哈希(散列)存储结构。 2.3数据运算 数据运算是对数据的操作,分为:运算描述和运算实现。 3.数据类型和抽象数据类型 1.数据类型,是一个值的集合和定义在此集合上的一组操作的总称。 数据类型就是已经实现类的数据结构。 2.抽象数据类型=逻辑结构+抽象运算 抽象数据类型((ADT))指的是从求解问题的数学模型中抽象出来的数据逻辑结构和运算(抽象运算), 而不考虑 计算机的具体实现 。 4.算法概述 4.1 什么是算法 数据元素之间的关系有逻辑关系和物理关系,对应的运算有基于逻辑结构的运算描述和基于存储结构的运算实现。 通常把基于存储结构的运算实现的步骤或过程称为算法。 算法的特性:有穷性、确定性、可行性、有输入、有输出。 4.2 算法分析 4.2.1 算法时间复杂度分析 一个算法是由控制结构( 顺序 、分支和循环三种 )和原操作( 指固有数据类型的操作,如如+、-、 * 、/ 、++和 和 -- 等 ) 构

三年 Git 使用心得 & 常见问题整理

Git 流程图 Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库 配置 Git # 配置全局用户 $ git config --global user.name "用户名" $ git config --global user.email "git账号" # 配置别名 $ git config --global alias.co checkout $ git config --global alias.ss status $ git config --global alias.cm commit $ git config --global alias.br branch $ git config --global alias.rg reflog # 这里只是美化 log 的输出,实际使用时可以在 git lg 后面加命令参数,如:git lg -10 显示最近10条提交 $ git config --global alias.

wireshark找不到接口的解决办法

wireshark找不到接口的解决办法 之前更新了wireshark结果安装完一看,显示找不到接口。于是就在网上查找各种解决办法: 管理员身份进入cmd输入net start npf,然而不管怎么弄都显示服务名无效,只好放弃。重新安装wireshark之后又分别单独安装了win10pacp和npacp,最后还是安装失败。 不过今天我偶然间在网上看见一个答案说清理注册表,于是抱着试一试的心态,下载了一个ccleaner,清理完之后又重新安装一遍wireshark,令人惊叹的是npacp终于下载成功了。 安装完wireshark后,第一次要用管理员身份运行,打开wireshark,果然能找到接口。 事实证明办法总会有的,山重水复疑无路,柳暗花明又一村,说不定在某个瞬间你一下就找到了解决问题的方法。

Hive 函数大全(吐血整理)

Hive 函数大全(吐血整理) 前言关系运算1、等值比较:=2、不等值比较:<>3、小于比较:<4、小于等于比较:<=5、大于比较:>6、大于等于比较:>7、空值判断:IS NULL8、非空判断:IS NOT NULL9、LIKE 比较:LIKE10、JAVA 的 LIKE 比较:RLIKE11、正则匹配:REGEXP 数学运算1、加法操作:+2、减法操作:-3、乘法操作:*4、除法操作:/5、取余操作:%6、位与操作:&7、位或操作:|8、位异或操作:^9、按位取反操作:~ 逻辑运算1、逻辑与操作:AND2、逻辑与操作:OR3、逻辑非操作:NOT 条件运算1、IF 函数:IF2、非空查找函数:COALESCE3、条件判断函数:CASE4、条件判断函数:CASE 数值计算1、近似函数:round2、指定精度近似函数:round3、向下取整函数:floor4、向上取整函数:ceil5、向上取整函数:ceiling6、取随机函数:rand7、自然指数函数:exp8、以 10 为底的对数函数:log109、以 2 为底的对数函数:log210、对数函数:log11、幂运算函数:pow12、幂运算函数:power13、平方根函数:sqrt14、二进制函数:bin15、十六进制函数:hex16、反转十六进制函数:unhex17、进制转换函数:conv18、绝对值函数:abs19、正取余函数:pmod20、正弦函数:sin21、反正弦函数:asin22、余弦函数:cos23、反余弦函数:acos24、positive 函数:positive25、negative 函数:negative 日期函数1、UNIX 时间戳转日期函数:fom_unixtime2、获取当前 UNIX 时间戳函数:unix_timestamp3、日期转 UNIX 时间戳函数:unix_timestamp4、指定格式日期转 UNIX 时间戳函数:unix_timestamp5、日期时间转日期函数:to_date6、日期转年函数:year7、日期转月函数:month8、日期转天函数:day9、日期转小时函数:hour10、日期转分钟函数:minute11、日期转秒函数:second12、日期转周函数:weekofyear13、日期比较函数:datediff14、日期增加函数:date_add15、日期减少函数:date_sub 字符串函数1、字符串长度函数:length2、字符串反转函数:reverse3、字符串连接函数:concat4、带分隔符字符串连接函数:concat_ws5、字符串截取函数:substr | substring6、字符串截取函数:substr | substring7、字符串转大写函数:upper | ucase8、字符串转小写函数:lower | lcase9、去空格函数:trim10、左边去空格函数:ltrim11、右边去空格函数:rtrim12、正则表达式替换函数:regexp_replace13、正则表达式解析函数:regexp_extract14、URL 解析函数:parse_url15、JSON 解析函数:get_json_object16、空字符串函数:space17、重复字符串函数:repeat18、首字符 ASCII 函数:ascii19、左补足函数:lpad20、右补足函数:rpad21、分割字符串函数:split22、集合查找函数:find_in_set 聚合函数1、统计函数:count2、求和函数:sum3、平均值函数:avg4、最小值函数:min5、最大值函数:max6、总体方差函数:var_pop7、样本方差函数:var_samp8、总体标准差函数:stddev_pop9、样本标准差函数:stddev_samp10、百分位函数:percentile11、百分位函数:percentile12、近似百分位函数:percentile_approx13、近似百分位函数:percentile_approx14、直方图:histogram_numeric 前言 Hive 内部提供了很多函数给开发者使用,包括数学函数,类型转换函数,条件函数,字符函数,聚合函数,表生成函数等等,这些函数都统称为内置函数。 在 hive 中可通过以下命令查看函数信息: --显示所有的可用函数,包括运算符、内置函数、自定义函数 show functions; --显示指定函数的描述信息 desc function trim; --显示指定函数的详细信息 desc function extended trim; 关系运算 1、等值比较:= 语法:A = B 操作类型:基本类型 描述:如果表达式 A 与表达式 B 相等,则为 TRUE;否则为 FALSE。

STM32CubeMX学习笔记五 《GPIO 外部中断》

前言 废话: 黑曼巴、新冠疫情反复、中印冲突国内经济民生都受到相应的影响,这个2020注定不平凡啊!不管怎样,我们都要以积极的心态去生活,“阳光怎在风雨后”。来吧学习吧!这个歌词暴露年龄了 haha。 前面我们已经初步学习了STM32CubeMX软件怎样去建立工程及配置GPIO的输入输出,到目前相信对软件的使用方法已经相对熟悉了很多,最起码知道该去做什么。本节我们继续学习用STM32CubeMX软件去配置GPIO的外部中断这个功能,下一节看看串口的配置方法。 本博主使用的STM32F7这款芯片,正好上次项目中用到了就顺手用它来复习一下STM32CubeMX的配置方法。芯片不重要方法很重要。 外部中断简介: STM32F7 的每个 IO 都可以作为外部中断的中断输入口(除去电源和GND等特殊的IO), STM32F7 的中断控制器支持 22 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F7的 23 个外部中断为: EXTI 线 0~15:对应外部 IO 口的输入中断。 EXTI 线 16:连接到 PVD 输出。 EXTI 线 17:连接到 RTC 闹钟事件。 EXTI 线 18:连接到 USB OTG FS 唤醒事件。 EXTI 线 19:连接到以太网唤醒事件。 EXTI 线 20:连接到 USB OTG HS(在 FS 中配置)唤醒事件。 EXTI 线 21:连接到 RTC 入侵和时间戳事件。 EXTI 线 22:连接到 RTC 唤醒事件。 EXTI 线 23:连接到 LPTIM1 异步事件。 本节通过STM32F7这款芯片外部 IO 口的中断功能,通过中断的功能,实现上一节中按键控制LED灯的亮灭。

面试官问:你熟悉哪些HashMap的封装扩展类?

我习惯了无所谓,却不是真的什么都不在乎。 请关注:源码猎人 目录 简介 LinkedHashMap 源码解读 LinkedHashMap属性 LinkedHashMap构造函数 LinkedHashMap 方法 LinkedHashMap 内部类 LinkedHashMap.Entry,v> HashSet 类源码解读 HashSet 属性 HashSet 构造函数 HashSet 方法 LinkedHashSet 类源码解读 LinkedHashSet 构造函数 常见面试题 简介 LinkedHashMap、HashSet、LinkedHashSet都扩展了HashMap。它们是HashMap的二次封装,LinkedHashMap加入了一个单独链表存所有数据,并且完整保留HashMap结构。 HashSet 实际上只用到了HashMap的键,值为常量;LinkedHashSet 继承HashSet,并且和LinkedHashMap一样内部维护一个链表。 LinkedHashMap 源码解读 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> LinkedHashMap属性 // 链表头结点 transient LinkedHashMap.Entry<K,V> head; // 链表尾结点 transient LinkedHashMap.Entry<K,V> tail; // LRU算法相关 false 基于插入顺序,true 基于访问顺序 final boolean accessOrder; LinkedHashMap构造函数 public LinkedHashMap(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); // 默认使用插入顺序 accessOrder = false; } public LinkedHashMap(int initialCapacity) { super(initialCapacity); // 默认使用插入顺序 accessOrder = false; } public LinkedHashMap() { super(); // 默认使用插入顺序 accessOrder = false; } public LinkedHashMap(Map<?

习题8-5 使用函数实现字符串部分复制 (20分)

一、需求 本题要求编写函数,将输入字符串t中从第m个字符开始的全部字符复制到字符串s中。函数接口定义如下 void strmcpy( char *t, int m, char *s ); 函数strmcpy将输入字符串char *t中从第m个字符开始的全部字符复制到字符串char *s中。若m超过输入字符串的长度,则结果字符串应为空串。 二、裁判程序样例 #include <stdio.h> #define MAXN 20 void strmcpy( char *t, int m, char *s ); void ReadString( char s[] ); /* 由裁判实现,略去不表 */ int main() { char t[MAXN], s[MAXN]; int m; scanf("%d\n", &m); ReadString(t); strmcpy( t, m, s ); printf("%s\n", s); return 0; } /* 你的代码将被嵌在这里 */ 三、测试样例 输入样例 7 happy new year 输出样例 new year 四、代码实现 void strmcpy( char *t, int m, char *s ) { int len = strlen(t); char *p = t + m -1; if(m > len) { *s = NULL; } while(*p !

海康sdk-MFC包编译+生成详解

文章流程:下载vs2013 ->海康SDK->vs2013编译海康SDK成功->完毕 必要工具: 海康sdk,地址:海康官网下载地址 vs2013编译环境:推荐下载vs2013IDE 地址:vs2013旗舰 补丁: vs2013MFC多字节地址:2013MFC多字节下载地址 编译海康SDK 可以先什么都不配置的,生成一下,出现错误可以看下报错信息 - 如果出现const char 无法转换LPCSTR,则选择项目属性 - 常规-字符集,改为多字节字符集。 - 报如提示:错误 MSB8031 Building an MFC project for a non-Unicode character set is deprecated. You must change the project property to Unicode or download an additional library. See http://go.microsoft.com/fwlink/p/?LinkId=286820 for more information. PlayBack C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets 376错误,下载MFC多字节补丁即可编译成功过,运行出现缺少HCNetSDK.dll,则根据HCNetSDKCom.txt配置工程 运行 有问题大家可以交流!!!

【ECharts】使用vue-echarts数据实时更新导致dataZoom(数据缩放)被重置问题

前情提要 在使用vue-echarts进行可进行数据缩放的图表的渲染,并且图表数据是实时更新的。每一次更新都会刷新图表,导致用户选择的缩放范围在更新后被重置。 基于此,希望在刷新图表数据时,能够保持缩放范围。 实现过程 1. 基本思想 监听图表的dataZoom(缩放)事件,记录缩放后的start和end(缩放范围)。在刷新图表前,将上述记录的缩放范围设置到option中dataZoom的start和end值。 2. 具体实现 1)设置事件监听 <Echarts :style="{ height: height + 'px' }" :options="options" :auto-resize="true" @datazoom="onDataZoom" /> 2)缩放事件发生时执行的方法,主要实现缩放范围的保存 onDataZoom (event) { if (event.batch) { // 在图表内使用鼠标滚轮缩放 this.dataZoom = { start: event.batch[0].start, end: event.batch[0].end } } else { // 使用滑块缩放 this.dataZoom = { start: event.start, end: event.end } } } 3)更新数据后执行mergeOptions(options);chart.resize();之前,作用实现将上述缩放范围设置到当前option的dataZoom中 if (options.dataZoom && this.dataZoom) { options.dataZoom[0].start = this.dataZoom.start; options.dataZoom[0].end = this.dataZoom.end; options.dataZoom[1].start = this.dataZoom.start; options.dataZoom[1].end = this.

elasticsearch启动报错mapper [logoUri] of different type, current_type [....

elasticSearch启动时报错: Caused by: java.lang.IllegalArgumentException: mapper [logoUri] of different type, current_type [text], merged_type [keyword] 原因: 代码中的document映射实体中的logoUri字段类型为keyword,而索引库中的类型为text 解决办法: 进入索引库(可以使用kibana等工具进入),修改logoUri字段类型为keyword,再重新导入数据就可以了

Springboot代码修改后,不需重新运行即可生效,使用Springloaded进行热部署

spring-boot使用Springloaded进行热部署 在开发Java程序的时候,修改代码了就需要重启一下应用,这样肯定会导致开发效率低。 比较大的项目,要重启一下应用,要花费 5、6 分钟,灵感泉涌的时候,怎么能忍受得了。 spring为我们提供了一个免费好用的jar包–springloaded 依赖: <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.6.RELEASE</version> </dependency> 在spring-boot开发时我们一般使用spring-boot-maven-plugin pox.xml部分配置如下: <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <executable>true</executable> </configuration> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.6.RELEASE</version> </dependency> </dependencies> </plugin> 修改完项目代码后 重新编译 看弹出的提示框显示的提示即可:蓝色就是重新编译加载成功,红色则失败需要手动重启dubug 在方法的参数修改 和 类属性修改后,重新编译会失败,还需要重启项目。

Android studio调用手机相机拍照显示并保存+读取本地相册并显示

移植深度学习训练好的模型,第一步是可以使用安卓手机的相机进行拍照或者访问相册进行图片选择。第二步,调用模型,进行结果显示。现在记录第一步的代码实现。 我的界面有三个,第一个是MainActivity,第二个是Camera拍照的显示,第三个是Albums的显示。 结构介绍 1.activity_main.xml和MainActivity.java介绍1.1.activity_main.xml代码1.2.MainActivity.java代码及介绍 2.albums.xml和Albums.java介绍以及添加方法介绍2.1.albums.xml代码介绍和添加方法2.2.Albums.java代码介绍和添加方法 3.camera.xml和Camera.java代码介绍及添加方法3.1.camera.xml的添加方法和代码3.2.Camera.java的添加方法和代码 4.在AndroidManifest.xml中添加注册4.1.注册除了MainActivity的其他两个界面,添加provider4.2.申请使用相机的权限,读写 5.添加图片保存的xml路径,添加方法和内容点击运行,可以在虚拟设备上运行了运行或安装的问题总结续上次的程序总结 1.activity_main.xml和MainActivity.java介绍 1.1.activity_main.xml代码 首先是activity_main.xml,主要有3个控件,但是第三个ImageView控件这里没有使用,界面图下图所示 详细代码如下 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/take_photo" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="拍照" android:textSize="20dp" /> <Button android:id="@+id/choose_from_album" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="相册" android:layout_below="@+id/take_photo" android:textSize="20dp" /> <ImageView android:id="@+id/picture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_below="@+id/choose_from_album" android:layout_marginTop="20dp" /> </RelativeLayout> 1.2.MainActivity.java代码及介绍 MainActivity.java代码如下所示:我的主界面主要功能比较简单,就是在拍照和相册按钮中添加响应,然后跳转到相应的显示界面 package com.example.mycamera; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.

分享2020版详细搭建IPTV服务器教程

IPTV系统服务器搭建,首先要保证自己动一些计算机技术,在处理中能对一些简单的事情进行处理,如果是计算机一点不了解的话,处理起来难度还是有的。先说说目前了解到的搭建IPTV服务器的方法。 如果是想自己建设一套可运营的IPTV电视直播系统,而自己也没有技术团队的话,比较好的方式是找第三方团队,一个是经验丰富,再就是IPTV电视直播系统进过市场检验,系统的稳定性和功能更齐全些。一般搭建IPTV服务器,肯定得有一台 服务器,至于服务器的性能,要看电视直播频道数的多少以及是否需要回看、时移等功能需要保留多少数据。也要看直播源的情况,如果IPTV系统服务器的作用仅仅是管理用户,而不需要做直播流的中转分发的话,要求并不高。如果需要做中转的话,可能考虑的要多了。IPTV系统软件公司在这方面的优势就有充分体现了,点量可以根据具体的情况,给出合理化的建议,以及需要购买的服务器参数,直接去相应官网购买即可。 对于运营方来说,搭建教程再好都是为了IPTV电视直播系统让用户有良好的体验。那么在搭建IPTV电视直播系统的时候应该注意哪些问题呢? 1、 视频观看的流畅度,直播秒切台 对于IPTV电视直播系统来说,观看直播是很重要的一环,而直播在观看中对用户来说,流畅度是很重要的,此外在保证流畅的基础上如果能做到低延时就会更好,因为对体育比赛等类型的节目对实时性要求还是很高的,这种的话需要在推流方面做好技术衔接,尽量做到2秒内的延时,这种效果还是很好的。 2、 点播界面功能的操作便利性 点播界面操作便利,比如不同的分类可自己编辑,可通过标签等推荐相关影片。对于单个影片的介绍、导演、简介、选集这些就更多了,可以从多种方式中选择一种喜欢的。目前点播的界面虽然大的方面不同,但小的操作方面还是有很大不同。比如选集,和介绍是在同一个页面,还是单独一个选集的操作,再就是对于像美剧、综艺这种有很多季,每季有不同的集数这种该怎么处理等。 3、 技术团队实力和经验 技术团队的实力,可以从以下几个方面考虑,一个是团队人员的组成,比如后台开发人员涵盖的语言、安卓开发人员和iOS开发人员,甚至有些其他的系统比如Roku人员这些都是考察的一些方面。再就是这些人员的专注于IPTV电视直播领域的时间和经验丰富度。相对来说时间越长、案例越多,对于一些问题的处理越有经验。 侧面来说考察公司的团队实力,可以看下合作的公司和案例,再就是在相关领域的产品体系。比如在IPTV电视直播系统相关的视频加密、视频传输和播放是否有涉及,比如P2P、流加密帧加密这些。 4、 系统的可扩展性 这个对于有多期功能规划的项目是比较重要的,因为比如应用在学校或者酒店行业,会有扩展性的功能,是之前没有涉及的,比如直播活动、酒店服务等。所以系统的可扩展性要好一些。

net start mysql无法启动mysql,发生系统错误1067

排查流程 net start mysql无法启动mysql,发生系统错误1067 查看事件日志提示:Table '.\mysql\user' is marked as crashed and should be repaired。 user表索引文件损坏 解决办法 找到mysql的安装目录的bin/myisamchk工具,在命令行中输入: myisamchk -c -r ../data/mysql/user.MYI #修复mysql user表索引 参考文章: [MySQL]快速解决"is marked as crashed and should be repaired"故障

如何找回微信小程序源码?2020年微信小程序反编译最新教程

前言:在网上看了找回微信小程序源码很多教程,都没法正常使用。微信版本升级后,会遇到各种报错, 以及无法获取到wxss的问题。查阅各种资料,最终解决,于是贴上完整的微信小程序反编译方案与教程。 本文章仅作学习使用。 微信小程序反编译截图1 微信小程序反编译截图2 ------ 常见的微信小程序反编译失败问题 ----- 1 获取不到Wxss 2 遇见分包,无法反编译。 3 apkg反编译报错。 ( 目前都已解决) 一 准备工具 1 node.js 运行环境 如果没有安装nodejs,请先安装一下 下载地址:https://nodejs.org/en/ 2.反编译的脚本 在网上找的大神写的node.js版本的 地址:https://github.com/qwerty472123/wxappUnpacker 3 夜神模拟器 需要安装微信和QQ 地址:https://www.yeshen.com/cn/download/fullPackage 接下来正式开始反编译 1 获取小程序pkg包: 在模拟器中登录微信,随便打开一个小程序A 打开文件管理器,找到/data/data/com.tencent.mm/MicroMsg 目录 ,然后找到一个很长的用户随机码, 继续找到/appbrand/pkg/xxx,接下来会出现小程序A的wxapkg包 2 压缩apkg包,然后长按发送到QQ,微信暂不支持发送。。 3 到此我们获取到了小程序的包 ,打开node.js , 路径切换到我们下载的反编译脚本的目录,如图 提示: ( 路径不要包含中文名称,否则反编译时可能因编码不对 造成异常 ) 4 切换到反编译脚本的目录后 ,在node命令窗口中依次安装以下依赖: npm install esprima npm install css-tree npm install cssbeautify npm install vm2 npm install uglify-es npm install js-beautify

【MySQL 必知必会 聚簇索引与非聚簇索引 (一看就会)】

文章目录 什么是索引索引的作用聚簇索引与非聚簇索引误区:把主键自动设置为聚簇索引图文解释聚簇索引的优势聚簇索引的劣势为什么主键通常建议使用自增id覆盖索引 什么是索引 在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单,简单来说,索引就是一种快速查询和检索数据的数据结构,就像是图书的目录,根据目录快速查找到所需内容。 索引的作用 保证数据的准确性( 唯一的索引值对应着唯一的数据。)加快检索速度(索引可以极大加快检索速度。)提高系统性能 聚簇索引与非聚簇索引 聚簇索引:将数据存储与索引放到了叶子节点,找到索引也就找到了数据 非聚簇索引:将数据存储与索引结构分开存放,索引结构的叶子节点存有指向对应数据块的指针,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因 澄清一个概念:innodb中,在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引,辅助索引叶子节点存储的不再是行的物理位置,而是主键值 由于聚簇索引是将数据跟索引结构放到一块,因此一个表仅有一个聚簇索引 误区:把主键自动设置为聚簇索引 聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一的非空索引代替。如果没有这样的索引,InnoDB 会隐式定义一个主键来作为聚簇索引。InnoDB 只聚集在同一个页面中的记录。包含相邻健值的页面可能相距甚远。如果你已经设置了主键为聚簇索引,必须先删除主键,然后添加我们想要的聚簇索引,最后恢复设置主键即可。 此时其他索引只能被定义为非聚簇索引。这个是最大的误区。有的主键还是无意义的自动增量字段,那样的话Clustered index对效率的帮助,完全被浪费了。 刚才说到了,聚簇索引性能最好而且具有唯一性,所以非常珍贵,必须慎重设置。一般要根据这个表最常用的SQL查询方式来进行选择,某个字段作为聚簇索引,或组合聚簇索引,这个要看实际情况。 图文解释 1.InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。 2.若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。(重点在于通过其他键需要建立辅助索引) 3.MyISM使用的是非聚簇索引,非聚簇索引的两棵B+树看上去没什么不同,节点的结构完全一致只是存储的内容不同而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来说,这两个键没有任何差别。由于索引树是独立的,通过辅助键检索无需访问主键的索引树。 聚簇索引的优势 看上去聚簇索引的效率明显要低于非聚簇索引,因为每次使用辅助索引检索都要经过两次B+树查找,这不是多此一举吗?聚簇索引的优势在哪 1.由于行数据和叶子节点存储在一起,同一页中会有多条行数据,访问同一数据页不同行记录时,已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。这样主键和行数据是一起被载入内存的,找到叶子节点就可以立刻将行数据返回了,如果按照主键Id来组织数据,获得数据更快 2.辅助索引使用主键作为"指针"而不是使用地址值作为指针的好处是,减少了当出现行移动或者数据页分裂时辅助索引的维护工作,使用主键值当作指针会让辅助索引占用更多的空间,换来的好处是InnoDB在移动行时无须更新辅助索引中的这个"指针"。也就是说行的位置(实现中通过16K的Page来定位)会随着数据库里数据的修改而发生变化(前面的B+树节点分裂以及Page的分裂),使用聚簇索引就可以保证不管这个主键B+树的节点如何变化,辅助索引树都不受影响。 3.聚簇索引适合用在排序的场合,非聚簇索引不适合 4.取出一定范围数据的时候,使用用聚簇索引 5.二级索引需要两次索引查找,而不是一次才能取到数据,因为存储引擎第一次需要通过二级索引找到索引的叶子节点,从而找到数据的主键,然后在聚簇索引中用主键再次查找索引,再找到数据 6.可以把相关数据保存在一起。例如实现电子邮箱时,可以根据用户 ID 来聚集数据,这样只需要从磁盘读取少数的数据页就能获取某个用户的全部邮件。如果没有使用聚簇索引,则每封邮件都可能导致一次磁盘 I/O 聚簇索引的劣势 1.维护索引很昂贵,特别是插入新行或者主键被更新导至要分页(page split)的时候。建议在大量插入新行后,选在负载较低的时间段,通过OPTIMIZE TABLE优化表,因为必须被移动的行数据可能造成碎片。使用独享表空间可以弱化碎片 2.表因为使用UUId(随机ID)作为主键,使数据存储稀疏,这就会出现聚簇索引有可能有比全表扫面更慢,所以建议使用int的auto_increment作为主键,主键的值是顺序的,所以 InnoDB 把每一条记录都存储在上一条记录的后面。当达到页的最大填充因子时(InnoDB 默认的最大填充因子是页大小的 15/16,留出部分空间用于以后修改),下一条记录就会写入新的页中。一旦数据按照这种顺序的方式加载,主键页就会近似于被顺序的记录填满(二级索引页可能是不一样的 3.如果主键比较大的话,那辅助索引将会变的更大,因为辅助索引的叶子存储的是主键值;过长的主键值,会导致非叶子节点占用占用更多的物理空间。 为什么主键通常建议使用自增id 聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。如果主键不是自增id,那么可以想 象,它会干些什么,不断地调整数据的物理地址、分页,当然也有其他一些措施来减少这些操作,但却无法彻底避免。但,如果是自增的,那就简单了,它只需要一 页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高 因为MyISAM的主索引并非聚簇索引,那么他的数据的物理地址必然是凌乱的,拿到这些物理地址,按照合适的算法进行I/O读取,于是开始不停的寻道不停的旋转。聚簇索引则只需一次I/O。(强烈的对比) 不过,如果涉及到大数据量的排序、全表扫描、count之类的操作的话,还是MyISAM占优势些,因为索引所占空间小,这些操作是需要在内存中完成的。 覆盖索引 我们知道在InnoDB存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值。最终还是要“回表”,也就是要通过主键再查找一次; 覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了, 而无需回表查询 如普通索引,如果一条SQL需要查询name,name字段正好有索引, 那么直接根据这个索引就可以查到数据,也无需回表。

数据质量评估标准与数据质量规则梳理

做过大数据的伙伴应该都清楚,数据的质量是直接影响着数据的价值,并且直接影响着数据分析的结果以及我们以此做出的决策的质量。质量不高的数据不仅仅是数据本身的问题,还会影响着企业经营管理决策;错误的数据还不如没有数据,因为没有数据时,我们还会基于经验和基于常识的判断来做出不见得是错误的决策,而错误的数据会引导我们做出错误的决策。因此数据质量是企业经营管理数据治理的关键所在。 而最近我们在所进行的数据治理项目的过程中就对数据质量标准和质量规则进行了梳理,数据的质量是从六个维度进行衡量,每个维度都从一个侧面来反映数据的品相。 根据检验复杂的程度由低到高,这六个维度分别是:完整性、及时性、唯一性、一致性、规范性和准确性。 那么,相应的每一个检核维度又可以参考以下的质量规则来对数据进行校核: 完整性 空值或者无效:检查字段是否为空;检查数值是否为0记录数异常:检查源表和目标表的记录条数是否一致 及时性 时间切片缺失:检查是否有缺失日期数据 唯一性 存在冗余:检查是否有重复数据(技术主键和业务主键) 一致性 映射异常:源表和目标表中直接映射的字段值相同无法关联:检查外键是否正确违反交叉验证规则:数值交叉校验规则和特定值交叉校验规则 规范性 违反码值规范:值域约束——代码表值域约束违反格式规范:日期格式是否正确;利用通用格式规则对字段进行检核,如身份证 准确性 值域异常:值域约束(指定有业务含义的数值值域和文本值域)时序波动异常:单一维度分布稳定性校验(维度/度量);环比数据相比正常 最终,在根据实际的业务情况对数据质量规则进行梳理完成之后,就可以输出一个数据质量校核规则梳理的文件(可以是Excel格式)。

C++ ——学生成绩管理系统

一、实验目的 (1) 加深对C++语法、基础知识和编程技巧的运用,编写具有一定综合应用价值程序。 (2) 熟悉掌握C++的语法和面向对象程序设计方法。进一步理解和运用结构化和面向对象程设计想结合的思想和方法。 (3) 掌握函数的定义方法,掌握利用单继承和多继承的方式定义派生类的方法。 (4) 学会利用流程图或N-S图表示算法。 (5) 理解在各种继承方式下构造函数和析构函数的执行顺序。 二、环境 1、 安装windows XP或者以上版本的操作系统 2、 安装visual c++ 6.0或者visual studio 2017 三、正文 (一)分析 设计一个简易的学生成绩管理系统,能够完成学生成绩的增加、删除、查找、修改、统计等操作,数据信息使用文件保存。要求系统具有菜单和提示。 (二)设计 1、设计程序功能 学生成绩系统中学生的成绩信息按照学号的顺序进行排序。根据任务要求,下面将系统进行详细划分,功能结构如下图所示。 成绩的增加:通过键盘输入学生成绩信息并将其添加到学生成绩信息记录中,按照要求学号顺序插入。 成绩的删除:根据学生的学号从学生成绩信息记录中删除该学生的成绩信息。 成绩的查询:可以根据学生的学号和姓名查询学生的成绩信息,也可以根据某一门成绩的分数段查询学生成绩信息。 成绩的修改:根据学生的学号修改相应学生的成绩信息。 成绩的输出:将所有学生成绩信息输出。 成绩的统计:统计每门课程的及格人数显示不及格学生的信息,统计三门课程成绩全为优秀的学生人数,显示三门课程成绩全不及格的学生信息。 保存数据:利用文件操作将链表中学生成绩信息保存到文件中。 加载数据:利用文件操作从文件中读取学生成绩信息,形成学生记录的链表。 2、设计数据格式 要完成学生成绩信息的增删改查及统计,首先设计一下内存中存放数据信息的格式。在本设计中采用动态内存空间分配的链表方法,该方法为一个结构分配内存空间。每一次分配一块内存空间可用来存放一个学生成绩的数据,可称之为一个结点。有多少个学生就应该分配多少块内存空间,也就是说建立多少个结点。当然用结构数组也可以完成上述操作,但如果不能预先把握学生人数,也就无法确定数组大小。而且当学生留级、退学之后也不能把该元素占用的内存空间释放出来。 用动态存储的方法可以很好地解决这些问题。有一个学生就分配一个结点,无需预先确定学生的准确人数,某学生退学,可删去该结点,并释放该结点所占用的内存空间,从而节约了内存资源。另一方面,用数组的方法必须占用一块连续的内存区域。而使用动态分配时,每个结点之间可以是不连续的(结点内是连续的)。结点之间的联系可以在结点结构中定义一个指针项用来存放下一个结点的首地址。 可在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存入第三个结点的首地址,如此串连下去直到最后一个结点的指针域为空。 3、设计结点的组成 结点是一个结构体类型,由两部分组成,第一部分是数据部分,在该系统中用来存放学生的学号、姓名、数学成绩、英语成绩、计算机基础成绩、和三门成绩的总分;第二部分定义了一个结构体指针变量,该指针爆开用来存放下一个结点的地址,如下图所示。 定义存放学生成绩结点信息的语句如下: struct score { int num; //学号 string name; //姓名 float math; //数学成绩 float computer; //计算机基础成绩 float scoresum; //三门成绩总和 struct score * next; //next为指向下一结点的指针 } ; 一个个结点就通过next指针连接起来形成了单向链表的结构,如下图所示。head为指向链表的首结点。 4、程序设计与实现

【UEFI实战】网络启动

简述 UEFI下实现了若干中网络启动的方式,比如HTTP启动,PXE启动等。对应的默认如下: !if $(PXE_ENABLE) == TRUE NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf !endif !if $(HTTP_BOOT_ENABLE) == TRUE NetworkPkg/DnsDxe/DnsDxe.inf NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf NetworkPkg/HttpDxe/HttpDxe.inf NetworkPkg/HttpBootDxe/HttpBootDxe.inf !endif 从它们的宏定义就可以看出来具体HTTP启动和PXE启动对应哪些代码。下面分别介绍这两种网络启动方式。 PXE启动 PXE网路启动是一种比较老的网路启动方式,在PXE简介及使用说明有介绍具体的使用方式,而这里主要介绍它的实现。首先查看NetworkPkg\UefiPxeBcDxe\UefiPxeBcDxe.inf文件,从这里可以看到它实际上实现了两个Protocol用于包装整个PXE的动作: [Protocols] ## TO_START ## SOMETIMES_CONSUMES gEfiDevicePathProtocolGuid gEfiNetworkInterfaceIdentifierProtocolGuid_31 ## SOMETIMES_CONSUMES gEfiArpServiceBindingProtocolGuid ## TO_START gEfiArpProtocolGuid ## TO_START gEfiIp4ServiceBindingProtocolGuid ## TO_START gEfiIp4ProtocolGuid ## TO_START gEfiIp4Config2ProtocolGuid ## TO_START gEfiIp6ServiceBindingProtocolGuid ## TO_START gEfiIp6ProtocolGuid ## TO_START gEfiIp6ConfigProtocolGuid ## TO_START gEfiUdp4ServiceBindingProtocolGuid ## TO_START gEfiUdp4ProtocolGuid ## TO_START gEfiMtftp4ServiceBindingProtocolGuid ## TO_START gEfiMtftp4ProtocolGuid ## TO_START gEfiDhcp4ServiceBindingProtocolGuid ## TO_START gEfiDhcp4ProtocolGuid ## TO_START gEfiUdp6ServiceBindingProtocolGuid ## TO_START gEfiUdp6ProtocolGuid ## TO_START gEfiMtftp6ServiceBindingProtocolGuid ## TO_START gEfiMtftp6ProtocolGuid ## TO_START gEfiDhcp6ServiceBindingProtocolGuid ## TO_START gEfiDhcp6ProtocolGuid ## TO_START gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES gEfiPxeBaseCodeCallbackProtocolGuid ## SOMETIMES_PRODUCES gEfiPxeBaseCodeProtocolGuid ## BY_START gEfiLoadFileProtocolGuid ## BY_START gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES 这里的BY_START表示的是生成Protocol,可以直接在NetworkPkg\UefiPxeBcDxe\PxeBcDriver.

初见Python解题之道(一)

Item ISO日期转化成美式英语日期 Knowledge 数据类型:浮点数(float)、整数(int)、字符串(str)、类型转换基本运算符:比较运算符、算术运算符、隶属运算符IF语句:内嵌、else、elif容器(个人想法):变量存储、元组(list)、列表(tuple)其他:del语句、input函数英语:高中毕业一年了,啥都忘了,倒是给我复习了一下序数词和月份单词,hhh~~ Me 以前接触过一点点Python,这是我学习的第一门编程语言,我记得去接触时还是因为看了某位博主爬取学堂在线习题答案的文章,然后自己琢磨了大半天,写了一份爬取雨课堂习题的py,就已经被这门语言征服了,初学Python,首次买书、看书、做练习、自己设计运行方式,然后发博客,心里有种说不出的快乐和愉悦,Python的神奇功能真的让我着迷,我想把自己学习中每一次的快乐记录在CSDN中,请各位大佬多多指教,加油,奥里给! Code # 年 Year = input('请输入年数字:') Year_num = int(Year) # 月 Mon = input('请输入月数字(1-12):') Mon_num = int(Mon) months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] Mon_s = months[Mon_num-1] # 日 days = ['st', 'nd', 'rd'] + 17*['th'] + ['st', 'nd', 'rd'] + 7*['th'] + ['st'] # 处理算法:闰年问题、大月小月问题、2月28|29问题 if Year_num % 4 == 0: if Mon_num == 2: Day = input('请输入日数字(1-29):') del days[29:] else: if Mon_num == 2: Day = input('请输入日数字(1-28):') del days[28:] if Mon_num in (4, 6, 9, 11): Day = input('请输入日数字(1-30):') del days[30] elif Mon_num in (1, 3, 5, 7, 8, 10, 12): Day = input('请输入日数字(1-31):') Day_s = Day + days[int(Day) - 1] # 结果输出 print(Mon_s + ' ' + Day_s + ',' + Year)

创新者的窘境

跨越速运作为物流行业的后来者,从零起家,以极其有限的资源,在成熟的物流市场中稳扎稳打成为行业独角兽。从巨头的盲区寻找需求,抓住巨头不管的企业物流快递需求;从巨头的反面定义产品,快速占领巨头没有占领的服务认知;从巨头的反面简化流程,节约成本;连接巨头没有团结的合作伙伴,有效利用航空公司客机副舱、货拉拉等合作伙伴的空闲资源。作为后来者一路逆袭,弥补自己的短板,在强手林立的行业格局里突围。 跨越速运的成功与《创新者的窘境》一书中描述的行业破坏性创新非常相似,站在行业的巨头角度思考,那些管理良好的企业,在行业的延续性创新中始终保持着市场领先。延续性产品既能满足消费者需求,并针对大型市场获得维持增长所必须的销售额和利润。这种延续性投资的风险非常小,因为消费者是现成的,消费者的需求也是已知的。这些巨头的高层管理人员为了维护自身和企业的利益一般都会选择支持市场需求看起来有保障的项目。 破坏性产品通常是在成熟企业先发现市场机会,但市场营销人员通常会根据已有客户市场对新兴市场做出悲观的销售预测,理性公司的高层管理人员通常也会将这些需求不明确、利润率更低的提案束之高阁。为了开发破坏性产品结构,通常在成熟企业不得志的员工会创建新企业,这些企业通常并不能为主流市场消费者提供更好的产品,而是提供更加垂直、单一的产品,预期利润率也会更低。新兴企业逐步在市场站稳脚跟后,会继续发展破坏性产品,使其产品逐步满足客户的其他需求,使产品从小众变为主流,从而入侵到高端市场。虽然成熟企业能够通过产品补位维护自己的市场地位,但新兴企业已经在成本和设计经验上建立了不可逾越的优势,这些成熟企业很难在新兴市场占据有利地位。 因此成熟企业要长期领导市场,需要重视破坏性产品属性的新市场,成立新的企业独立运作,避开主流机构流程和价值观,建立一套不同的企业运作方式。

什么是自动化运维?自动化运维必备技能有哪些?

万丈高楼平地起,高楼稳不稳取决于地基是否扎实。基础数据便是运维管理这座高楼的地基。 首先介绍一下我们在运维管理中所涉及到的基础数据有哪一些。请看下图: 基础数据大致分为CMDB、日志、生产DB、知识库四个模块。 一、基础数据概况 CMDB中文是配置管理数据库,存储与管理企业IT架构中设备的各种配置信息,与未来的IT运维管理标准化和流程化紧密关联,并且支持流程的运转。运维管理平台创建初期或初版中的CMDB更多是偏向IT资产管理,我们在这里定义的IT资产管理,暂时抛除公司个人使用的普通PC机。 日志主要存储CMDB中涉及到服务器或是其它设备的日志信息。 DB主要是所有IT系统的数据库信息,包括运维管理系统本身的数据库。由于数据库的重要性,所以在基础数据中单独一个模块管理数据库,包括生产数据库、测试数据库、开发数据库。数据库的日志放在日志模块进行统一管理,监控和备份。 知识库主要存储日常运维管理中发生的事件、问题以及一些经典问题的解决和常用的解决方案,主要起到运维管理辅助的功能。 二、基础数据三要素 基础数据要求完整、准确、实时,这三个特性缺一不可。 1.完整性 完整性,要求在数据采集整理阶段,要一一梳理,不能有遗漏。任何一个设备的疏漏都将会导致未来出现问题。例如最近的勒索病毒在防范上需要给服务器升级打补丁,这个时候就是根据服务器清单一一对照,升级。如果有遗漏落下的服务器未及时打补丁而导致病毒入侵,后果将很严重。那么,如何做到完整性呢?大致可以分为以下几步: 首先数据采集阶段多人(推荐三人以上)同时对IT资产进行采集,那么在数据采集完成后,将会有三份或以上的IT资产清单。 接下来就是相互确认阶段。相互check对比两方的清单和自己梳理的清单,找到不一样的地方,大家在一起开会进行讨论。经过这个阶段,会产生一份相对完整且三方(或以上)认可的IT资产清单。 最后就是三方(或以上)一同针对认可的IT资产清单进行最终check,确保最后的清单,是经过多方讨论确认,并最终又check过的IT资产清单。此时这份IT资产清单,相对比较完整。另外在梳理、讨论和check的过程中,针对新增、变更、删除的IT资产一定要及时更新我们的IT资产清单。 2.准确性 准确性要求IT资产清单或是CMDB中存储的数据不能与实际情况有任何差异。要做到基础数据的准确性除了在数据采集阶段要下功夫外,要在运维管理的每一个阶段定期对基础数据进行审计,确保基础数据中的数据无误。一般月度一小审,半年一大审,具体情况根据企业的IT规模而定。 3.实时性 基础数据的实时性可以确保数据的准确性。即基础数据的每一次变动,包括增加、删除、修改,不论大小,只要有变动(在运维流程完结阶段,执行运维操作成功后,就要及时更新基础数据。忽略基础数据的实时性,必将导致准确性大打折扣,在以后的月审、年审中必将导致额外的工作量。一般在审计的过程中,当数据的错误率达到一定程度后,需要重新梳理全部数据,以确保最终的准确和完整。 三、CMDB CMDB总的来说分为:产品线、资产管理、供应商管理三个部分。总的思路是:通过产品线管理IT资产,通过IT资产信息管理硬件或服务提供者,供应商管理。 1.产品线 产品线是指整个公司所有IT系统、产品按照属性进行归类划分。这有一个前提,就是梳理整个公司的IT项目和IT服务。这里项目也可以理解为每一套IT系统,例如OA、CRM、订单系统、支付系统等等。 IT服务主要是指:应用服务(Tomcat、WebLogic、数据库服务等),基础IT服务如Nginx、Varnish、Redis等。通过项目和服务两个维度来管理IT资产,尤其是虚拟机。因为一般系统和服务都是部署在虚拟机上,虚拟机的宿主机则是一台台物理主机。 产品线的划分一般除了根据业务分类划分几个大的产品线外,还需要划分一些基础产品线,如:信息安全产品线,主要管理信息安全、网络安全等系统和设备等;基础服务产品线,如Nginx反向代理大部分系统,Varnish缓存Web静态资源等。 在这里单独说一下产品线和项目包括的服务必须制定运维优先级等级。运维等级的制定不能简单定义为多少级,而应该是为每一套系统进行运维优先级打分,分值不能一样。这样保证在大面积故障的时候,可以根据优先级解决问题。 2.资产管理 资产管理主要有以下几个方面。首先是比较大的机房管理。有的企业可能会有多个机房,每个机房的基础信息,如带宽、位置、值班电话等都需要加以整理存储用来管理机房信息。机房中的机架、机柜、交换机、路由器等硬件信息,机房的空调、UPS电源、环境监测系统等都属于机房管理的范畴。 安全设备管理。安全设备管理这里主要包含防火墙、IPS、WAF、VPN等网络设施。企业信息安全非常重要,在运维管理中也把安全作为一个单独的模块进行管理。通过购买安全硬件设备和安全服务,不断学习和研究,从而保护好企业数据信息。 服务器管理。这里假定企业实现了虚拟化,大部分系统和服务都部署在虚拟机,而虚拟机是部署在物理机上。服务器管理分物理机和虚拟机分开管理,同时又密切关联。虚拟机在哪一台或几台物理机需记录清楚。 根据产品线中定义的运维优先度等级,在资产管理中的每一个节点标注上相应的等级分值,以便出现大规模故障,有选择、有重点、有顺序地逐一解决问题。 3.供应商管理 供应商管理主要是管理由第三方企业提供的IT系统或设备的服务信息。记录供应商的具体信息、值班电话、硬件备件库等信息。 以上几个模块单独管理,但是又密切相连。如产品线包含哪些项目,包含哪些服务,这些项目和服务部署在哪些虚拟机上,虚拟机又在哪一些物理机上,物理机分布在哪些机房和在机房中的具体位置,物理机在机房中的网络位置和网络架构如何,经过哪些安全设备等等。 反过来需要知道某一些机房有哪一些物理机,物理机位置,安全设备,以及安全设备与物理机的网络架构等,物理机上又有哪些虚拟机上部署了哪一些项目和服务等。系统和服务属于哪些供应商提供,供应商又提供了哪些系统、设备或服务器等。都要多维度进行管理。要求做到某一环节的故障,一查就知道所有受影响的系统和服务。CMDB中的信息相互交织,多维度查询和管理,构建出一张完整的总体架构图,通过总体架构图除了展现出各个部分的基础信息外,还描述了所有的依赖关系,做到坏一点而知全面。 四、日志 通过日志可以比较准确全面地知道系统或是设备的运行情况,可以返查问题产生的原因,还原问题发生的整个过程。通过日志也可以提前预测系统可能要发生的问题或是故障,如系统安全日志,如果网络攻击会在系统安全日志中有一定的体现。 1.系统日志 系统日志主要指的是操作系统的日志,主要在/var/log下的各种日志信息。包含系统操作日志、系统安全日志、定时任务日志等。系统日志是运维管理安全模块中审计的重要依据。一般默认的操作系统日志不能满足要求,需要对系统的参数进行修改,如为history命令加上时间戳、IP,并且长久保留历史等功能。并且对日志文件进行处理,不允许用户进行清空命令,只能append。 2.应用日志 应用日志主要记录应用服务的健康运行情况以及业务操作的具体日志两部分。应用监控运行情况反应应用服务的健康状态,如果应用占用CPU或是内存过高或是忽高忽低不定,都可以通过分析应用日志结合业务操作日志得出结论。业务操作日志可以为业务审计提供主要依据。有一些系统喜欢把业务操作日志写到数据库中,这个也是需要注意的。不过不管在哪个地方,要求是不可缺少的,它为以后业务审计和问题返查提供依据。 3.数据库日志 数据库日志主要反馈数据库的运行情况。通过监控和管理数据库的日志,及时了解数据库的运行情况,遇到问题及时解决等。可以通过数据库日志结合数据库系统自带的数据库如Oracle的系统视图v$开头,MySQL的performance_schema等。虽然数据库的一些信息不是存在日志中而是在数据库里面,但是也可以作为数据库日志的一部分进行管理和监控,已便我们及时知道数据库的监控状况,从而预防可能出现的问题。 4.设备日志 设备日志一般是一个比较容易忽略的地方,但设备日志往往可以反映设备的运行情况。交换机故障,防火墙故障等设备故障都可能引起大面积的系统和服务故障。所以设备日志一定要收集,分析和监控预警。常用的设备日志有交换机日志、防火墙日志、网络安全设备日志等。 在CMDB中梳理的IT基础设施的基础上,对日志进行分类收集、管理、分析和监控,配着监控管理模块的系统,就已经可以达到多方位监控IT系统,保障IT系统的安全稳定。 五、DB 由于数据和数据库的重要性,在基础数据中,数据库作为单独的模块存在,根据环境划分为:生产数据库、测试数据库、开发数据库。严格区分三种环境的数据库,避免测试数据到生产环境,生产数据到测试环境等。另外数据库中数据也为业务监控提供数据依据。通过查询数据库中的数据,依据业务逻辑进行判断是否有错误或是遗漏的数据。 六、知识库 知识库在整个运维管理中是一个辅助功能,主要为运维提供事件管理、问题管理。很多朋友可能会疑惑为什么把事件库和问题库放在知识库这里,这些不是应该在CMDB中吗?这里稍微解释一下,其实本人也并不太清楚这种办法是否可行。在CMDB模块中更多是偏向IT资产管理,为以后的运维操作提供运维范围和运维目标。而事件(主要指运维过程中遇到的所有的运维事件)和问题(需要进行变更发布才能解决的事件升级)更多是在IT资产之上,是解决IT资产的过程中遇到的事件和问题。如果把CMDB作为IT运维的基础管理对象和范围目标的话,事件和问题应该单独出来。也许在后面的运维管理中,逐渐强化CMDB的功能,会把事件库和问题库回归到CMDB模块中。 知识库中还包含经典案例库,主要是解决一些常遇故障、经典问题的解决方法的整理和归档。 解决方案库只要是一些常用的或是探索中的解决方案,例如:Nginx+Tomcat+Redis部署方案,FastDFS分布式文件服务器方案等。 文档库主要用来存储运维管理过程中执行的运维标准和规范以及运维的流程规范,常用的一些规范举例: 文档库也包括一些企业或是部门的规章制度,与供应商的合同条文等。主要是涉及到IT系统文档的一个存放和查阅的地方。 运维标准和运维流程的文档一定是必不可少的。因为运维自动化的前提就是运维的标准化和流程化。如果没有明确的标准和规范的流程,运维自动化就只能一直停留在测试环境的假想空间中。 总结 基础数据在整个运维管理中起到基础、奠基的重要作用,也是做运维管理平台的第一步和以后每一步的重要依据。一定要舍得投入时间、人力等来建立起完整、准确、实时的基础数据。打好地基,以后运维的每一步都将有条不紊地循序渐进,终将建设成属于运维的高楼大厦。 作者:战学超,青航数据架构师。曾任职于NEC软件、海尔B2B平台巨商汇,负责企业数据平台构建、B2B电商平台数据管理与搭建。拥有丰富DBA、系统运维架构经验,擅长数据库、数据平台搭建、私有云部署、自动化运维等。 来源:http://www.yunweipai.com/archives/19490.html 8月云计算免费训练营 时间: 8月23日 - 8月29日 (为期5天,24/25日休息) 课程内容: 什么是Linux、云计算、虚拟化; KVM虚拟化实战; Linux操作系统由来;

GDB图形数据库/Tinkerpop gremlin使用总结

什么是gdb? 图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。例如,在一个典型的社交网络中,常常会存在“谁认识谁,上过什么学校,常住什么地方,喜欢什么餐馆之类的查询”,传统关系型数据库对于超过3度的查询十分低效难以胜任,但图数据库可轻松应对社交网络的各种复杂存储和查询场景。 gdb 基本用法 1.添加点 g.addV('gdb_sample_person').property(id, 'gdb_sample_marko').property('age', 28).property('name', 'marko') g.addV('gdb_sample_person').property(id, 'gdb_sample_vadas').property('age', 27).property('name', 'vadas') g.addV('gdb_sample_person').property(id, 'gdb_sample_josh').property('age', 32).property('name', 'josh') g.addV('gdb_sample_person').property(id, 'gdb_sample_peter').property('age', 35).property('name', 'peter') g.addV('gdb_sample_software').property(id, 'gdb_sample_lop').property('lang', 'java').property('name', 'lop') g.addV('gdb_sample_software').property(id, 'gdb_sample_ripple').property('lang', 'java').property('name', 'ripple') 说明: 操作点 用 g.addV() 操作边 用 g.addE() 后边用点来跟相加的property 属性值。 有点像lambda表达式。 g.V().drop() 这个操作是删除点 g.addV("Metric").property(T.id, "metric-111") g.addV("Metric").property(T.id, "metric-222") g.addV("Metric").property(T.id, "metric-333") g.addV("Source").property(T.id, "source-111") g.addE('flow').from(V('source-111')).to(V('metric-111')) g.addE('flow').from(V('metric-111')).to(V('metric-222')) g.addE('flow').from(V('metric-111')).to(V('metric-333')) 基础语法 V():查询顶点,一般作为图查询的第1步,后面可以续接的语句种类繁多。例,g.V(),g.V('v_id'),查询所有点和特定点; E():查询边,一般作为图查询的第1步,后面可以续接的语句种类繁多; id():获取顶点、边的id。例:g.V().id(),查询所有顶点的id; label():获取顶点、边的 label。例:g.V().label(),可查询所有顶点的label。 key() / values():获取属性的key/value的值。 properties():获取顶点、边的属性;可以和 key()、value()搭配使用,以获取属性的名称或值。例:g.V().properties('name'),查询所有顶点的 name 属性; valueMap():获取顶点、边的属性,以Map的形式体现,和properties()比较像; values():获取顶点、边的属性值。例,g.

Python爬虫实战练习(疫情数据获取)

一、国内疫情数据的爬取1.1 获取响应1.2 使用xpath解析数据1.2.1 分析xpath解析的数据1.2.2 再一次分析数据 1.3 json转化xpath数据类型1.4 逐个获取我们需要的数据,并保存至Excel中1.4.1 创建工作簿1.4.2 创建工作表1.4.3 写入数据至表中1.4.4 数据保存 1.5 代码汇总 二、国外疫情数据的爬取2.1 代码汇总 三、结果 一、国内疫情数据的爬取 1.1 获取响应 # 导入requests库 import requests url = "https://voice.baidu.com/act/newpneumonia/newpneumonia" response = requests.get(url) # 查看响应的编码 print("编码:",response.encoding) # 查看响应头 print(response.headers) # 查看响应地址 print("地址:",response.url) # 查看响应状态码,200表示请求成功 print("状态码:",response.status_code) # 查看正确响应的结果,并与网页源代码比较一下,是否相同 result = response.text print(result) 1.2 使用xpath解析数据 # 导入xpath库,如未安装在cmd里面输入pip install xpath即可 from lxml import etree # 将数据转化为树形态 # 生成HTML对象 html = etree.HTML(result) result = html.xpath('//script[@type="application/json"]/text()') 1.2.1 分析xpath解析的数据 # 查看解析结果 print(result) # 查看数据类型 print(type(result)) # 查看列表长度 print(len(result)) # 进一步提取列表中的数据 result = result[0] 1.

流形:Java的扩展方法

这是有关Manifold的系列文章的第二篇, Manifold是Java的一种新型工具。 第1部分介绍Type Manifold API ,它是常规代码生成的强大替代方案。 本部分探讨了扩展类 ,它是一种创新功能,使您可以使用自己的方法,接口和其他功能来补充类,而无需子类化而无需更改原始类。 快! 编写一些代码以将File的内容读取为String 。 预备,开始! 作为务实的开发人员,您希望这样的事情: String contents = file.readText(); 遗憾的是,您键入file. 在您的IDE中并Swift发现不存在这种方法。 接下来,您在StackOverflow中搜索样板解决方案,并找到有用的代码段。 您希望避免自己和其他人重复此工作,因此将样例代码片段包装在Util库中: public class MyFileUtil { public static String readText(File file) { // boilerplate code... } } 现在您可以编写: String contents = MyFileUtil.readText(file); 这是一样好吗? 您应该拥有一个更友好,更实用的File API — readText()更适合作为直接在File上的实例方法,并且更易于发现。 这是语言社区中通常称为“ Extension Methods所有差异。 这也是Manifold在Java遗留下来的地方接手的地方。 集成块通过扩展类完全实现了Java的扩展方法: package extensions.java.io.File; import manifold.ext.api.*; @Extension public class MyFileExtension { public static String readText(@This File thiz) { // boilerplate code.