文章目录 一、ElasticSeach简介1. 介绍2. ES可以做什么2.1 信息检索2.2 企业内部系统搜索2.3 数据分析引擎 3. ES特点3.1 海量数据处理3.2 开箱即用3.3 作用传统数据库的补充 4. ES对比solr: 二、Lucene全文检索库1. 什么是全文检索1.1 结构化数据与非结构化数据1.2 搜索结构化数据和非结构化数据1.3 全文检索: 2. Lucene简介 三、ES的核心概念:1. 索引 index:2. 映射 mapping3. 字段 Field4. 类型type5. 文档 document6. 集群 cluster7. 节点 node8. 分片和副本: shards & replicas8.1 分片8.2 副本 四. 安装ES:1. 安装es:1.1 创建普通用户:1.2 为普通用户添加sudo权限1.3 准备安装包1.4 修改配置文件1.4.1 修改elasticsearch.yml1.4.2 修改jvm.option 1.5 配置其他节点1.6 修改系统配置, 解决启动问题1.6.1 打开文件的最大数限制;1.6.2 启动线程数限制1.6.3 调大虚拟内存 1.7 启动es 2. 使用Docker3. Elasticsearch-head插件4. 安装IK分词器5. 准备Vscode开发环境 一、ElasticSeach简介 官方网站: https://www.elastic.co/cn/elasticsearch/
1. 介绍 Elasticsearch是一个基于Lucence的搜索服务器;提供了一个分布式多用户能力的全文搜索引擎, 基于RESTful web接口;Elasticsearch是用java语言发开的, 并作为Apache许可条款下的开放源码发布, 是一种流行的企业级搜索引擎;ES用于云计算中, 能够达到实时搜索, 稳定, 可靠,快速,安装使用方便;官方客户端维护多种编程语言可用;根据DB-Engines排名显示, ES是最受欢迎的企业所搜索引擎; 2.
👨🎓作者:bug菌
✏️博客:CSDN、掘金等
💌公众号:猿圈奇妙屋
🚫特别声明:原创不易,转载请附上原文出处链接和本文声明,谢谢配合。
🙏版权声明:文章里可能部分文字或者图片来源于互联网或者百度百科,如有侵权请联系bug菌处理。
一、前言🔥 环境:Windows10 + Springboot 2.3.1Release + idea 2019.3
小伙伴们在批阅文章的过程中如果觉得文章对您有一丝丝帮助,还请别吝啬您手里的赞呀,大胆的把文章点亮👍吧,您的点赞三连(收藏⭐️+关注👨🎓+留言📃)就是对bug菌我创作道路上最好的鼓励与支持😘。时光不弃🏃🏻♀️,创作不停💕,加油 日常使用idea开发,谁料项目正常启动没问题,但debug模式启动时却出现了如下报错。让我疑惑不解啊?用着好好的,咋突然出现问题了?还能咋办,解决呗!
报错code:
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended.
实际报错界面截图:
正当我抓耳挠腮时,一位大佬见我如此一脸懵逼的盯着屏幕,热心上前询问一番,我给他说明了前后缘由,他几秒钟啪的一下就帮我搞定了,大佬还是牛批的呀。
于是我赶紧把他的解决操作过程记录了下来,偷偷来告诉你们,希望大家也能跟那个好心人一样,会将这种爱传递下去,好人终将一生平安喜乐。
二、解决方案🔥 点击idea左上角。选择File→ Settings→ 输入 async 回车–> 选择Debugger下的Async Stack Traces,把图中该选项的√ 去掉 → 点击apply → 点击ok;
大功告成?项目我们再次debug启动。看看是否还报错??
控制台可以看到,报错内容不见了,这就说明此方式足矣解决该问题。
虽然问题是得以解决了,但是至于为何报错, 我也不得而知,有哪位小伙伴是清楚的,麻烦下方评论区告诉我一身,bug菌感激不尽。
... ...
好啦,以上就是这期的全部内容啦,如果对你有所帮助,还请不要忘记给bug菌[三连支持]哟。若想学习更多教学内容,就请关注我,咱们下期见啦。
三、文末🔥 如果你还想要学习更多,小伙伴们大可关注bug菌专门为你们创建的专栏《bug调优》,都是我一手打下的江山,持续更新中,希望能帮助到更多小伙伴们。
我是bug菌,一名想走👣出大山改变命运的程序猿。接下来的路还很长,都等待着我们去突破、去挑战。来吧,小伙伴们,我们一起加油!未来皆可期,fighting!
最后送大家两句话,与诸君共勉!
☘️做你想做的人,没有时间限制,只要愿意,什么时候都可以start,
🍀你能从现在开始改变,也可以一成不变,这件事,没有规矩可言,你可以活出最精彩的自己。
💌如果文章对您有所帮助,就请留下您的赞吧!(#^.^#);
💝如果喜欢bug菌分享的文章,就请给bug菌点个关注吧!(๑′ᴗ‵๑)づ╭❤~;
💗如果对文章有任何疑问,还请文末留言或者加群吧【QQ交流群:708072830】;
override在C++中它是覆盖了一个方法并且对其重写,从而达到不同的作用。在我们C++编程过程中,最熟悉的就是对接口方法的实现,在接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口声明的所有方法。还有一个典型应用就是在继承中也可能会在子类覆盖父类的方法。
1.公有继承 包含两部分:一是“接口”(interface),二是 “实现” (implementation)。
class Shape { public: virtual void Draw() const = 0; // 1) 纯虚函数 virtual void Error(const string& msg); // 2) 普通虚函数 int ObjectID() const; // 3) 非虚函数 }; class Rectangle: public Shape { ... }; class Ellipse: public Shape { ... }; 1. 1 纯虚函数 纯虚函数,继承的是基类成员函数的接口,必须在派生类中重写该函数的实现:
Shape *ps1 = new Rectangle; ps1->Draw(); // calls Rectangle::Draw Shape *ps2 = new Ellipse; ps2->Draw(); // calls Ellipse::Draw 调用基类的 Draw(),须加 类作用域操作符 ::
目录 1 实验简介2 实验环境3 实验具体过程—脚本编写3.1 编写用户登录页面3.2 编写登录信息判断页面 4 实验验证5 实验拓展6 归纳 1 实验简介 实验目的:模拟网站账户的注册与登录等,实现对用户登录进行验证,在此过程中练习前面学过的HTML和PHP语法。
实验内容:
利用HTML表单让用户注册账号、密码。(假设账户为duzz,密码为123456)利用PHP语句验证账户密码是否正确,成功则弹出欢迎界面,失败则提示失败并要求重新输入。 2 实验环境 服务端:本实验基于虚拟机win2008系统的WAMP环境进行,该环境相关配置过程参考文章《【语言环境】WAMP环境部署及优化—以win2008R2SP1为操作系统》
客户端:浏览器通过IP地址访问所编写网页。
服务端与客户端处于同一个局域网下。
3 实验具体过程—脚本编写 3.1 编写用户登录页面 编写用户登录表单login.html。
根据用户登录功能需求应该有账号和密码输入框,并且有登录按钮以提交数据。根据页面处理功能需求,应该将登录页面数据提交给数据处理界面。
代码如下: <html> <meta charset="utf-8"> <h1>用户登录</h1> <form action="./get.php" method="get" > 用户名:<input type="text" name="userName"><br/> 密码:<input type="password" name="userPassword"><br/> <input type="submit" name="userSubmit" value="登录"> </form> </html> 3.2 编写登录信息判断页面 编写登录信息判断页面get.php,该网页与form.html存放在同一文件夹下。
判断用户是否从登录页面进入,用isset($_GET[ ‘userSubmit’ ]判断是否有提交按钮数据(isset()函数判断变量是否已定义);若存在则判断账号密码是否正确,若不存在则提示进行登录。判断账号密码内容是否存在且是否正确,若正确则弹出欢迎界面,若错误则提示重新登录。
代码: <meta charset="utf-8"> <?php if(isset($_GET['userSubmit'])){ if(isset($_GET['userName']) && $_GET['userName']=='DuZZ' && isset($_GET['userPassword']) && $_GET['userPassword']==123456){ echo "Welcom, {$_GET['userName']}"; } else{ echo "
最强干货 多的不说 直接上配置 copy下来放上去即可
{ "security.workspace.trust.untrustedFiles": "open", "vetur.format.options.tabSize": 4, "vetur.format.defaultFormatterOptions": { "prettier": { "semi": false, "singleQuote": true }, "js-beautify-html": { "wrap_attributes": "auto", "wrap_line_length": 12000, "end_with_newline": false }, "prettyhtml": { "printWidth": 100, "singleQuote": true, "wrapAttributes": false, "sortAttributes": false } }, "vetur.format.styleInitialIndent": false, //"explorer.confirmDelete": false, "vetur.format.defaultFormatter.html": "js-beautify-html", "vetur.format.defaultFormatter.js": "vscode-typescript", "[vue]": { "editor.defaultFormatter": "octref.vetur" }, "vetur.format.defaultFormatter.css": "none", "[jsonc]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[javascript]": { "editor.defaultFormatter": "vscode.typescript-language-features" }, "prettier.endOfLine": "auto", "vetur.ignoreProjectWarning": true } {
vivado 2019.1安装modelsim 10.7版本是正确其中modelsim的下载地址是:
链接:https://pan.baidu.com/s/1jpdNqo2a6jLtWlgA72l1Aw 提取码:rthz 我安装的参考的是这篇博客,安装modelsim参考的链接
在第十一步的 时候提示无法找到mgls.dll和mgls64.dll文件,然后在评论区找到百度的解决方法,但是以管理员的身份运行,操作后没有顺利执行,而是提示“patch_dll.dat 不是内部或外部命令,也不是可运行的程序或批处理文件”
我的解决方法是先展示win64目录下所有的文件,然后再输入同样的命令就生成了LICENSES.
通过URL传递参数与上面的URL不同,上面的URL中均需写明参数名和对应参数值,这里的URL传递参数,仅需要在地址栏输入参数值,然后后台自动匹配到对应的参数名。
springMVC通过使用处理器映射和@PathVariable注解的组合来获取URL参数。
首先通过处理器映射可以定位参数的位置和名称,而@PathVariable则可以通过名称来获取参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.awaimai.web; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; @RestController public class kzq { @RequestMapping ( "/param/geturl/{name}/{age}/{score}" ) @ResponseBody public Map<String, Object> getUrlParam( @PathVariable ( "name" ) String name, @PathVariable ( "age" ) Integer age, @PathVariable ( "score" ) Double score) { Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.
想学习ref,必须先学习reference_rapper
1、是什么? ref是个函数模板:
用来构建一个reference_wrapper对象并返回,该对象拥有传入的elem变量的引用。如果参数本身是一个reference_wrapper类型的对象,则创建该对象的一个副本,并返回。
2、为什么要有ref std::ref主要在函数式编程(如std::bind)时使用,bind是对参数直接拷贝,无法传入引用(即使你传入的实参是引用类型也不行),故引入std::ref()。使用std::ref可以在模板传参的时候传入引用。
ref能使用reference_wrapper包装好的引用对象代替原本会被识别的值类型,而reference_wrapper能隐式转换为被引用的值的引用类型。
#include <iostream> #include <functional> #include<vector> using namespace std; std::ref主要是考虑函数式编程(如std::bind)在使用时,是对参数直接拷贝,而不是引用 void f(int& a, int& b, int& c) { cout << "in function a = " << a << " b = " << b << " c = " << c << endl; cout << "in function a = " << &a << " b = " << &b << " c = "
一、前言 可能大家对obproxy不是很了解,这里边我提一个类比的,mysql的mysql-router,大家应该就明白了,mysql-router是作为在mysql之上的一个"路由转发"的组件。obproxy对于oceanbase就像mysql-router之于mysql一样。
二、obpoxy是什么 OBPrxoy是为OceanBase数据库专门量身定制的反向代理服务器,用户的数据在OceanBase上以多副本的形式存放在各个ObServer上, OBProxy负责接收用户发过来的SQL请求,转发用户请求SQL路由到最佳目标ObServer上,并将执行结果给用户。作为OceanBase数据库产品不可或取的一部分,OBProxy具备以下特性:
高性能转发: OBProxy完整兼容MySQL协议,采用多线程异步框架和透明流式转发的设计,保证了数据的高性能转发(单核5万QPS),以及自身对机器资源的最小消耗(内存不超过50M,单cpu不超过20%)。最佳路由: OBProxy需要充分考虑用户请求涉及的的副本位置、用户配置的读写分离路由策略、OceanBase多地部署的最优链路,以及OceanBase各机器的状态以及负载情况,将用户请求路由到最佳的ObServer,最大限度的保证OceanBase整体性的高性能运转。连接管理:针对一个Client端的物理连接,OBProxy维持自身到后端多个ObServer的连接,采用基于版本号的增量同步方案维持每个ObServer的连接在同一状态,保证了Client高效访问各个ObServer。定制协议:原生MySQL协议存在报文CRC校验缺失,Request ID校验缺失的正确性缺陷,而OBProxy默认使用OceanBase定制协议予以解决,保证了和ObServer之间链路的正确性。易运维:OBProxy本身无状态,支持同时访问多个OceanBase集群,支持无限水平扩展。并且可以通过丰富的内部命令实现对自身状态的实时监控,实现自身冷热升级/下线/重启等常见运维操作,可以提供极大的运维便利性。 OceanBase 数据库与传统单机数据库不同,OceanBase 数据库是分布式数据库,每个表甚至每个表的不同分区都可能存放在不同的机器上。想要对表进行读写,必须先要定位到数据所属的表或是分区的主副本位置,然后才能执行相应的SQL DML 语句,这在应用层面而言是几乎不可能做到的。OBProxy 作为 OceanBase 数据库专用的反向代理软件,其核心功能就是路由以将客户端发起的数据访问请求转发到正确的 OBServer 上。
客户端通过 OBProxy 访问 OceanBase 数据库的数据链路如下图所示,用户通过任意 Client 驱动发出请求,请求通过负载均衡组件访问到任意一台无状态的 OBProxy 上,然后 OBProxy 再将用户请求转发到后端 OceanBase 集群中最佳的 OBServer 上去执行。
每个 OBServer 均包含完整的 SQL 引擎和存储引擎,用来负责解析用户 SQL 以生成物理执行计划并执行。分布式的 OBServer 之间通过 Paxos 协议以保证高可用性。这种架构设计中,OBProxy 只承担基本的路由和容灾功能,而数据库的功能全部交由 OBServer 实现。这样更加简单明确的分工可以将各组件性能做得更加极致,OceanBase 数据库整体最高也能做到近似访问单机数据库的性能。
OBProxy 支持将请求正确发送至主副本,并且通过特定配置还支持读写分离和备优先读等场景。另外在 OBServer 节点发生宕机、升级或合并等状态时,可以通过黑名单机制确保用户请求可以被路由至状态正常的 OBServer 上。
三、OBProxy是如何设计实现的? OBProxy的主要架构可以简单描述如上图所示,其中异步框架实现高效的代理转发,通信协议实现OBProxy与Client和ObServer之间通信方式,连接管理实现OBProxy的连接池功能,路由选择实现对用户请求的的最优路由选择,而容灾模块则负责监控OceanBase集群状态。监控运维提供对OBProxy的丰富运维手段,集群管理实现OBProxy对OceanBase多集群的支持。以上组件相互依赖配合,共同实现OBProxy的整体功能。下边我专门讲解一下路由选择模块:
1. 路由选择
路由选择是OBProxy的核心功能,如前所述说,路由选择的输入用户的SQL,用户配置规则,ObServer的状态,路由选择的输出是一个可用ObServer地址。其路由逻辑可以入下图所示:
其中,解析SQL模块使用OBProxy自己定制的语法parser模块,只需要解析出DML语句中数据库名/表名/hint,不需要其他复杂的表达式推演等,因此parser模块做的十分高效。
路由规则确定模块中,OBProxy需要根据不同情况确定最佳的路由规则。比如强一致性读的DML请求期望发到副本leader的ObServer上,弱读的DML请求和其他请求则不要求,leader和follower均衡负载即可。如果OceanBase集群是多地部署,OBProxy还提供了LDC路由,优先发给同机房的ObServer,其次是同城的ObServer,最后才是其他城市的ObServer。如果OceanBase集群是读写分离部署,OBProxy还需要提供读zone优先,只限读zone,非合并优先等规则供业务按照自身特点配置。上述的几种情况在路由选择中是组合关系,输出是一个确定的路由规则。
获取路由表是指OBProxy根据用户的请求SQL获取该SQL涉及的副本位置。OBProxy每次首先会尝试从本地线程缓存中获取路由表,其次是全局缓存,最后才是发起异步任务去向ObServer查询路由表。对于路由表的更新,OBProxy采用触发更新机制。OBProxy每次根据路由表转发给ObServer的请求,当ObServer不能本地执行时,会在回包时反馈给OBProxy。OBProxy根据反馈决定是否下次强制更新本地缓存路由表。那么什么时候路由表才会变化呢?通常是在ObServer合并或者负载均衡导致切主发生才会发生。
选择目标ObServer则是根据上上一步确定的路由规则从上一步获取的路由表中选择最佳的ObServer,在经过黑名单/灰名单检查通过后作为最终的目标server进行请求转发。
@article :期刊文章
@book: 有明确出版商的书
@booklet: 没有指定出版商或赞助商的印刷品
@conference: 会议文章,与inproceedings相同
@inbook: 书的一部分,可以是章节等
@incollection: A part of a book having its own title
@inproceedings: 会议文章
@manual: 技术文档
@mastersthesis: 硕士论文
@misc: 大杂烩,当没有其他适合的时候使用这个类型
@phdthesis: 博士论文
@proceedings: 会议记录
@techreport: 由学校或其他机构出版的报告,通常含编号
@unpublished: 有作者和标题但未正式出版的文件
目录
第一章 前言
1.1 背景和意义
1.2 设计目标
第2章 数据库设计 2.1 需求分析
2.2 概念结构设计 2.3 逻辑结构设计
2.4 关系模式规范化检查及处理
第3章 数据库定义与操作
3.1 数据库及数据表定义
3.2 数据查询操作
3.3 数据增删改操作 3.4 索引及视图应用
第4章 应用系统实现
4.1 登录窗口
4.2 注册页面
4.3 普通用户界面窗口
4.4 服务员界面窗口
4.5 管理员界面窗口
4.6 统计界面
第5章 总结
第一章 前言 1.1 背景和意义 近年来,在中国市场上KTV娱乐业是当今市场化程度最高的行业之一,伴随着娱乐市场的迅速升温,各大KTV商家竞争激烈性不言而喻。在竞争的巨大压力下去了解、适应、占领和创造市场,不断丰富KTV经营内容,革新经营模式,提高服务质量,开拓新型市场,才能在激烈的市场竞争中处于不败之地。KTV管理系统不仅能解决KTV在管理和经营上的一些问题,也能更好的为消费者提供一个良好的体验环境。
1.2 设计目标 本系统设计初衷是希望在快节奏的时代,不论是家庭,还是工作场所,亦或是学校,在业余时候,人们能找到一种释放压力疲惫的娱乐方式。顾客来到KTV一定会开包房消费,但是包房会有大小之分,不同类型的包房价格也不同。本系统希望可以按照顾客的需求进行包房分配,并且及时知道包房剩余状态,更方便服务员快捷的进行包房分配,并且服务员可以了解顾客的个人信息,可以准确地为顾客提供服务。
第2章 数据库设计 2.1 需求分析 需求分析也称为软件需求分析、系统需求分析或需求分析工程等,是开发人员经过深入细致的调研和分析,准确理解用户和项目的功能、性能、可靠性等具体要求,将用户非形式的需求表达转化为完整的需求定义,从而确定系统必须做什么的过程。
通过实际调查,本系统需要具备:
良好的人机交互界面方便用户预定KTV房间以及酒水消费等如果系统使用用户多,有较好的权限管理方便添加、删除、修改和查询数据 2.1.1 功能概述 经分析,KTV管理系统应具备以下功能模块:
1)用户方面,功能要求如下:
可以查看并修改个人信息可以查看并预定KTV房间可以查看并取消预定情况记录 2)服务员方面,功能要求如下:
可以查看并修改个人信息可以查看并修改顾客预约情况可以为顾客安排房间可以查看顾客信息可以查看KTV房间预约情况可以查看顾客历史预约记录表 3)管理员方面,功能要求如下:
可以查看并修改个人信息可以对服务员信息进行维护,包括增删改查可以对KTV房间进行维护,包括增删改查可以对所有地用户进行管理,包括增删改 主要功能模块图如下图2.1所示: 图2.1.1 系统总功能模块图 2.
配置
apt-get install python-software-properties -y apt-get install software-properties-common python-software-properties LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php apt-get update apt-get upgrade -y 安装
apt-get install php5.6 php5.6-fpm php5.6-mysql php5.6-gd php5.6-mbstring php5.6-curl php5.6-soap php5.6-redis php5.6-xml php5.6-apcu php5.6-mcrypt -y nginx 配置
vim /etc/nginx/fastcgi_params # 在文档最后添加一下代码: fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 1、mkdir -p /www/test 2、vim /www/test/info.php 输入内容 <?php phpinfo(); server { listen 8082; root /www/test; location / { } index index.php index.html index.htm; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php5.6-fpm.sock; include fastcgi_params; } location ~ /\.
H264编解码参数说明 一、H264码流分层1、NAL层①、如何判断帧类型(是图像参考帧还是I、P帧等)?②、 帧格式③、 [SPS格式解析代码分析 ParseAndRewriteSps方法 ](https://github.com/chensongpoixs/cwebrtc/blob/chensong/common_video/h264/sps_vui_rewriter.cc) 2、 VCL层3、 码流基本概念①、 SODB(String Of Data Bits)②、 RBSP(Raw Byte Sequence Payload)③、 NALU 单元④ SPS/PPS/Slice Header⑤ [webrtc中对应RBSP的代码 段 方法SpsVuiRewriter::ParseAndRewriteSps](https://github.com/chensongpoixs/cwebrtc/blob/chensong/common_video/h264/sps_vui_rewriter.cc) 二, SPS中两个重要的参数分别是 Profile 与 Level1、 H264 Profile2、 H264 Level3、 分辨率4、 帧相关的①、 帧数 log2_max_frame_num_minus4②、 参考帧数 max_num_ref_frames③、 显示帧序号 pic_order_cnt_type 5、 帧率的计算 三、 PPS与 Slice Header6、Slice Header①、 帧类型②、 GOP中解码帧序号③、 预测权重④、 滤波 音视频基础学习实验地址:https://github.com/chensongpoixs/caudio_video
一、H264码流分层 1、NAL层 Network Abstraction Layer,视频数据网络抽样层。
①、如何判断帧类型(是图像参考帧还是I、P帧等)? NALU类型是我们判断帧类型的利器,从官方文档中得出如下图:
我们还是接着看最上面图的码流对应的数据来层层分析,以00 00 00 01分割之后的下一个字节就是NALU类型,将其转为二进制数据后,解读顺序为从左往右算,如下:
(1)第1位禁止位,值为1表示语法出错
(2)第2~3位为参考级别
(3)第4~8为是nal单元类型
例如上面00000001后有67,68以及65
其中0x67的二进制码为:
Haffman Tree 构造方法: 1.初始化每个叶子结点都是一棵树。 2.找最小权值的两棵树。 3.合并两树,生成新结点。 编码: 1.往左为1,右为0. 2.不等长编码。 #include<stdio.h> #include<malloc.h> #include<stdlib.h> #define MaxN 100 //最大结点个数 #define Maxbit 255 //最大编码值 #define MaxValue 9999 //最大权值 //树储存结构 typedef struct { int weight;//权值 int flag;//标记,flag==1则已经加入到hafftree中 int parent;//父结点下标 int leftChild;//左孩子结点下标 int rightChild;//右孩子结点下标 }HaffNode; //哈夫曼编码结构 typedef struct { int bit[MaxN];//每个叶子结点到根节点路径所对应的哈夫曼编码 int start;//编码起始下标 int weight;//字符权值 }Code; //建立hafftree //叶节点数为n,权值数组为weight的hafftree* void Haffman(int weight[], int n, HaffNode haffTree[]) { int i, j, m1, m2, x1, x2; //初始化hafftree //共有n*2+1个结点,前n个是叶子结点 for (i = 0; i < 2 * n - 1; i++) { if (i < n) { haffTree[i].
目录
1、安装JRE环境
2、安装STM32CubeMX
3、HAL库安装(可不安装)
在线安装
离线安装
4、安装完成
这个是使用Java开发的一个工具,所以要先安装JRE环境。
1、安装JRE环境 下载路径:
a、官网: https://www.java.com/en/download/manual.jsp
b、百度网盘:链接:https://pan.baidu.com/s/1lVXw0WgeW5x28xyYXBc_hg 提取码:4i2z
c、自己百度
下载完安装包后,点击安装,如下(若不想使用默认路径,记得在左下方勾选“更改目标文件夹”)。选择安装 修改安装路径, 点击下一步 然后等待完整完成关闭即可
2、安装STM32CubeMX 下载路径:
a、官网:www.st.com/stm32cubemx
b、 百度网盘:链接:https://pan.baidu.com/s/1lVXw0WgeW5x28xyYXBc_hg 提取码:4i2z
1、下载完安装包后,点击安装
2、接受条款,下一步
3、选择第一个即可,下一步 4、改不改默认安装位置都可
5、更改目录,同意吧
6、嗯,继续下一步 7、等待安装完成,done
3、HAL库安装(可不安装) STM32 HAL固件库是Hardware Abstraction Layer的缩写,中文名称是:硬件抽象层。HAL库是ST公司为STM32的MCU最新推出的抽象层嵌入式软件,为更方便的实现跨STM32产品的最大可移植性。HAL库的推出,可以说ST也慢慢的抛弃了原来的标准固件库,这也使得很多老用户不满。但是HAL库推出的同时,也加入了很多第三方的中间件,有RTOS,USB,TCP / IP和图形等。
和标准库对比起来,STM32的HAL库更加的抽象,ST最终的目的是要实现在STM32系列MCU之间无缝移植,甚至在其他MCU也能实现快速移植并且从16年开始,ST公司就逐渐停止了对标准固件库的更新,转而倾向于HAL固件库和 Low-layer底层库的更新,停止标准库更新,也就表示了以后使用STM32CubeMX配置HAL/LL库是主流配置环
HAL库,有在线安装、离线安装两种方式。意见使用在线安装,简单省事。
在线安装 a、打开安装好的 STM32CubeMX 软件 点上面的Help -> Manage embedded software packages(如果第一打开有提示界面,选最后一个 NO thank 就可以了)
b、然后选择你的芯片型号,安装既可以了( 点击“Install Now” )
c、等待完成就可以了
离线安装 安装包:
官网:www.st.com/stm32cubemx
或者:自己百度或者下方留个邮箱我发给你
打开官网,选择“tools-software”
下拉,选择你的芯片型号
点击上图芯片型号,在新开的网页中,下拉获取软件
a、打开安装好的 STM32CubeMX 软件 点上面的Help -> Manage embedded software packages -> From Local(如果第一打开有提示界面,选最后一个 NO thank 就可以了)
第十六章:红黑树模拟实现STL中的map与set Iterator.h #pragma once // 反向迭代器--迭代器适配器 template<class Iterator> struct ReverseIterator { typedef typename Iterator::reference Ref; typedef typename Iterator::pointer Ptr; typedef ReverseIterator<Iterator> Self; Iterator _it; ReverseIterator(Iterator it) :_it(it) {} Ref operator*() { return *_it; } Ptr operator->() { return _it.operator->(); } Self& operator++() { --_it; return *this; } Self& operator--() { ++_it; rteurn *this; } bool operator!=(const Self& s) const { return _it != s._it; } bool operator==(const Self& s) const { return _it == s.
Socket套接字原理 1、什么是Socket 在计算机领域,套接字Socket作为计算机之间进行通信的固定的约定方式之一存在。这种太抽象了,我举个例子,我们要是用笔记本电脑前需要先对电脑供电,那供电就有两种方式电线插座供电和电池供电,电网有电就用插座供电,电网没电就用笔记本的自带的电池供电。那么这个供电的工具(电池或者电线插座)就是套接字Socket。
Socket起源于Linux系统 ,我们都知道Linux是以文件系统进行存在。在linux里万物皆文件,就连进程都成为了一种数据结构,设备也被视为一个文件可以读写。在我看来Socket对于计算机就是实现这种模式的工具,Socket的函数就是实现对通信的操作来实现网络通信。
Socket作为中间件几乎支持所有协议使用
2、Socket如何实现网络通信 学过计网的都知道,对于计算机本地通信之间的通信是由进程实现的。
2.1、本地进程的通信方式 常见就只有几种。消息队列、管道、进程管理器、信号量等
消息队列 ,按照普通队列方式完成多进程之间的数据传递(multiprocessing模块的Queue)
管道 ,文件的一种,本质是一个固定大小的缓冲区,在Linux中缓冲区大小为4kb。
管道工作原理:假设两个进程之间需要通讯,前面的进程对缓冲区进行文件写操作,后面的进程对文件进行读操作,就这样前面写后面读,两个进程就通过管道完成通信。
#这里提供一个演示文本 import datetime from multiprocessing import Process,Pipe import time from charset_normalizer import constant num=0 def sendMsg(p): now=str(datetime.datetime.now()) # p.name msg="管道传输的数据" # name=psutil.Process(os.getpid()).name() print("这个是独立子进程 "+now+"数据是 :"+msg) p.send(msg) print("数据发送成功") p.close() def receiveMsg(p): print("接受管道传输信息:",p.recv()) if __name__=='__main__': print("-----------start---------") # (grandPipe,parentPipe)=Pipe() (parentPipe,sonPipe)=Pipe() task1=Process(target=sendMsg,args=[parentPipe]) task1.start() task3=Process(target=sendMsg,args=[parentPipe],name="task1") task3.start() task2=Process(target=receiveMsg,args=[sonPipe],name="task2") task2.start() time.sleep(5) print("-----------end---------") 远程过程调用、共享内存、同步等
2.2、网络中进程的通信方式 要理解网络进程通讯,我们要先解决两个问题
如何标定一台主机,我们需要直到需要通信的进程在哪一个主机上运行?如何标定唯一进程,本地进程通讯可以通过pid区别,在网络上怎么区别? TCP/IP协议族会解决第一个问题,定位通讯主机;而网络七层的传输层利用三元组(ip、端口、协议)则可以解决第二个问题
2.3、Socket实现通信的过程 现在我们已经知道网络中进程如何通信的,那么如何去实现他就是Socket的作用了。
Socket就如定义一般,是作为三元组解决网络通信中的中间件工具,就目前程序来说大部分都是采用Socket套接字中间件去实现网络中进程的通讯
Socket通信的传输方式
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 前言一、CS和BS架构特点二、动态网页和静态网页浏览器内部结构浏览器工作原理DNS解析过程:OSI七层模型TCP/IP协议渲染过程http协议 前言 web测试的价值:
a、挖掘测试深度,提高测试价值
客户端/浏览器----应用服务器----数据库服务器
数据从客户端/浏览器接收,经过http协议、tcp/ip协议传输,来到应用服务器,最后到达数据库,前面我们分析过界面的输入域,服务器数据库的后台,但是我们没有去关心整个数据传输的正确性,数据从前台到后台,或者从后台到前台后是否准确无误,又有什么规则来限制和约束我们传输的数据保证安全性和准确性,这就是我们要研究的问题
b、协助自动化(功能,接口,性能)测试定位调优
客户端/浏览器----应用服务器----数据库服务器,性能定位调优 过程是采用一一排除的方法,整体分为三个方向,前端调优、网络调优、后端调优,那么前段调优也就主要是针对的浏览器端的web页面,我们需要了解前台发出的请求数据通过什么过程发送到后台,后台相应的数据经过什么样的过程传到前台,浏览器怎样把数据渲染完成,中间是否存在性能问题。
一、CS和BS架构特点 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
优点:
1、有独立的客户端,安全性高
2、大部分业务都在客户端实现,可以实现很复杂的业务
缺点:
1、对环境要求高,需要安装客户端,推广速度慢
2、需要专门前后台的开发团队,维护成本高
BS架构
优点:
1、不需要安装客户端,只需要浏览器,推广速度块
2、只需要维护服务器端,开发维护成本低
缺点:
1、安全性差
2、大部分业务都在服务器端实现,不能实现复杂的业务
总结:
CS架构—socket协议用于描述IP和端口号,应用程序通过套接字向网络发送请求和应答。
BS架构—http协议,用于向web服务器传输超文本到本地浏览器
目前cs和bs架构一般结合使用,例子:空间、邮箱、QQ等
两大主流架构相同点
三部分
客户端 不管是浏览器还是自主研发的应用程序,都担负客户端的工作。负责与用户的交互(输入)和数据的展示(输出)
服务器 接收客户端的信息(输入),分析处理后把处理后的响应结果返回给客户端。负责处理业务逻辑。
数据库 负责数据的存储和查询,还可以通过存储过程来处理业务逻辑
二、动态网页和静态网页 优点:
1、安全,理论上没有攻击漏洞
2、没有数据库访问,减少服务器负荷,速度快
3、易于搜索引擎收录
缺点:
1、网站更新需要修改代码
2、缺少交互功能,动态效果差
3、网站设计按页计费
动态网页:所谓动态网页,就是说该网页文件不仅具有HTML标记,以asp、jsp、php、cgi等形式为后缀,并且在动态网页网址中有一个标志性的符号——“?”而且含有程序代码,用数据库连接, 动态网页能根据不同的时间,不同的来访者显示不同的内容,动态网站更新方便,一般在后台直接更新的,并不需要人工手动修改代码。
例子:淘宝,京东
优点:
1、网站更新不需要修改代码
2、更新容易,可扩展升级,与数据库连接,维护方便
3、动态效果强,可与用户进行动态交互
缺点:
1、交互性强,存在的攻击漏洞多
2、页面信息需要从数据库读取,速度慢
3、对搜索引擎不友好,不便于搜索
浏览器内部结构 1、5款主流的浏览器
IE、Firefox、Safari、Chrome、Opera 等
2、浏览器的主要功能
通过过从服务器请求,并显示在浏览器窗口,以提供您选择的Web资源。
资源通常是一个HTML文档,也可能是一个PDF文档、图片或者其它类型。
资源的位置是由用户使用URI(统一资源标识符)指定的。
3、浏览器的内部组成
1、JS引入 1. 尽量放在html最下面 内部标签引用外部引用,src属性 <script type="text/javascript" src="myjs.js"></script> 2. href src url区别【重点】 href
link a浏览器可以识别当前的资源是一个样式表,页面解析就不会暂停。 src
scritp img frame在浏览器下载,编译,执行这个文件之前页面的加载和处理会被暂停 图片加载的时候,下面的页面会暂停加载js文件放到html的最下面 url
统一资源定位符background-image:url(“img/bg.png”); 2、变量 2.1 变量命名规范 驼峰式命名
数字,字符,下划线,不能以数字开头
大小写敏感,变量名区分大小写!!!【重要】
可以以 $ 和 _ 开头
JavaScript 命名请不要以 $ 符号开头。此举会引起 JavaScript 库名称冲突。 万物皆可var
2.2 【基本类型】特殊值: undefined 未定义,所有js变量未赋予初始值的时候,默认值都是undefinednull 空值NaN Not a Number,非数字,非数值,即非法 NaN与所有数值都不相同(NaN===NaN❌)Infinity 含义无穷大 ps: undefined==null true
undefined===null false
2.3 【基本类型】数值Number 不区分小数和整数
尽量避免浮点数计算,存在精度问题
在进行二进制转换的时候会出现无限循环的情况
var x = 0.1; var y = 0.2; var z = x + y // z 中的结果并不是 0.
目录
集合的特性
创建集合
添加元素
删除元素
查找元素
判断元素值否在集合中
计算集合的元素个数
清空集合
集合的交、并、补、差运算
子集的判断
判断两个集合是否有相同元素
集合的拷贝
集合的特性 集合是没有重复元素的集合数据类型,可以自动去重
集合是无序的,没有顺序
创建集合 可以用 set() 语句创建,其中 set 中的值必须是字符串类型,而且只能有一个参数可以用 { } 的形式创建,单创建时必须有值传入,不然类型默认为字典a={1,2,3,4}a=set( '1234' )a{ '1' , '2' , '3' , '4' } 添加元素 set.add(values)set.update(values) , 其中values可以是列表、元组、字典等不论添加什么类型在set都会被分解为字符,但 { } 中则不会 删除元素 set.remove(values) : 将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误set.discard(values) : 将元素 x 从集合 s 中移除,如果元素不存在,不会发生错误set.pop() : 随机删除一个元素,并返回被删除的元素值 查找元素 由于集合是无序的,所以不能通过下标来查找 判断元素值否在集合中 in : 若在集合中,返回True,否则,返回Falsenot in : 若不在集合中,返回True,否则,返回False 计算集合的元素个数 len(set) : 返回元素个数a=set('123')len(a)3 清空集合 set.
本案例要求编写一个程序,模拟库存管理系统,该系统内容主要包括,商品入库,商品显示,和删除商品功能。(此程序用手机举例)
此管理系统分别为两个类Phone,和Test类
Phone类 确定四个变量(类)
1.生成空参数构造方法
2.全部参数的构造方法
3.生成全部参数的Setter和Getter方法
4.生成全部参数的to String方法
package anli06_1; public class Phone { private String name; private String color; private int price; private int num ; public Phone() { } public Phone(String name, String color, int price, int num) { this.name = name; this.color = color; this.price = price; this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.
simulink仿真步长默认为50步,即步长间隔为stop time/50
图示为y=x+1,仿真时间4s
改仿真为固定步长:
1 在simulink界面按ctrl+E,出现设置页
2 Solver→Solver selection→Type选择Fixed-step。
Fixed-step size(fundamental sample time)修改步长。
3 结果为:
信贷的互金产品归纳起来有两大产品,非循环贷与循环贷产品。这两类产品有差异也有相同点。既然是互金产品,重视贷前模块都是必然的。贷前的欺诈风险及信用风险把控,是在互金中最受重视的部分。
而这两个产品的区别,如对于非循环贷这类业务,基本就是会将授信额度一次性用完,风险在一开始就暴露。而对于循环贷这类业务,会涉及到贷中调额等内容,贷中策略中的提额跟降额策略就显得非常重要。看看此次疫情期间的信用卡业务,某些银行的卡中心纷纷对某些地区的客群大幅度降低其贷中额度,贷中额度策略进一步收紧。
同时随着金融业务发展深化,贷前许多细节均已被覆盖,跟同业人员交流,许多该做的贷前风险内容都已被开拓。后续在市场竞争中,贷中存量的客户经营,贷中的额度调整就是关键的技术点,跟抢占市场的必争桥头堡。本文来谈谈贷中相关调额策略等内容。
一.策略开发流程
额度的策略,看看在这块深耕多年的信用卡业务,与之相关调额的方法论就非常成熟,值得借鉴。本文我们仍以偏向大额的现金贷的调额策略跟大家介绍具体的调额细节。
首先整个策略的开发流程的体系都是基于系统化建设跟科学决策的方法进行的。在整体的流程模块上分成四个部分:
业务策略+业务流程+模型算法+数据管理
业务策略是信贷产品的相关逻辑,这里会涉及产品细则,以及对应的准入策略,白名单用户规则等内容;
业务流程与相关征信数据互相关联,需要把控征信更新的频率与查询优化的细节;
在数据模型开发上,结合业务是为了更好服务业务。模型模块跟算法模块的内容,这里有不同的风控评分模型以及响应模型等;
以上内容都来自数据,数据管理也至关重要。相关数据管理包括数据仓库、交易数据以及账户类数据等内容。
介绍完上述的规则流程后,接下来将上述的内容按照业务策略结合算法模型的角度介绍:
1.白名单准入策略+socreB的置入以及置出策略
2.额度策略矩阵
二.白名单准入策略+socreB的置入以及置出策略
2.1.基础内容介绍:
在以上开发流程的基础上,这里我们会卡上最基础的硬规则+软规则+scoreB
硬规则,HardCheck,就是产品进入的门槛,如年龄在25岁~45岁,就是HardCheck。不在这个年龄范围的一概拒绝。
软规则,即命中多条规则,对应的软规则都有一个规则分的内容。
scoreB,贷中B卡,行为评分模型,估计大家就比较熟悉相关内容。
欺诈B卡的建模目标
a.使用机器学习方法,识别(预估)已持卡6个月以上信用卡客户未来逾期风险。
b.阶段目标是按照客户顶层细分模型,重新衍生新特征变量基础上,提升模型预测效果。
2.2.在白名单的基础上结合B卡如何做风险筛
这里为了解释在白名单的基础上结合B卡的策略,在白名单客群中使用两个B卡,一个是主卡中会用到的B1卡,一个子卡的B2卡。
单只有一个评分B卡的时候,通常我们是使用一个阈值+评分卡的策略做客群筛选。比如在下图中我们选择640分以下的置出,640分以上的置入的策略,两者用虚线切分。显然,这样一刀切的划线方式向来并不是最好的风险把控手段。比如对于评分卡低于640分的,难道就没有好客群吗?对于高于640分的就没有坏人吗?显然这种方法太粗犷了。
做精细化风险管控的,必须进一步做相应的风险客群划分。于是我们在阈值分的基础上,再结合B2卡,一张子卡,进一步做风险客群的筛选。
2.3.具体实操方法参考如下:
①首先,通过一些硬规则和软规则筛选出白名单客群,并剔除近60天人行查询客群,选定B卡分>640分为cutoff,得到老白名单。现需要加入一个大额现金贷准入评分,来替换软规则,通过换出高风险客群换入低风险客群的方法来达到增加白名单范围的目的。
②如上图,图中第一个表格是分数交叉后的个数比例情况,第二个表格是分数交叉后的风险情况。以B卡分大于640分对应的边际风险1.9%进行换入换出。图中黄色部分为新白名单换入的部分,灰色部分为新白名单换出的部分。因此新白名单应为白色区域+黄色区域。新的策略如下:
(Bscore>660&大额现金分>620)且(Bscore介于640和659之间&大额现金分>640)且(Bscore介于620和639之间&大额现金分>680)且(Bscore介于600和619之间&大额现金分>700)且(Bscore介于580和599之间&大额现金分>720)
③在实际操作过程中,有一部分客户会被Bscore这一节点之前的硬规则拒绝,所以会导致没有Bscore分,这是上面没有考虑到的。这里选的1.9%作为风险容忍线,实际情况中这个取值可以根据公司的风险偏好来设定,考虑到评分缺失的客户,阈值可以适当更低一点,留出一些风险缓释垫以确保策略效果和线上效果更为接近。
④根据上图中的新旧白名单切分后的结果,统计相应的客户数量、风险表现,对比新旧白名单的效果(实际与上图有些不符,上图换出3%的客户换入1%的客户)。
旧白名单:800万客户,不良率0.72%;新白名单:900万客户,不良率0.56%。
新白名单较于旧白名单,在扩充白名单客户数量的同时,降低了风险,因此新白名单效果更好。
2.4.风险矩阵跟额度系数
在得到以上的风险新风险报名单后,我们最重要的一个动作便是最这部分的客群进行相关的调额策略。
调额策略在贷中模块是属于关键跟核心模块,在这个细节中,我们继续以实操内容跟大家介绍。
现看下在调额策略前,客群的数据情况:
①调额前:
【调额前】
翻找了相关的调额的历史,可以看到,相关的调额细则如下:
结合这两个表,可以看到额度区间之间没有明显划分,区间无论是纵向跟横向都无法拉开差距。在前述白名单开发完成后,我们决定通过以下维度对新客群进行调额,分别是:
a.分析客群占比
b.分析坏账率
c.分析响应率
以上相关的各项数据如下:
通过以上的客群占比、坏账率、响应率等指标,我们在相关的额度系数矩阵后,定义了相关的额度系数区间:
【调额后】
以上内容参考至:
1:番茄风控的往期《星球课堂》。
2:番茄风控《全线条训练营》。
~原创文章
…
end
(Linux下V4L2相关头文件所在路径为/内核源码目录/include/linux/videodev2.h,V4L2相关API文档可查看链接https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/v4l2.html)
摄像头(相机)常见参数:
白平衡(自动白平衡AWB)及色温、曝光(自动曝光AE、曝光补偿EV)、亮度、对比度、饱和度、色度(色调+饱和度)、锐度(也叫清晰度)、背光补偿(也叫逆光补偿)、增益、对焦等
(注:不同摄像头开放的参数不一致,需提前确认该款摄像头的可调参数,未开放的参数是无法调整的!!!)
上述参数涵义如有不懂,可自行维基百科https://zh.wikipedia.org/wiki/Wikipedia:%E9%A6%96%E9%A1%B5和百度词条百度百科——全球领先的中文百科全书科普。
常见的 ioctl 命令: VIDIOC_QUERYCAP /* 获取设备支持的操作 */ VIDIOC_G_FMT /* 获取设置支持的视频格式 */ VIDIOC_S_FMT /* 设置捕获视频的格式 */ VIDIOC_REQBUFS /* 向驱动提出申请内存的请求 */ VIDIOC_QUERYBUF /* 向驱动查询申请到的内存 */ VIDIOC_QBUF /* 将空闲的内存加入可捕获视频的队列 */ VIDIOC_DQBUF /* 将已经捕获好视频的内存拉出已捕获视频的队列 */ VIDIOC_STREAMON /* 打开视频流 */ VIDIOC_STREAMOFF /* 关闭视频流 */ VIDIOC_QUERYCTRL /* 查询驱动是否支持该命令 */ VIDIOC_G_CTRL /* 获取当前命令值 */ VIDIOC_S_CTRL /* 设置新的命令值 */ VIDIOC_G_TUNER /* 获取调谐器信息 */ VIDIOC_S_TUNER /* 设置调谐器信息 */ VIDIOC_G_FREQUENCY /* 获取调谐器频率 */ VIDIOC_S_FREQUENCY /* 设置调谐器频率 */ 参数控制相关函数及结构体: 函数:ioctl(fd,VIDIOC_QUERYCAP,struct v4l2_streamparm *argp);
Description 给出一个正整数n(1<=n<=100000)。在n的右边加入n的一半,然后在新数的右边再加入n的一半的一半,一直进行,直到不能再加为止。
例如 n=37
37的一半为18(取整数)加到n的右边成为
3718 18的一半为9,加到新数的右边成为
37189 9的一半为4,加到新数的右边成为
371894 4的一半为2,加到新数的右边成为
3718942 2的一半为1,加到新数的右边成为
37189421 1的一半为0,加数结束,最后得到的数是一个8位的数
Input 整数n
Output 加数结束后新数的长度。
Samples 输入数据 1 37 Copy
输出数据 1 8 Copy
Limitation 1s, 1024KiB for each test case.
代码 #include<bits/stdc++.h> using namespace std; int ws(int a) { int s=0; while(a){ a/=10; s++; } return s; } int main() { int n; cin>>n; int x=ws(n); while(n) { n/=2; x+=ws(n); } cout<<x; return 0; }
Description 2022年湖南省《信息与未来》小学夏令营将在衡阳市八中进行,组委会决定在衡阳市八中的学生中推选一名旗手,推选方法如下:
衡阳市八中有n名学生(1<=n<=1000)。每名学生有一个学号,学号为(1,2,3,4......n)。同时,每名同学有一张选票,可以推选一名同学为旗手。最后,得票最多者当选,若得票最多者相同票数,则学号小者当选。
例如n=8,选票为2 3 4 4 3 4 1 6,4号学生得票最多(3票)当选小旗手。
Input n和x1两个整数,n为学生数,x1为第一个选票上的学号,之后的选票Xi(i>=2)由下面的递推关系给出:
Xi=((X(i-1)*37+33031)% n)+1
根据这个公式,就能从X1推导出X2,X3,X4.......Xn.
Output 一个整数,即选出的旗手的学号。
Samples 输入数据 1 5 2 Copy
输出数据 1 2 Copy
Limitation 1s, 1024KiB for each test case.
思路: 根据递推式Xi=((X(i-1)*37+33031)% n)+1,直接带入求值。
代码 #include<bits/stdc++.h> using namespace std; int main() { int n,x1,x[1001],f[1001]; memset(x,0,sizeof(x)); memset(f,0,sizeof(f)); cin>>n>>x1; x[1]=x1; for(int i=2;i<=n;i++) { x[i]=((x[i-1]*37+33031)%n)+1; } for(int i=1;i<=n;i++) { f[x[i]]++; } int max=-1,ans; for(int i=1;i<=n;i++) { if(f[i]>max) { max=f[i]; ans=i; } } cout<<ans; return 0; } //Xi=((X(i-1)*37+33031)% n)+1
系列文章目录 学习使用HAL库进行STM32软件开发 | 开始
学习使用HAL库进行STM32软件开发 | 选择开发环境和开发板
学习使用HAL库进行STM32软件开发 | 官方资料汇总和下载资料
学习使用HAL库进行STM32软件开发 | 安装STM32cubeMX及STM32F4支持包(本文)
文章目录 系列文章目录摘要一、安装cubeMX二、联网安装支持包STM32Cube MCU Package三、不能联网的话如何安装支持包 摘要 使用从官网下载的STM32 cubeMX的安装包进行安装,安装完成之后联网使用软件中的更新功能安装STM32F4的pack。
备注:如果需要安装的电脑不能联网,就在官网把支持包一起下载了,离线安装。
一、安装cubeMX 点击win版安装包,进行安装。
等待安装包自解压。
一路点点点,需要勾选同意的地方就勾上,收集用户信息那里可以根据习惯自己选。
二、联网安装支持包STM32Cube MCU Package 打开cubeMX。
之前没有勾选收集信息,这里弹出来再次询问是否同意收集信息,继续选No thanks。
点 Help > Manage embedded packages,进入安装界面。
找到STM32F4,勾选最新的版本,点Install安装,联网的时候会自动下载并安装。
安装完成之后,STM32F4的支持包显示为已存在,如果需要的话,可以继续用同样的方法安装其他系列芯片的支持包,或者哪天不需要了也可以把对应的支持包卸载。
三、不能联网的话如何安装支持包 需要安装的电脑不能联网的话,就在下载软件安装包的时候,顺便把软件支持包下载了,在下载软件的地方,点工具与软件,在相关的工具和软件中选择STM32F4支持包,点击进入STM32F4支持包的网页。或者直接从st首页一路点点点点到STM32F4支持包的网页:ST > 工具与软件 > 嵌入式软件 > 微控制器软件 > STM32微控制器软件 > STM32Cube MCU和MPU包 > STM32CubeF4 > 获取软件 > STM32CubeF4 > Get last > Dowload。
直接从cubeMX下载链接处跳转:
或者从首页一路点点点。
进入STM32微控制器软件的页面。
往下翻阅,点击ARM Cortex M。
目录
UDP协议:
udp协议格式(实现):
udp协议特性:
影响:
TCP协议: TCP格式(实现):
协议特性: 面向连接: ****tcp连接管理的过程(三次握手四次挥手): 可靠传输:
****传输性能提升各种机制:
面向字节流**: tcp连接管理中的保活机制:
可以说应用层负责规定应用程序之间沟通的方式. 那传输层负责数据能够(准确的)从指定源端口发送到指定对端口.
UDP协议: 用户数据包协议.
udp协议格式(实现): 16位源端端口: 描述源端处理进程是谁. 16位对端端口: 描述对端处理进程是谁,源端与对端端口描述了是哪两个进程之间在进行传输
16位数据报长度: 即报文长度, 为报头长度+实际数据长度,所以实际的数据长度是报文长度减8;
因为udp协议限制了报文最大不超过64k. 则报文中数据大小(上层所sendto给予的大小)必须小于64k-8。否则就会丢弃数据报错
16位校验和: 采用二进制反码求和算法,校验收到的数据与对方发送的数据是否完全一致,不一致则丢弃.
二进制反码求和算法: 发送方组织好报文后,将校验和字段置为0,然后从第0个字节开始(包含报头)对每个字节取反求和,超出16位的,则将高位截断与低16位继续求和,完成之后,将校验和填充到校验和字段中接收方收到数据,从头到尾进行反码求和,这时候如果数据没问题,则刚好得到的结果就是0.
udp协议特性: 无连接: 指只要知道对方的地址就能给对方发送数据, 不需要建立连接.
不可靠: udp没有任何的丢包检测机制,数据包丢了也没有重传机制,并且也没有包序管理机制
因此udp传输既不保证数据能够安全到达对端,也不保证数据有序到达对端
面向数据报: 指一种有最大长度限制的,数据块传输方式, 因为udp协议中限制了一个udp报文必须小于64k(数据必须小于64k-8)
数据块的传输方式: 上层sendto给与一个数据则直接封装报头进行发送,数据到达对端会包括报头存放在接收缓冲区中
上层recvfrom时候每次只能刚好取出一条完整数据,不能取出半条或者多条数据. 因为如果取出半条或者一条半,缓冲区中剩余半边数据,下次取的时候就不知道该取多少, 因此udp通信有一个严格点: 整条传输整条交付 意味着: recvfrom的时候如果你给的buf空间大小比接收的数据长度小则会接收失败.
影响: 1. udp不保证数据安全有序到达,需要程序员自己在应用层进行丢包检测以及包序管理机制以及重传机制,才能保证安全至少要在上层有包序管理。
2. udp面向数据报的,必须保证sendto发送的数据长度必须小于64k-8个字节大小
3. udp是整条交付的,必须保证recvfrom时,给与的空间大小足够大,否则有可能会接收失败
TCP协议: 传输控制协议.
TCP格式(实现): 16位源端端口+16位对端端口: 描述通信两端
32位序号+32位确认序号: 实现tcp的包序管理,以及确认应答机制(丢包检测), 相当于tcp对数据都给予了序号, 接收端再根据序号进行排序.
4位报头长度: 描述tcp报头长度. 因为报头中的选项数据可有可无, 大小为0-40个字节, 所以报头长度最大是60字节,最小20字节, 在解析tcp报头时,先取出固定长度20字节,然后根据报头长度-20取出指定长度的选项数据,剩下应用数据
文章目录 被嗅探的流量镜子里的世界隐藏的钥匙另外一个世界神秘龙卷风[第一章 web入门]常见的搜集web签到 被嗅探的流量 下载后打开题目没有思路,查看别人的wp发现是文件传输找POST的包,用wireshark追踪http流量 http.request.method==POST在文件末尾找到flag
镜子里的世界 打开后是一张图片,隐写套路,查看属性,用winhex打开都没发现什么有用的信息,这时注意到图片名steg想到了用stegslove打开图片,查看图片并没有发现有用的信息,调整后发现flag
隐藏的钥匙 打开后是一张图片,看属性啥也没有,用010打开找到flag
base64解码得到flag
另外一个世界 还是图片,直接扔到010中拉到底发现
很明显是二进制,网上搜索二进制转字符得到flag
神秘龙卷风 打开后一个加密压缩包,直接暴力破解得到
没见过这个东西,看别人的wp发现是brainfuck代码使用
http://bf.doleczek.pl/
运行得到flag
[第一章 web入门]常见的搜集 打开网页提示是敏感文件,尝试查看网页的文件
一些常见的常见的网页后缀
一个个尝试下发现robots.txt发现一个文件
查看这个文件可以得到第一段flag
尝试到index.php~时得到第二段flag
输入.index.php.swp下载一个记事本,打开得到第三段flag
组合得到完整flag
web签到 直接查看源代码
通过MD5解密得到flag
编写一个测试程序,利用 fork-join 并发框架,实现 2000×2000 的随机数矩阵乘法运算,分别对使用并行方法和顺序方法计时。
import java.util.concurrent.*; import java.util.ArrayList; public class Demo { public static void main(String[] args) { final int N = 2000; double[][] matrix1 = new double[N][N]; for (int i = 0; i < matrix1.length; i++) for (int j = 0; j < matrix1[i].length; j++) matrix1[i][j] = Math.random()*100; double[][] matrix2 = new double[N][N]; for (int i = 0; i < matrix2.length; i++) for (int j = 0; j < matrix2[i].
前言:首先我们要明白什么旋转数组?它包括左旋和右旋;我们不妨拿一个例子来解释,更加的容易理解;假设有一组数据:1 2 3 4 5 6 7 8 9:
如果是左旋1次=====》2 3 4 5 6 7 8 9 1
如果是右旋1次=====》9 1 2 3 4 5 6 7 8 通过这个简单的小例子我们就可以理解旋转数组的意思;下面我们来具体分析一下方法吧!
目录
方法1:暴力求解法
1.1 解析:
1.2 具体代码:
左旋代码:
右旋代码:
1.3 代码解析:
方法2:三步翻转法
2.1 解析:
2.2 具体代码:
2.3 代码分析:
方法1:暴力求解法 1.1 解析: 这种方法很好想,也很好理解,但是效率不怎么高!!!
左旋:对于一组数据1 2 3 4 5 6 7 8 9;假设我们是左旋1次;结果是2 3 4 5 6 7 8 9 1;是怎么得到的呢?我们不难发现其实是先把第一个数据拿出来,然后把后面的n-1个数据依次往前移;最后在把首元素的数据放到最后面就行啦,这就需要写一个循环!!!这是左旋转1次的结果,那么如果要旋转k次了怎么办?再在外面写一层循环不就好啦!
右旋:对于一组数据1 2 3 4 5 6 7 8 9;假设我们是右旋1次;结果是9 1 2 3 4 5 6 7 8 ;同样的思路,我们需要把最后一个数据拿出来,然后把前面n-1个数据往后移;最后再把最后一个元素的数据放到最前面就行啦,同样也是两层循环!
#include <stdio.h> #include <math.h> int main() { int n,a,max,min; scanf("%d\n",&n); //int max = 0;//max不能随意赋值。若赋值为0.如果输入的数都是负数,则会输出0,而不是实际的输入最大值 int A[n]; for(int i = 0; i < n; i++){ scanf("%d",&a);//"%d "有空格的话必须多输出一次才能结束程序。但是多输出的那个值并不会被记录。 A[i]=a; min = (min<a)?min:a; } max = min; for (int i = 0; i < n; i++) { max = (max>A[i])?max:A[i]; } printf("%d",max); return 0; } 这道题原本想只用一个max参数,发现max不一定能取到输入的最大值。
int max = 0;//max不能随意赋值。若赋值为0.如果输入的数都是负数,则会输出0,而不是实际的输入最大值 max = (max>a)?max:a;//若是只有一个循环结果如下。 如输入 2
-1 -2
结果会输出0。因为每次比较max都是最大,于是就输出了初始值。
正如上面所说。所以第一次循环是为了找到最小值。将min赋值给max以保证每一次都可以成功比较。
第二次循环就是为了找出最大值。
修改hosts文件 打开访达 按住command+shift+g搜索/private/etc/hosts
然后修改hosts文件
把你想要的域名设置成localhosts一样的ip
修改完成后终端输入sudo vim /etc/hosts查看hosts文件
设置好了后 可以ping一个这个域名 测试一下通不通
如果通的话 项目启动后
原本localhost:8080/的地址可以在浏览器中替换为你配置的域名:8080/
我们可以使用appendChild()函数给节点添加子节点,Node.appendChild() 方法将一个节点附加到指定父节点的子节点列表的末尾处。要注意的是:如果将被插入的节点已经存在于当前文档的文档树中,那么 appendChild() 只会将它从原先的位置移动到新的位置(不需要事先移除要移动的节点)。
这意味着:一个节点不可能同时出现在文档的不同位置,所以如果某个节点已经拥有父节点,在被传递给此方法后,它首先会被从原始父节点中移除,再被插入到新的位置。若要保留已在文档中的节点,可以先使用 Node.cloneNode() 方法来为它创建一个副本,再将副本附加到目标父节点下。请注意,用 cloneNode 制作的副本不会自动保持同步。
前提:最近看到一些网站进行了wasm加密,但是开始没有接触过这个wasm。就花了一点时间来了解wasm 1.了解wasm
这里放个网站 https://www.cntofu.com/book/150/zh/ch1-quick-guide/ch1-02-helloworld.md这个网站我觉得讲的蛮好的。wasm是啥?按照我个人理解哈
就是将c/c++的程序编译成二进制格式.wasm,使之可以在网页中调用。这样速度会更快,毕竟是c语言写的嘛。
专业解释:
WebAssembly是新一代的Web虚拟机标准,C/C程序可以通过Emscripten工具链编译为WebAssembly二进制格式.wasm,进而导入网页中供JavaScript调用——这意味着使用C/C编写的程序将可以直接运行在网页中。
好了,我们大概知道wasm是个啥玩意了,就是运行在浏览器的c/c++代码嘛。那么我们先上手做个小demo。
这里我进行了编译,形成了两个文件
这里我在网页了调用hello.js看看.
可以看到,这里输出了你好,世界,当然,你用nodejs直接运行hello.js也可以得到输出。
2.wasm转c 既然c可以转wasm,那么wasm也应该可以转c。
wasm2c hello.wasm -o hello.c 就会生成hello.c和hello.h两个文件
这里我用的吾爱破解大佬的工具,所以他自动加了些文件。这个hello.c很长。有五千六百多条。
这你敢想?我就仅仅输出了一个你好,世界呀!这么多代码,谁能想到这个是这个仅仅是是个printf呀?
这样麻烦的话,有没有办法就是说简单一点,当然有!我们可以将生成的hello.c和hello.h编译成.o文件放到ida进行分析。
3.编译成o文件 这里用的是吾爱大佬逍遥一仙的文件wasm一键转c - 『原创发布区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn。链接放到这里了。https://www.52pojie.cn/thread-1438499-1-1.html
编译成hello.o文件就可以放到ida进行分析了。这里我放到ida是这样的。
这里就简单多了,但是还是有点麻烦。这里和我们的源代码还是有蛮大的差别。还多了很多函数。这里我知道js调用了main函数。我们就能直接反编译的c文件,将c文件编译成exe或者dll。这样的话,就可以给其他语言使用了。
4.python调用wasm 前面我们说可以将wasm反编译成c语言,再编译成exe或者dll来调用。其实python还带了个模块,叫pywasm。
pip install pywasm import pywasm # pywasm.on_debug() runtime = pywasm.load('./examples/fib.wasm') r = runtime.exec('fib', [10]) print(r) # 55 这里简单调用的例子。这样就可以直接调用wasm。相对来说更加方便。
这里放上两个地址。都是wasm的加密。但是相对来说比较简单。直接调用wasm就行。
https://match.yuanrenxue.com/match/15猿人学15题
https://spa14.scrape.center/崔庆才大大的测试网站的14题
有兴趣可以去试试
兴趣交流群:342096685
PDM 系列目录
1、划时代的 Python 包管理器:PDM 教程 — 入门篇
2、划时代的 Python 包管理器:PDM 教程 — 原理篇
3、划时代的 Python 包管理器 — PDM 局部&全局配置
4、划时代的 Python 包管理器 — PDM 局部&全局项目
5、划时代的 Python 包管理器 — PDM 缓存机制
6、读者问:如何让 PyCharm 支持 PDM ?
在之前的一篇文章中(来了!划时代的 Python 包管理工具 – PDM),我详细介绍了 PDM 的保姆级入门用法。
之前一直想着出一篇 PDM 的高级篇,却一直食言,当然更主要的是好像也没人催。
写长一点的文章,需要投入长达几个小时的时间与精力,因此打算以这种小知识点的形式开展下去,写得不会很累,重要的是能保持稳定输出。
今天介绍一下 PEP 582 的原理,说说 PDM 是如何做到本地包目录的支持的?
在 pdm 的环境之下,它是优先从项目里的 __pypackages__ 搜索包的(安装时也是如此)
这是如何实现?其实原理非常简单。
使用 -m site,可以查看当前 Python 环境包搜索目录的顺序
从下图可以看到使用 pdm 工具后,无疑就是在全局的 site-packages 目录之前加上项目目录里的 __pypackages__ 路径,使得 __pypackages__ 的搜索优先级高于全局的 Python 环境。
poly2trellis poly2trellis由卷积码的生成多项式产生trellis图,它的输出主要取决于函数convenc和vitdec的输入。
前向反馈卷积码:trellis = poly2trellis(7,[171,133]);
convenc是卷积码的编码函数: 1.code = convenc(msg,trellis);
2.code = convenc(msg,trellis,puncpat);
注释:
puncpat参数的意思:用于指定打孔方式已获得更高的码率。
puncpat是由1或者0组成的向量,其中0的位置为打孔比特,puncpat的长度至少有log2(trellis.numOutputSymbols)个比特。 有个三个输出的trellis,每个输出有两个取值(0或者1)所以trellis.numOutputSymbols=2^3=8
函数vitdec 函数vitdec 采用Viterbi算法对卷积码进行译码。
decode = vitdec(code,trellis,tblen,opmode,dectype);
tblen是一个正整数参数,指定回溯深度,如果码率为1/2,tblen的一个典型值是约束长度的5倍。
字符串opmode指定译码器的操作模式和相应的编码器的假设,他有三个选择:
1.‘cont’:认为编码器从零状态开始编码,编码器从最佳路径回溯,有tblen的延迟。
2.‘term’:认为编码器从零状态开始,并且结束于零状态。
3.‘trunc’:认为编码器从零状态开始编码。该模式没有延迟。
字符串dectype指定译码器的判决类型,并影响译码器code的数据类型。
1.‘unquant’:code包含实输入,其中1表示逻辑0,-1标示逻辑1.
2.'hard':code为二进制输入。
3.‘soft’:有限比特量化软判决译码,软判决译码需要参数nsdec.
decode = vitdec(code,trellis,tblen,opmode,'soft',nsdec);对向量code进行软判决译码。code为从0到2^nsdec-1的整数,其中0表示0,2^nsdec-1表示1.
decode = vitdec(code,trellis,tblen,opmode,dectype,puncpat);表示code是打孔的,参数puncpat是打孔类型向量,其中0表示输入编码结果中打孔的比特。
什么是工业物联网网关 工业物联网网关(IIoTGateway)是一种硬件设备或软件程序,作为本地设备(如PLC、扫码枪、机器人、数控机床、非标上位机等)与云端系统(如物联网平台、SCADA系统、MES系统等)之间的桥梁,在设备和云端之间流动的所有数据都通过IoT网关,如下图所示:
数据的流向 设备到云端的通信(数据采集)
云端到设备的通信(反向控制)
设备到设备的通信(M2M)
基于.NET6的开源工业物联网网关 受益于.NET在工控以及医疗等领域的长期积累,网上的确分散着很多通信相关的dll、源码和项目,但至今没有基于B/S架构的开源项目,这也是本项目的初衷。
依托.NET6开源、跨平台、高性能的特点,以及WTM 框架的低代码开发方式,快速搭建起网关应用。目前已完成遥测和属性的上传,反向控制正在开发中。
项目地址
github:iotgateway: https://github.com/iioter/iotgateway/ gitee:iotgateway: https://gitee.com/iioter/iotgateway/
项目文档:http://42.193.160.84/
在线体验:http://42.193.160.84:518/
开源网关具有以下特点 跨平台运行 既可以是windows,也可以是linux系统;
既可以是主机运行,也可以通过docker运行;
既可以是x86主机,也可以是arm32、arm64嵌入式开发板。
内置多种驱动 驱动可以看做公司的一种无形资产。目前提供Modbus完整协议、西门子全系列PLC、三菱QPLC、欧姆龙PLC、ABPLC、MTConnect数控机床等驱动。当然你也可以通过驱动Demo实现自己的驱动,也可以集成业内流行的IoTClient(码农一生)、HSL(胡工)等提供的驱动进行整合。
计算表达式 类似于js等脚本语言,C#也可以作为脚本进行动态编译执行,你可以随时修改表达式对数据进行二次计算,不只是倍率的计算哦。
MQTT服务 内置MQTT Server,可以通过订阅数据与你的业务系统进行集成,当然网关也可以作为MQTT客户端,将数据推送到你的MQTT服务中去。
OPCUA服务 内置OPCUA Server,你的工控系统可以很方便的获取数据。注意,项目中OPCUA相关功能仅用作学习及测试,若使用OPCUA协议请联系OPC基金会进行授权,产生一切纠纷与本项目无关。
数字孪生3D可视化 通过使用threejs搭建了数字孪生的demo,前端通过基于WebSocket的Mqtt协议订阅数据变化,实时获取数据更新,而不是通过WebAPI轮训。
在线组态 无缝集成在线组态项目,快速设计和部署你的可视化应用。
为什么需要物联网网关 协议转换 面对不同年代、不同厂家、不同协议的设备多少会让人头疼,IoT网关会帮助你屏蔽协议的差异,转换为常用的物联网协议(如MQTT、HTTP等)输出到平台端,让你有更多时间专注于平台端的业务建设。
保证安全 所有物联网设备都有被外部影响和攻击的可能,但IoT网关在互联网和设备本身之间增加了另外一层,大幅度减少了连接到互联网的设备的数量,网关变成了第一道防线,进而防止外部各方对物联网设备进行未经授权的控制。
容易扩展 在工业现场的高度分散性的前提下,随着连接的设备数量不断增加,不同协议设备的持续接入,只能通过网关来管理和控制这些复杂的变化,而不是以往牵一发而动全身的痛苦的升级。
数据处理 1、数据预处理
如倍率、偏移量处理等,这有助于边缘计算的发展,因为他本身就是边缘智能的一种简单应用。
2、数据过滤
设备产生的海量数据中,全部发送到平台端肯定是不堪重负的,一方面传输、处理和存储都是有成本的;另一方面可能只有一部分是需要关注的,如变化的产量,就需要变化才上传,一直推送不变的值是没有意义的。
3、数据汇总和聚合
有些场景下不同设备或相同设备的不同变量是需要聚合计算后发送到平台端的,有些原始数据没有特别大的价值,当然这也可以分担一部分平台端的压力。
4、数据缓存
网络通信不是100%可靠的,断线时IoT网关既需要暂存数据,当网络恢复后发送至云端;又需要存储云端的控制策略,让控制流程及时执行。
目录 一.什么是面向过程
1.面向过程的缺点
2.面向过程的优点
补:简单介绍代码与代码之间的耦合度
二.什么是面向对象
三.面向过程与面向对象有什么区别
一.什么是面向过程 面向过程主要的特点是注重 实现这个功能的步骤. 第一步干什么,第二步干什么......
另外面向过程也注重 实现功能的因果关系. 因为......所以......
1.面向过程的缺点 面向过程是每一步与每一步的因果关系,其中A步骤因果关系到B步骤.A和B结合起来形成一个子模块,子模块又和子模块之间因为因果关系结合在一起,假设其中 任何一个因果关系出现问题 (错误),此时 整个系统的运转都会出现问题. (代码与代码之间的 耦合度太高,扩展力差 !)
2.面向过程的优点 对于小型项目,采用面向过程的方式开发, 效率较高 .可以直接开始干活,写代码来实现功能,并不需要前期对对象提取什么的!
补:简单介绍代码与代码之间的耦合度 代码与代码之间的耦合度就是 代码与代码之间的粘连程度.粘连程度越紧密,耦合度就越高!
举个例子:螺栓与螺母
螺栓与螺母 拧在一起 ,这个时候的 耦合度低 ,因为它们还可以拧开,它们之间存在着接口.如果螺栓和螺母 拧在一起,再用焊条焊接起来 ,这个时候的 耦合度就比较高 .因为完全分不开. 二.什么是面向对象 面向对象的开发形式更注重对象A,对象B,对象C,然后组合起来的对象ABC或对象CBA!
采用面向对象的方式进行开发,更符合人类的思想方式.人类就是以"对象"的方式去认识世界的.也正是因为这个,面向对象才成为主流的原因!面向对象就是将现实世界分割成不同的单元,然后 每个单元都实现成对象 ,然后驱动一下,让 各个对象之间协作起来形成一个系统.
举个例子:对象"张三" , 对象"香烟" , 对象"打火机" , 对象"吸烟的场所"
这4个对象组合在一起就可以模拟一个人的抽烟场景.其中对象"张三"可以更换成"李四",对象"香烟",对象"打火机",对象"吸烟的场所"也可以进行更换!这样的话 耦合度低,并且扩展力很强!
三.面向过程与面向对象有什么区别 从 语言方面 出发:
对于C语言是完全面对过程的.C++是一般面向过程,一半面向对象的,也就是半面向对象的.JAVA语言是完全面向对象的! 在上述面向过程与面向对象的介绍里,已经看的很清楚了他们之间的区别,对吧!那么咱们来看一看实际的例子加深一下理解!
假如现在需要开发一个计算机!
如果用 面向过程 的方式来开发一个计算机!那么就不存在任何一个部件,所有的东西都融合在一起,成为了一个一体机!如果说计算机的某个地方坏掉了,那么这整个计算机都坏掉了,就直接废掉挂闲鱼了(估计咸鱼挂不上!哈哈哈哈哈)! 如果用 面向对象 的方式来开发这个计算机!那么内存条就一个对象,主板是一个对象,CPU是一个对象,硬盘等等电脑任何一个部件都是一个对象!.然后把所有对象组合在一起形成了电脑!这个是个哪个地方坏掉了,我们就找到这个对象,然后换掉那个对象就欧克了!例如内存条快掉了,就换个内存条就木有问题了啦!这样的耦合度就很低,扩展力很强的有木有! 再简单举个例子!咱们洗衣服是很常见的对吧!
面向过程 时:我们需要第一步脱衣服 ------> 第二步放到盆里 ------> 第三步倒洗衣粉 ------> 第四步倒水浸泡 ------> 第五步手洗衣服 ------> 第六步清洗衣服 ------> 第七步拧干 ------>第八步晾衣服而 面向对象 时:脱衣服 ------> 找到对象全自动洗衣机(该洗衣机具备洗衣服的功能) ------> 晾衣服 这样一比较,是不是就发现自己爱上面向对象了!
本文首发于 Nebula Graph Community 公众号
互联网金融的借贷同传统信贷业务有所区别,相较于传统信贷业务,互联网金融具有响应快、数据规模大、风险高等特点。众安保险主要业务是做信用保证保险,为了服务业务,大数据团队搭建了风控系统用于处理互联网借贷的决策问题。本文主要讲述 Nebula Graph 是如何通过众安保险的选型,以及 Nebula Graph 又是如何落地到具体业务场景帮助众安保险解决风控问题。
业务背景 有别于传统银行的信贷业务十天、半个月的申请审核时长,互联网金融借贷第一个特点便是申请审核非常快,可能用户上一秒刚在手机端提交授信申请,下一秒系统便会返回授信申请的结果。此外,互联网金融借贷还有一个特点:数据信息的真实性难以保证,用户填写的信息:年收入、家庭关系、联系人都会存在信息不实的情况。而这两个互联网金融的特点催生了一个产业,就是网络黑产。通俗来说,网络黑产就是用户薅“借贷”羊毛的行为。因为网络借贷隐匿性强,一旦黑产账号实施了欺诈行为后,通过互联网很难追踪到特定的人。此外,由于借贷审批时效性的关系,黑产账号能很方便地做到走量、薅到更多的钱。基于此,催生互联网金融的风控需求,需要系统甄别欺诈场景。
那如何甄别网络黑产呢?通过用户与不同实体、设备、GPS 与手机号之间的关联关系,以及社群发现查看社群中的个体是否有欺诈风险、进行反欺诈的个案调查,能很好地进行借贷风控。目前,众安保险的风控是基于 Nebula Graph 实现的。
为什么选择 Nebula Graph 在众安保险技术选型之初,团队成员调研过图数据库市场的产品,首先筛选出了 JanusGraph、OrientDB。
先来说下 JanusGraph,在众安金融事业技术团队内部 JanusGraph 有一大优势:团队成员对它熟悉,不少工程师使用过 JanusGraph,这从某种程度上降低了图数据库开发、上手成本。使用过 JanusGraph 的研发都知道它是一个分布式图数据库,存储、索引依赖开源组件,例如:HBase(存储)、Elasticsearch(索引)。而之前公司的某个业务线曾使用过 JanusGraph,底层搭载线上 HBase 存储服务,而该业务相对独立和其他核心业务不存在强依赖关系。“不同的国家有不同的国情,一旦相同机制硬搬到不同的国家,可能会出现水土不服问题”,目前众安保险风控业务的基础数据存储在 HBase 中,假如风控系统使用 JanusGraph 的话,将上百亿图数据完全导入 HBase 会对 HBase 集群产生影响、增加查询毛刺,导致其他业务线受到影响。此外,在大规模写入速度性能方面,JanusGraph 导入较慢。综合上述原因,即便 JanusGraph 具有低上手成本,但其强依赖其他组件、导入性能差,所以 JanusGraph pass。
在图数据库产品调研过程中,我们发现 OrientDB 在 DB-Engine 排名较前、功能完善。经过性能测试,发现在小规模数据集下使用 OrientDB 体感良好,但一旦 Mock 数据过亿,大规模数据集下使用 OrientDB 会遇到 Server 端频繁报错问题。查阅 OrientDB 官方文档无果之后,众安保险向 OrientDB 官方 GitHub 仓提交了 issue。但是 OrientDB 反馈响应慢,在提交 issue 的过程中,我们还发现大规模数据集 Server 端频繁报错问题社区用户两年前提交过,issue 仍未解决处于 open 状态。此外,在大规模数据写入性能方面,写入点的速度尚可接受,但写入边的 QPS 只有 1-2k,用这个速度开始图数据建模的话耗时将在天级别,这是不可接受的。综上,虽然 OrientDB 排名靠前、功能完善,但大规模数据频繁 Server 报错、社区 issue 响应慢、大规模写入速度不佳导致最后我们没有选择 OrientDB。
先决条件
硬盘分区,发现/dev/nvme0n1p1并挂载
1. 查看硬盘所有分区
sudo fdisk -lu 可以看到 /dev/nvme0n1 就是我们加的固态硬盘,还没有使用
2. 给硬盘分区
使用 fdisk 对硬盘进行分区
sudo fdisk /dev/nvme0n1 在 Command(m for help)提示符后面输入 m,查看支持的命令;
在 Command(m for help)提示符后面输入 n,执行 add a new partition 指令给硬盘增加新分区;
Partition type: 输入p
出现 Partition number (1-4) 时,输入1
后续指定硬盘分区大小,默认起始地址为 2048,结束地址为:按 ENTER,填入默认值;后续指定硬盘分区大小,默认起始地址为 2048,结束地址为:****,不输入数字的话按 ENTER,将填入默认值;
在这里插入图片描述
在 Command(m for help)提示符后面输入 p,打印分区情况,可以看到已完成分区;
在 Command(m for help)提示符后面输入 w,保存分区表。退出。
再次输入
sudo fdisk -lu 查看硬盘分区,显示 /dev/nvme0n1p1 则表示分区完成
3. 格式化硬盘
输入命令
sudo mkfs -t ext4 /dev/nvme0n1p1 4.
文章目录 一、AF_UNIX 本地通信1. Linux进程通信机制2. socket本地域套接字AF_UNIX3. demo示例 二、AF_INET域与AF_UNIX域socket通信原理对比1. AF_INET域socket通信过程2. AF_UNIX域socket通信过程3. 相同点4. 不同点5. 使用场景 三、PF_INET和AF_INET、PF_UNIX和AF_UNIX之间的区别四、参考资料 一、AF_UNIX 本地通信 1. Linux进程通信机制 linux本地进程间通讯,大概有如下几种方式,socket本地域套接字是其中的一种。
项目中,主应用和协议栈两个进程间通讯,就是用的socket本地域套接字。(需要自定义数据协议格式,一般定义好协议格式头+数据+尾即可)
2. socket本地域套接字AF_UNIX 用于本地进程间的通信。
基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC 更有效率 :
不需要经过网络协议栈不需要打包拆包、计算校验和、维护序号和应答等,可靠性更强 只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
3. demo示例 https://blog.csdn.net/m0_37542524/article/details/84668406
二、AF_INET域与AF_UNIX域socket通信原理对比 转自:https://blog.csdn.net/sandware/article/details/40923491
1. AF_INET域socket通信过程 典型的TCP/IP四层模型的通信过程。
发送方、接收方依赖IP:Port来标识,即将本地的socket绑定到对应的IP端口上,发送数据时,指定对方的IP端口,经过Internet,可以根据此IP端口最终找到接收方;接收数据时,可以从数据包中获取到发送方的IP端口。
发送方通过系统调用send()将原始数据发送到操作系统内核缓冲区中。内核缓冲区从上到下依次经过TCP层、IP层、链路层的编码,分别添加对应的头部信息,经过网卡将一个数据包发送到网络中。经过网络路由到接收方的网卡。网卡通过系统中断将数据包通知到接收方的操作系统,再沿着发送方编码的反方向进行解码,即依次经过链路层、IP层、TCP层去除头部、检查校验等,最终将原始数据上报到接收方进程。
2. AF_UNIX域socket通信过程 典型的本地IPC,类似于管道,依赖路径名标识发送方和接收方。即发送数据时,指定接收方绑定的路径名,操作系统根据该路径名可以直接找到对应的接收方,并将原始数据直接拷贝到接收方的内核缓冲区中,并上报给接收方进程进行处理。同样的接收方可以从收到的数据包中获取到发送方的路径名,并通过此路径名向其发送数据。
3. 相同点 操作系统提供的接口socket(),bind(),connect(),accept(),send(),recv(),以及用来对其进行多路复用事件检测的select(),poll(),epoll()都是完全相同的。收发数据的过程中,上层应用感知不到底层的差别。
4. 不同点 1 建立socket传递的地址域,及bind()的地址结构稍有区别:
socket() 分别传递不同的域AF_INET和AF_UNIX
bind()的地址结构分别为sockaddr_in(制定IP端口)和sockaddr_un(指定路径名)
2 AF_INET需经过多个协议层的编解码,消耗系统cpu,并且数据传输需要经过网卡,受到网卡带宽的限制。AF_UNIX数据到达内核缓冲区后,由内核根据指定路径名找到接收方socket对应的内核缓冲区,直接将数据拷贝过去,不经过协议层编解码,节省系统cpu,并且不经过网卡,因此不受网卡带宽的限制。
3 AF_UNIX的传输速率远远大于AF_INET
4 AF_INET不仅可以用作本机的跨进程通信,同样的可以用于不同机器之间的通信,其就是为了在不同机器之间进行网络互联传递数据而生。而AF_UNIX则只能用于本机内进程之间的通信。
5. 使用场景 AF_UNIX由于其对系统cpu的较少消耗,不受限于网卡带宽,及高效的传递速率,本机通信则首选AF_UNIX域。
不用多说,AF_INET则用于跨机器之间的通信。
三、PF_INET和AF_INET、PF_UNIX和AF_UNIX之间的区别 https://blog.
Centos 7离线安装MySql8 linux版本:Centos 7
mysql版本:mysql-8
一、安装 1、下载mysql离线安装包 下载地址:https://dev.mysql.com/downloads/mysql/
选择如下:
【Red Hat Enterprise Linux 7 / Oracle Linux】
【Red Hat Enterprise Linux 7 / Oracle Linux 7 (x86, 64-bit)】
2、上传tar包至服务器 在服务器home目录下创建一个mysql目录 cd .. cd home mkdir mysql 上传tar包到mysql目录 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8hVFZMiE-1648180679224)(C:\Users\15005\AppData\Roaming\Typora\typora-user-images\image-20220323115754094.png)]
3、删除原有的mariadb 先查看一下是否已经安装了,命令:
rpm -qa|grep mariadb 删除mariadb,命令:
rpm -e --nodeps mariadb-libs 4、解压缩mysql离线安装包 cd/home/mysql tar -xvf mysql-8.0.28-1.el7.x86_64.rpm-bundle.tar 解压缩之后,包含以下rpm包
mysql-8.0.28-1.el7.x86_64.rpm-bundle.tar mysql-community-icu-data-files-8.0.28-1.el7.x86_64.rpm mysql-community-client-8.0.28-1.el7.x86_64.rpm mysql-community-libs-8.0.28-1.el7.x86_64.rpm mysql-community-client-plugins-8.0.28-1.el7.x86_64.rpm mysql-community-libs-compat-8.0.28-1.el7.x86_64.rpm mysql-community-common-8.0.28-1.el7.x86_64.rpm mysql-community-server-8.0.28-1.el7.x86_64.rpm mysql-community-devel-8.0.28-1.el7.x86_64.rpm mysql-community-test-8.0.28-1.el7.x86_64.rpm mysql-community-embedded-compat-8.0.28-1.el7.x86_64.rpm 5、安装rmp包 逐个安装,命令如下:
rpm -ivh mysql-community-common-8.
文章目录 一、前言二、什么是OAuth2?三、应用场景四、三部分五、四种授权模式1. 授权码模式(authorization code)2. 简化模式(implicit)3. 密码模式(resource owner password credentials)4. 客户端模式(client credentials) 六、编程1、授权服务a、引入依赖b、`application.yml`配置c、Security 核心配置类d、配置生成token存储e、自定义JWT返回信息f、配置添加JWT额外信息j、授权服务器配置 2、资源服务a、引入依赖b、`application.yml`配置c、配置生成token存储d、资源服务器配置e、测试api 3、第三方应用a、引入依赖b、`application.yml`配置c、index.htmld、测试apie、Token获取和定时刷新任务 4、测试 七、本文案例demo源码 一、前言 Spring Security(1) 入门体验Spring Security(2) 自定义登录认证Spring Security(3) 动态url权限控制Spring Security(4) 整合JWT 二、什么是OAuth2? OAuth 是一个开放标准,允许用户授权第三方应用访问他们在某网站上存储的私密资源(ex:用户昵称、头像等),在这个过程中无需将用户名和密码提供给第三方应用。
即以令牌token换资源信息数据。
三、应用场景 第三方应用授权登录,ex:QQ、微信授权登录
四、三部分 第三方应用授权服务器资源服务器 五、四种授权模式 1. 授权码模式(authorization code) 常用模式,主流第三方验证
第三方应用引导用户跳转到授权服务器的授权页面,授权后,授权服务器生成认证码code,然后携带code重定向返回第三方应用使用认证码code和自身应用凭证(app_id和app_secret)到授权服务器换取访问令牌(access_token)和更新令牌(refresh_token)第三方应用使用访问令牌(access_token)去资源服务器获取资源信息(ex:用户昵称,头像等) 2. 简化模式(implicit) 适用于只有前端,前端单方面即可完成
用户在第三方网站上点击授权跳转授权服务器,授权后,携带访问令牌(access_token)返回第三方网站第三方网站再携带 access_token 去资源服务器获取用户信息(昵称,头像等) 3. 密码模式(resource owner password credentials) 适用于自家公司搭建的授权服务器,给兄弟公司用
直接使用用户名/密码从授权服务器获取访问令牌(access_token)
4. 客户端模式(client credentials) 此过程中无需用户参与,一般用于提供给完全信任的服务端服务
客户端请求就返回访问令牌(access_token)
六、编程 参考 https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI1NDY0MTkzNQ==&action=getalbum&album_id=1319833457266163712
^_^建议跟着这个大佬的OAuth2系列学习下^_^
项目端口备注auth10010授权服务器client10020第三方应用user10030资源服务器 oauth2.sql
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- 建库 create database if not exists oauth2 default charset = utf8mb4; use oauth2; -- ---------------------------- -- Table structure for oauth_client_details -- ---------------------------- DROP TABLE IF EXISTS `oauth_client_details`; CREATE TABLE `oauth_client_details` ( `client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客户端ID,唯一标识', `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客户端访问秘钥,BCryptPasswordEncoder加密算法加密', `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '可访问资源id(英文逗号分隔)', `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '授权范围(英文逗号分隔)', `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '授权类型(英文逗号分隔)', `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '重定向uri', `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '@PreAuthorize(\"
第十二届蓝桥杯C++B 组真题 试题A. 空间 小蓝准备用256MB的内存空间开一个数组,数组的每个元素都是32 位二进制整数。
如果不考虑程序占用的空间和维护内存需要的辅助空间,请问256MB 的空间可以存储多少个32 位二进制整数?
1MB= 1024KB 1KB= 1024B 1B= 1b
#include <iostream> using namespace std; int main() { cout << 256 * 1024 * 1024 / 4; return 0; } 试题B 卡片 小蓝有很多数字卡片,每张卡片上都是数字0 到9。
小蓝准备用这些卡片来拼一些数,他想从1 开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。
小蓝想知道自己能从1 拼到多少。
例如,当小蓝有30 张卡片,其中0 到9 各3 张,则小蓝可以拼出1 到10,但是拼11 时卡片1 已经只有一张了,不够拼出11。
现在小蓝手里有0 到9 的卡片各2021 张,共20210 张,请问小蓝可以从1拼到多少?
提示:建议使用计算机编程解决问题。
依次取出每个数的每个位数,
注意:当小于0的时候说明当前数已经算过了i,所以i需要减1, 可以用个小数模拟一下
#include <iostream> using namespace std; int a[11]; bool check(int n) { while(n) { int t = n % 10; if(-- a[t] < 0) return true; n /= 10; } return false; } int main() { for(int i = 0; i < 10; i ++) a[i] = 2021; for(int i = 1; ; i ++) { if(check(i)) { cout << i - 1; return 0; } } } 试题C 直线 在平面直角坐标系中,两点可以确定一条直线。
磁盘阵列RAID
说到这里,也是很尴尬前段时间测试,就提到RAID,不懂这个原理。。。。
多个磁盘合成一个“阵列”来提供更好的性能、冗余,或者两者都提供
RAID的好处:
1、提高IO能力,可以实现磁盘并行读写
2、提高耐用性,通过磁盘冗余来实现
3、级别:多块磁盘组织在一起的工作方式有所不同
RAID实现的方式
外接式磁盘阵列:通过扩展卡提供适配能力
内接式RAID:主板集成RAID控制器,安装OS前在BIOS里配置
软件RAID:通过OS实现
通常情况下,是通过硬RAID来实现
RAID级别
RAID-0:条带卷,strip
RAID-1:镜像卷,mirror
RAID-2 ..
RAID-5
RAID-6
RAID-10
RAID-01
RAID-0:
特点:
1、可以同时进行读写,很明显读、写性能提升;无容错能力;
2、最少磁盘数:2, 2+
缺点:将一份数据均等放在不同硬盘上,如果有一块硬盘损坏,数据就会损坏不能用,目前基本不用;容错性太差。
RAID-1:
特点:
读性能提升、写性能略有下降可用空间:1*min(S1,S2,...) 有冗余能力最少磁盘数:2, 2N 缺点:
1、两块硬盘读写性能提升,自动同步,另一块相当于镜像;如果损坏的话,均损坏
2、磁盘利用率明显降低
RAID-4:
特点:
多块数据盘异或运算值存于专用校验盘 如果损坏的话,通过异或校验位来找回来读写并行;具有容错性 缺点:
通过校验位占用了其中一块的空间,磁盘利用率为n-1/n (n>=3 )校验盘磁盘压力,容易损坏 RAID-5:
特点:
读、写性能提升可用空间:(N-1)*min(S1,S2,...)有容错能力:允许最多1块磁盘损坏 最少磁盘数:3, 3+解决了校验盘压力大的缺陷,均等分配磁盘压力 缺点:
如果损坏的话,需要降级使用在某些安全等级高的情况下,也基本不适用 RAID-6:
特点:
读、写性能提升可用空间:(N-2)*min(S1,S2,...)有容错能力:允许最多2块磁盘损坏最少磁盘数:4, 4+ RAID-10:
特点:
读、写性能提升可用空间:N*min(S1,S2,...)/2有容错能力:每组镜像最多只能坏一块最少磁盘数:4, 4+兼顾了RAID0和RAID1,磁盘利用率50% RAID-01
特点:
多块磁盘先实现RAID0,再组合成RAID1,磁盘利用率50%
相较于RAID10,RAID01相对较差
RAID-50
EnvironmentPostProcessor实现属性文件加载原理 关于EnvironmentPostProcessor自定属性文件加载可以参考官网Customize the Environment or ApplicationContext Before It Starts
本文以springboot2.6为例,讲解EnvironmentPostProcessor实现文件加载原理,EnvironmentPostProcessor子类实现的加载本质上SpringFactoriesLoader进行类的加载,加载时机是通过ApplicationEnvironmentPreparedEvent事件监听来实现。
SpringBoot2.4以前是ConfigFileApplicationListener,SpringBoot2.4+是通过EnvironmentPostProcessorApplicationListener,SpringBoot2.4版本对外部配置进行大幅度调整,由于ConfigFileApplicationListener过于笨重职责过多替换成EnvironmentPostProcessorApplicationListener、ConfigDataEnvironmentPostProcessor来实现。
关键类方法 ConfigFileApplicationListener (SpringBoot2.4前) org.springframework.boot.context.config.ConfigFileApplicationListener#onApplicationEnvironmentPreparedEvent方法
EnvironmentPostProcessorApplicationListener(SpringBoot2.4+) org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent方法
详细分析 SpringBoot2.4+ 源码解析 SpringBoot启动发布ApplicationEnvironmentPreparedEvent org.springframework.boot.SpringApplication.prepareEnvironment方法
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) { // Create and configure the environment ConfigurableEnvironment environment = getOrCreateEnvironment(); configureEnvironment(environment, applicationArguments.getSourceArgs()); ConfigurationPropertySources.attach(environment); //发布ApplicationEnvironmentPreparedEvent事件 listeners.environmentPrepared(bootstrapContext, environment); DefaultPropertiesPropertySource.moveToEnd(environment); Assert.state(!environment.containsProperty("spring.main.environment-prefix"), "Environment prefix cannot be set via properties."); bindToSpringApplication(environment); if (!this.isCustomEnvironment) { environment = convertEnvironment(environment); } ConfigurationPropertySources.attach(environment); return environment; } EnvironmentPostProcessorApplicationListener收到ApplicationEnvironmentPreparedEvent事件并处理EnvironmentPostProcessor子类 //事件回调处理 @Override public void onApplicationEvent(ApplicationEvent event) { //判断事件类型 if (event instanceof ApplicationEnvironmentPreparedEvent) { onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event); } if (event instanceof ApplicationPreparedEvent) { onApplicationPreparedEvent(); } if (event instanceof ApplicationFailedEvent) { onApplicationFailedEvent(); } } private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) { ConfigurableEnvironment environment = event.
在非MFC工程中.就包含atlstr.h
在MFC工程中.就包含afx.h
一般我们会使用MFC in ShareDLL的方式
然后需要包含stdafx.h 避免一些编译错误
stdafx.h的内容如下
#pragma once
#ifdef _DEBUG
#define _AFXDLL
#endif
#include <afxwin.h>
在代码中正常使用 CString 就可以了 不需要ATL::CString去引用,也没有二义性的问题
注意:#include "stdafx.h"要放在引用的cpp文件的最上面
二.判断语句练习题 demo01 代码:
set1 = "1\t3\t5\t7\n" \ "9\t11\t13\t15\n" \ "17\t19\t21\t23\n" \ "25\t27\t29\t31\n" set2 = "2\t3\t6\t7\n" \ "10\t11\t14\t15\n" \ "18\t19\t22\t23\n" \ "26\t27\t30\t31\n" set3 = "4\t5\t6\t7\n" \ "12\t13\t14\t15\n" \ "20\t21\t22\t23\n" \ "28\t29\t30\t31\n" set4 = "8\t9\t10\t11\n" \ "12\t13\t14\t15\n" \ "24\t25\t26\t27\n" \ "28\t29\t30\t31\n" set5 = "16\t17\t18\t19\n" \ "20\t21\t22\t23\n" \ "24\t25\t26\t27\n" \ "28\t29\t30\t31\n" day=0 print(set1) num=int(input("上面是否有你的生日? 1为有;2为无:")) if num==1 : day=1 print(set2) num=int(input("上面是否有你的生日? 1为有;2为无:")) if num==1 : day+=2 print(set3) num=int(input("上面是否有你的生日? 1为有;2为无:")) if num==1 : day+=4 print(set4) num=int(input("
新版Zotreo插件 一、开源翻译插件二、青柠学术的Zotero IF插件三、Zotero搜索引擎四、参考文献五、本文各项插件均可直接获取,插件获取方式见文未【获取方式】:关注微信公众号“舒意的碎碎念”,回复“新版zotero插件”,即可获取所有插件压缩包 一、开源翻译插件 由于Zotero更新了内置PDF阅读器并推出了手机端APP,具体配置见上篇。然而,由于Zoter内置PDF阅读器并没有翻译功能,因此本文介绍一款开源翻译插件,此插件可以在Github上直接获得,链接:https://github.com/windingwind/zotero-pdf-translate,本文也会将所有插件总结后放在一起分享,插件获取方式在文末。
插件安装方法:Zotero左上角点击工具–插件,出现以下页面,点击右上角小齿轮,选择Install Add-on From File,选中需要导入的插件(例如此处的开源翻译软件就是:zotero-pdf-translate.xpi),点击右下角的打开,在新页面中点击Install now即可安装,安装成功后重启Zotero即可开始使用。
开源翻译软件的使用:在安装插件并重启Zotero后就可以使用翻译软件,以随机打开的一篇文献为例,有两种查看翻译的方式:
一种是直接鼠标选中要翻译的段落,就可以看到下方出现翻译的文字
另一种方法是点击右上角的信息图标,即可看到有Translate选项,点击该选项即可看到刚刚鼠标选中的文字及翻译也在这里同步显示,在此栏中还可以对选中的原文和翻译进行复制
二、青柠学术的Zotero IF插件 青柠学术一直在更新Zotero IF插件,可以查询文献的影响因子等功能,具体功能可以关注青柠学术公众号,这里不作具体阐述。本文所有插件都已打包放在百度网盘内,获取方式见文末。
三、Zotero搜索引擎 利用Zotero的搜索引擎可以实现一些便捷搜索,例如选中某一文献,可以利用搜索引擎直接利用浏览器跳转到该文献所在页面;也可以和wolai我来联动(青柠学术);还可以打开海外版知网、知乎首页等多项功能。本文对网络上部分搜索引擎的代码进行汇总整理,整理后的插件也放在百度网盘中,文件名为:engines.json,文件获取方式见文末。
安装方式
(1)在Zotero首页选择编辑–首选项–高级,在此项内选择文件和文件夹,点击“数据存储位置”内的打开数据文件夹
(2)在打开的文件夹内选择locate文件夹,文件夹内有与本文提供的同名文件engines.json,将本文提供的该文件粘贴到该文件夹内,选择替换该文件夹内的原文件。完成以上操作后,重启软件即可
搜索引擎的使用:选中一篇文献,点击Zotero右上角的绿色箭头,就可以看到许多搜索引擎,点击自己需要的即可,链接网址的具体功能可自行摸索。
四、参考文献 [1]新版Zotero配置步骤
[2]开源翻译软件Github地址
[3]青柠学术
五、本文各项插件均可直接获取,插件获取方式见文未 【获取方式】:关注微信公众号“舒意的碎碎念”,回复“新版zotero插件”,即可获取所有插件压缩包
手动安装数字签名证书发现无法成功,或者利用工具安装数字签名证书重启电脑右下角无法出现”测试模式”。
解决方法:
WIN7/10 某些系统会自动开启 SecureBoot 功能,导致签名失败,只需要在 BIOS 中把“ScureBoot”选项 disable 即可。
pyside2加载ui文件的两种方式 目录 pyside2加载ui文件的两种方式一、直接加载ui文件1、首先进行ui设计2、然后自定义LoginGui类,调用QUiLoader的load方法对ui文件进行加载。3、效果显示 二、先转换为py文件再对转化的py文件进行调用1、将ui文件转换为py文件2、自定义类加载py文件3、QLayout: Attempting to add QLayout "" to LoginGui "Form", which already has a layout 三、Reference 一、直接加载ui文件 首先我们使用Ui Designer设计完成Ui界面,并且保存为ui文件,接下来我们可以使用QUiLoader这个类的load方法来对ui文件进行加载。
1、首先进行ui设计 我在这里只设计了一个pushbutton,然后保存ui文件。我的路径目录如下
2、然后自定义LoginGui类,调用QUiLoader的load方法对ui文件进行加载。 from PySide2.QtWidgets import QApplication from PySide2.QtUiTools import QUiLoader class LoginGui(object): def __init__(self): # 对ui文件进行加载 self.ui = QUiLoader().load('./demo/demo.ui') if __name__ == '__main__': app = QApplication([]) gui = LoginGui() gui.ui.show() app.exec_() 3、效果显示 显示效果和我们设计的ui界面一致,加载成功。
二、先转换为py文件再对转化的py文件进行调用 1、将ui文件转换为py文件 我们需要使用pyside自带的uic文件转化功能
进入ui文件存放的路径中使用cmd命令行窗口,输入
pyside2-uic 源文件 > 目标文件 比如这里
pyside2-uic dmeo/demo.ui > demo/Ui_Loader.py 转换完成之后,这里就会多一个Ui_Loader.py文件
Nginx-exporter部署手册 准备安装包 下载 Nginx-exporter wget https://github.com/hnlq715/nginx-vts-exporter/releases/download/v0.10.3/nginx-vts-exporter-0.10.3.linux-amd64.tar.gz 下载 Nginx wget http://nginx.org/download/nginx-1.17.7.tar.gz 下载 nginx 插件 ,记住项目下载地址,下面在配置nginx的时候需要指定 git clone git://github.com/vozlt/nginx-module-vts.git 建议使用当前最新版本 安装 解压Nginx
tar -zxvf nginx-1.17.1.tar.gz 进入Nginx目录
执行命令 ./configure 是用来生成Makefile,为下一步的编译做准备 --add-module=后面跟上插件的下载地址
./configure --prefix=/export/app/nginx --with-http_ssl_module --add-module=/export/gitspace/nginx-module-vts/ make & make install 修改nginx.conf配置文件添加一下信息
http { vhost_traffic_status_zone; vhost_traffic_status_filter_by_host on; server { # vhost_traffic_status off; location /status { vhost_traffic_status_display; vhost_traffic_status_display_format html; } } } 打开vhost过滤
vhost_traffic_status_filter_by_host on;
开启此功能,在Nginx配置有多个server_name的情况下,会根据不同的server_name进行流量的统计,否则默认会把流量全部计算到第一个server_name上。
在不想统计流量的server区域禁用vhost_traffic_status,配置示例: server { ... vhost_traffic_status off; ... } 假如nginx没有规范配置server_name或者无需进行监控的server上,那么建议在此vhost上禁用统计监控功能。否则会出现“127.0.0.1”,hostname等的域名监控信息。
首先ssh登录服务器,服务器端tensorflow虚拟环境下运行命令
tensorboard --logdir=‘你的服务器日志文件地址’
其次在本地cmd打开执行: ssh -L 16006:127.0.0.1:6006 -p port ( 服务器端口号) 服务器用户名@服务器ip,连上输入密码即可
本地打开浏览器进入地址:127.0.0.1:16006
就可以看到了
java.io.FileOutputStream extends OutputStream
FileOutputStream :文件字节输出流
作用:把内存中的数据写入到硬盘中去
构造方法:FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流
FileOutputStream(File file)创建一个向指定File对象表示的文件中写入数据的输出文件流
参数:写入数据的目的
String name:目的地是一个文件的路径
File file:目的地一个文件
构造方法的作用:
1、创建一个FileOutputStream对象
2、会根据构造方法中传递的文件/文件路径,创建一个空的文件
3、会把FileOutputStream对象指向创建好的文件
写入数据的原理(内存 ——>硬盘)
java程序->JVM(java虚拟机)->os(操作系统)->os调用写数据的方法 ->把数据写入到文件中
字节输出流的使用步骤(重点)
1、创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2、调用FileOutputStream对象中的方法write,把数据写入到文件中
3、释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提高系统效率)
public void write(byte [] b)将b.length字节从指定的字节数组写入此输出流,如果写的第一个字节是正数(0-127)那么显示的时候会查询ASCII表是负数则第一个字节和第二个字节组成一个中文显示,查询系统默认码表
public void write(byte [] b, int off ,int len):把字节数组的一部分写入 int off :数组的索引 int len :写入几个字节
写入字符串的方法:可以使用String类中的方法把字符串转换为字节数组 byte [] getByte()
数组的追加写和换行写
追加写/续写:使用两个参数的构造方法
FileOutputStream(String name,boolean append)创建一个向具有指定name的文件中写入数据的输出文件流
FileOutputStream(File file,boolean append)创建一个向File对象表示的文件中写入数据的文件输出流
参数:String name File file写入数据的目的地
Boolean append:追加写开关 true 创建对象不会覆盖源文件继续在文件的结尾追加写数据false 创建一个新文件覆盖源文件
换行写:写换行符
写在前面 本文转载于 论文中出现的 cf. i.e. s.t. e.g. w.r.t. et al. etc等英文缩写是什么意思 https://blog.csdn.net/weixin_42623382/article/details/105104169 ,感谢原博主的汇总。侵删。
论文阅读中经常遇到的一些缩写、简拼,具体含义 cf. 参考 例句:The prefix B denotes that the corresponding quantity is expressed in the frame B (cf., Fig. 2)
i.e. 即 例句:Inherently, the vision-only problem has six DoFs that are unobservable and need to be held fixed during optimization, i.e. the absolute pose.
s.t. 服从,满足 ,受约束于 subject to的缩写,通常出现在数学方程式和数学公式中,比如:
参数x满足约束g(x)=0的所有值中,使得f(x)的值最大。
e.g. 例如 源自拉丁文exempli gratia
例句:This is in contrast to, e.
说到跨域我们需要先了一些概念
同源策略定义: 同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。而浏览器也是建立在这样的同源策略基础上的它是浏览器最核心最主要的功能之一。
同源定义: 两个url地址如果 协议、主机、端口号三个都完全相同就属于同源,就可以正常的进行数据的交互
给定一个地址:http://www.localhost:8080/abc/index.html,下列列出与之同源和非同源的例子
地址是否同源理由https://www.localhost:8080非同源协议不一样,一个http,一个httpshttp://www.localhost:8081非同源端口号不一样,一个8080,一个8081http://localhost:8080非同源主机不相同(需要精准匹配)http://www.abc.localhost:8080非同源主机名不同http://www.localhost:8080/bck/a.html同源只有具体路径不相同http://www.localhost:8080/x/y/b.html同源协议,主机,端口号都相同 而我们在构建web应用程序的时候也要遵循这样的约定,但是有时候为了实现跨域请求和获取一些数据就需要使用跨域请求的方式去实现。
解决方案: JSONP jsonp是最先提出的跨域请求解决方案,这里我们需要知道一些基础知识,在html中能够跨域请求资源的有:script、link、img、video、audio、frame、iframe、embed等有src属性的标签。这些标签的请求方式都是GET方式,其中能够请求服务器拿到服务器返回的数据只有script标签
jsonp就是通过此特性实现跨域和服务器交互,具体实现逻辑
最简单并且能够理解的例子:
服务器端:这里使用的nodejs的express搭建的服务器 // 引入express let express = require('express'); // 创建一个服务器示例 let app = express(); // 这里是get请求的路由地址 app.get('/user', (req, res)=>{ //然后拿到地址的get参数 let callBack = req.query.callBack; // 这里是需要发送给客户端的数据,这里传出去的是对象字符串形式 let data = JSON.stringify({ name: 'qwguo', age: 34, sex: 'man' }); // 然后执行end方法结束连接,并且传给客户端一串字符串 // 其实这里传过去的是 /* callBack({ name: 'qwguo', age: 34, sex: 'man' }); */ // 上边的形式 res.end(`${callBack}(${data})`); }); // 然后服务器监听在3000端口上 let server = app.
OceanBase是阿里开发的分布式关系型(SQL)数据库,其目标是支持数百TB的数据量以及数十万TPS、数百万QPS的访问量,无论是数据量还是访问量,即使采用非常昂贵的小型机甚至是大型机,单台关系数据库系统都无法承受。
案例:OceanBase分布式关系数据库渡过了一个成功的双十一:支持了支付宝核心的交易、支付、会员和账务等,并且创造了新的纪录:交易创建17.5万笔/秒、交易支付12万笔/秒、全天累计支付10.5亿笔
1、特性 1.1、高扩展性
传统关系型数据库,比如Oracle或者MySQL功能已经很完善,但数据库本身不可扩展,随着数据量的增大和业务内容的丰富,需要拆库拆表,然后再进行访问路由,将相应的SQL解析路由到指定的数据库中。数据库的运维人员需要花费大量的时间来做数据库扩容,包括读写分离、垂直拆分、水平拆分等等。
OceanBase使用了分布式技术和无共享架构,来自业务的访问会自动分散到多台数据库主机上。在相关技术的支持下,OceanBase还能够采用廉价的PC服务器作为其数据库主机。通过这两个方面的变革,运维人员可以愉快地通过增加服务器数量来增加系统的容量和性能。
1.2、低成本
传统商业企业采用的“IOE”体系,实际上代表了一种高成本、高维护费、非高并发的商用数据库系统。特别是随着数据越来越大,所需要付出的升级硬件和维护的代价也会越来越惊人,阿里巴巴采用数据切分的策略,将部分海量数据应用从集中式Oracle切换到分布式集群,从纵向扩展到水平扩展,解决了数据库扩展性的问题,并用PC服务器替换了小型机。
由此带来的一个重要变革,就是成本的极大降低。与传统数据库公司的产品相比,OceanBase的升级维护不需要昂贵的共享存储、高可靠的服务器、数据库软件的许可费,可以将商业数据库成本降到一半以下。
1.3、高可靠性
数据库系统通常由数据库软件、运行数据库软件的数据库服务器硬件以及保存数据库数据的数据库存储硬件(即共享存储)组成。数据库系统的稳定可靠,也取决于这三个部分。使用PC服务器能够带来高扩展性、降低成本的同时,其硬件的可靠性却对应有些下降。
如何保证系统的可靠性?OceanBase的一个基本假设就是硬件(服务器、存储、网络等)是不可靠的,因此,OceanBase必须保证任何时刻出现的少量硬件(服务器、存储、网络等)异常不影响业务。
为此,OceanBase引入了Paxos协议,每一笔事务,主库执行完成后,要同步到半数以上库(包括主库自身),例如3个库中的2个库,或者5个库中的3个库,事务才成功。这样,少数库(例如3个库中的1个库,或者5个库中的2个库)异常后业务并不受影响。
分布式事务一致性协议paxos主要用于保证一个数据在分布式系统里是可靠的。当在机器里多数派都成功了之后,只要坏的机器是少数派,三个里少数派是一个,多数派是两个。三个机器里面有两个成功了,那就可以告诉用户这个数据保证不会丢了。这个时候机可能会损坏,但是损坏任何一台机器,至少还有另外一台机器恢复过来,这是在系统内部自动去做容灾。任何一台机器坏了,或者有一台机器落后,比如三个及其是一主拖着另外两个成功了之后,就会把数据补上,肯定会保证另外两份是OK的,最终三份是OK了,坏一台机器都不会有问题。
软件层面,OceanBase区别于传统数据库的一个关键特征是软件版本的灰度升级。
主备方式的传统数据库是“单活”的,只有主库可执行写事务,尽管维护升级时可以先操作备库,操作完成后备库变成主库并且接受用户访问是一步到位的,如果新版本有问题,则业务受到影响:
传统数据库:升级前
传统数据库:升级中
传统数据库:升级后只能一次性地引入全部读写流量
OceanBase则是“多活”设计,即多个库(3个,5个等)每个都可以有部分读写流量,升级时先把要升级的库的读写流量切走,升级后先进行数据对比,正常后逐步引入读写流量,一切正常并运行一段时间后再升级其他的库:
OceanBase之3机群(3库)部署:升级前
OceanBase之3机群(3库)部署:切走读写流量,准备升级
OceanBase之3机群(3库)部署:升级一个机群(库)
OceanBase之3机群(3库)部署:升级一个机群(库)后切回全部读写流量
基于硬件不可靠的假设并且能够容忍少量服务器的故障,OceanBase使用了相对廉价的PC服务器代替高可靠服务器并且不再使用昂贵的共享存储,从而不仅提供了比使用高可靠服务器和共享存储低得多的成本,容忍少数服务器乃至少数机群故障意味着比传统数据库更高的可靠性。
通过灰度升级,OceanBase避免了传统数据库的“一锤子买卖”的升级,极大地降低了数据库维护升级的风险。
1.4、数据准确性
许多的互联网服务可以允许有一定的数据差错,但是电子商务(如交易、金融领域等)与一般的互联网公司不太一样,它对于数据的一致性要求非常高,比如要确保钱的进入与流出要对得上账,不能丢失任何一条支付数据(阿里巴巴将OceanBase用于支付宝系统)。
OceanBase设计与经典关系数据库有所不同,其读事务基本是分布式并发执行的,写事务目前是集中式串行执行的,即serializable,且任何一个写事务在commit之前对其他读写事务都是不可见的,因此OceanBase是强一致的。这样,在设计方案上能够保证不丢数据。
几种常见的一致性类型有:
强一致性:系统中的某个数据被成功更新(事务成功返回)后,后续任何对该数据的读取操作都得到更新后的值。这是传统关系数据库提供的一致性模型,也是关系数据库深受人们喜爱的原因之一。
弱一致性:系统中的某个数据被更新后,后续对该数据的读取操作得到的不一定是更新后的值,这种情况下通常有个“不一致性时间窗口”(inconsistency window)存在:即数据更新完成后在经过这个“不一致性时间窗口”,后续读取操作就能够得到更新后的值。
最终一致性:属于弱一致性的一种,即某个数据被更新后,如果该数据后续没有被再次更新,那么最终所有的读取操作都会返回更新后的值。(如果主备库数据同步存在时间差,一旦主机出现异常,恢复无法实时进行,同样有可能会出现数据一致性问题)
如图,上述三个机群构成一个数据库,其中一个是主机群,所有事务都由主机群的UpdateServer(称为主UpdateServer,其他UpdateServer称为备UpdateServer)执行,事务的redo log同步到3个UpdateServer中的超过半数(即至少2个,包括主UpdateServer自己),则事务成功并应答客户。由于集群中只有一台主UpdateServer提供写服务,因此,OceanBase也很容易地实现了跨行跨表事务。
如果3个UpdateServer中有一个故障: *主UpdateServer故障:剩余的两个UpdateServer会自动选举出一个新的主UpdateServer(参见后文“OceanBase分布式选举的实现”),由于旧的主UpdateServer数据至少在一个活着的UpdateServer中存在,因此数据不会有任何丢失,两个活着的UpdateServer经过很短时间(通常是毫秒级)的相互同步后就可以继续对外服务,保证了数据的一致性和服务的高可用。 *单个备UpdateServer故障:主UpdateServer有全部数据,剩余两个UpdateServer仍然超过半数,数据一致性和服务都不受任何影响。
(如果把上述三个机群部署出于三个不同的机房,那么即使一个机房出现电源、网络或者空调等故障,剩余两个机群仍然能够继续工作,数据一致性和服务可靠性都不受影响。)
然而,TCP协议传输、磁盘读写都可能出现数据错误,程序Bug则更为常见。为了防止各种因素导致的数据损毁,OceanBase采取了以下数据校验措施:
数据存储校验。每个存储记录(通常是几KB到几十KB)同时保存64位CRC校验码,数据被访问时,重新计算和比对校验码。
数据传输校验。每个传输记录同时传输64位CRC校验码,数据被接收后,重新计算和比对校验码。
数据镜像校验。UpdateServer在机群内有主UpdateServer和备UpdateServer,集群间有主集群和备集群,这些UpdateServer的内存表(MemTable)必须保持一致。为此,UpdateServer为MemTable生成一个校验码,MemTable每次更新时,校验码同步更新并记录在对应的操作日志中。备UpdateServer收到操作日志并重放到MemTable时,也同步更新MemTable校验码并与接收到的校验码对照。UpdateServer重新启动后重放日志恢复MemTable时也同步更新MemTable校验码并与保存在每条操作日志中的校验码对照。
数据副本校验。定期合并时,新的子表由各个ChunkServer独立地融合旧的子表中的SSTable与冻结的MemTable而生成,如果发生任何异常或者错误(比如程序bug),同一子表的多个副本可能不一致,则这种不一致可能随着定期合并而逐步累积或扩散且很难被发现,即使被察觉,也可能因为需要追溯较长时间而难以定位到源头。为了防止这种情况出现,ChunkServer在定期合并生成新的子表时,也同时为每个子表生成一个校验码,并随新子表汇报给RootServer,以便RootServer核对同一子表不同副本的校验码。
1.5、高性能
OceanBase架构的优势在于既支持跨行跨表事务,又支持存储服务器线性扩展。当然,这个架构也有一个明显的缺陷:UpdateServer单点,这个问题限制了OceanBase集群的整体读写性能。为了在高扩展性、低成本、高可靠性、数据一致性的基础上实现高性能,OceanBase在数据访问方面与传统数据库有很大的不同。
和很多行业一样,虽然数据总量非常大,但是淘宝业务一段时间 (例如小时或天)内数据的增删改是有限的(通常一天不超过几千万次到几亿次),根据这个特点,OceanBase把一段时间内的增删改等修改操作以增量形式记录下来,这样也使得了主体数据在一段时间内保持了相对稳定(称之为基准数据)。
由于增量数据相对较小,通常情况下,OceanBase把它保存在独立的服务器UpdateServer的内存中。以内存保存增删改记录极大地提高了系统写事务的性能。不仅如此,由于冻结后的内存表不再修改,它也可以转换成sstable格式并保存到SSD固态盘或磁盘上。转储到SSD固态盘后所占内存即可释放,并仍然可以提供较高性能的读服务,这也缓解了极端情况下UpdateServer的内存需求。
为什么要做这件事情呢?现在的存储,不管是磁盘或SSD,顺序写的性能远远大于随机写。现在SSD稍微好一些,随机写也可以相对高一些,但是无论如何都跟顺序写这样的硬件属性在性能上有数量级的差别。OceanBase用磁盘存储数据库,但用内存数据库、SSD(普通磁盘最怕随机读,但SSD很适合)来存储修改数据。还消除了随机写磁盘,批量来写入。实现扬长避短,最大化发挥了硬件的特性。
数据分成基准数据和增量数据之后,增量数据每天都在增加,必须合到基准数据里面去。OceanBase每天一次真正同步修改到磁盘上修改增量融合也采用了多库异步的方式,同时会选择一个低负载时段进行数据的合并操作,避免了对业务的影响。(淘宝数据很明显,因为用户都是在一个地域之内的,所以他有一个明显的高峰和低谷)
在每日数据合并上,OceanBase也做了优化,采用了更细粒度的分片,把数据分块,如果某块数据发生更改,只对这条数据进行重写即可。以块为单位来设计的数据库则很难做到这一点的。
2、系统架构 整体架构图如下:
OceanBase由如下几个部分组成:
1> 客户端:用户使用OceanBase的方式和MySQL数据库完全相同,支持JDBC、 C客户端访问,等等。基于MySQL数据库开发的应用程序、工具能够直接迁移到OceanBase。
2> RootServer:管理集群中的所有服务器,子表(tablet)数据分布以及副本管理。 RootServer一般为一主一备,主备之间数据强同步。
3> UpdateServer:存储OceanBase系统的增量更新数据。UpdateServer一般为一主一备,主备之间可以配置不同的同步模式。 部署时,UpdateServer进程和RootServer进程往往共用物理服务器。
4> ChunkServer:存储OceanBase系统的基线数据。 基线数据一般存储两份或者三份,可配置。
5> MergeServer:接收并解析用户的SQL请求,经过词法分析、语法分析、查询优化等一系列操作后转发给相应的ChunkServer或者UpdateServer。如果请求的数据分布在多台ChunkServer上,MergeServer还需要对多台ChunkServer返回的结果进行合并。 客户端和MergeServer之间采用原生的MySQL通信协议,MySQL客户端可以直接访问MergeServer。
一面约40min
本来预定是1h,但是没想到40min左右就结束了,感觉还不错
面试官看起来比较严肃(头有点秃),很厉害的样子,上来就说明今天面试分为两部分:基础知识和项目情况
基础知识方面
1.介绍一下信号量和锁,底层是如何实现的,以及它们的区别
2.你知道自旋锁吗,说一下和互斥锁的区别
3.讲一下红黑树的特征,应用场景
4.说一下浏览器输入网址后,接收到响应的一系列流程
5.说一下cookie和session的区别
(问题很少,但是每个都能叭叭很久)
项目情况
没有问深入的业务和细节,针对我的项目都是问项目是做什么的,具体的分工。
最后提问环节,他问了我对哪方面感兴趣,问了一下我简历上写的实验室研究方向;我问了他base,部门的工作,以及对我整体的评价:
说整体还不错,前面都答上来了。但是他说觉得我项目有点杂(前端,后端小程序啥都有),对我实际的一个水平还没有很清晰。建议我后面其他面试官有问到的话,好好准备一下(自我感觉应该是稳了,祈求二面)
二面 1h
二面约的是电话面,面试官和我确认了上一个面试官对我项目的提问情况,我说上一个面试官问的情况,他就表示不会细问项目,多问一些c++相关的。面试开始
因为项目写了Qt,所以他问我Qt是如何对事件响应的。我用信号和槽函数回答。问了一个搜索问题:如何找出所有内容中含有某个字符串的文件。思路不是很明确,回答往B+树建立索引方向,讲了一下B+树的优点,为什么这么想;但是具体怎么用B+树来实现,没有回答上来。问了一下文本压缩,知道什么算法。 上来就回答哈夫曼编码,讲了实现过程,以及能够这种编码有效的原因。回答一下一亿个浮点数当中,如何找到最大的10个
很显然是top-k问题,说用一个大顶堆来维护,然后又问堆是如何维护的,大概说了一下流程就过了口述一个算法:一个二维平面中有很多点,如何找到最小的一个凸多边形,将所有的点包住。 回答思路是找到最外侧的点,一开始说的很模糊很混乱,最后回答用暴力,求所有最远的点对,最远的点对就是端点 感觉没答好问还有用c/c++做过其他项目吗? 介绍了一下操作系统课设,做的是模拟linux的文件系统。然后是问了一些实现的细节。让我设计一个内存池,用什么样的数据结构,提供怎样的API。 回答是仿照缓冲池,维护一个空链表,一个占用链表。
每一个节点就是一个“页”或者块whatever;
每一次申请,都从空链表当中申请节点,把结点写满,然后挂载到占用链表;以此类推。返回的是页面的索引编号。
然后又问到了如何选节点,回答四种内存分配算法。回答上,但记忆有些模糊,磕绊
问了一下项目当中的TextCnn,实现原理和过程,用的什么数据集,做了哪些优化工作等等。幸好有准备,基本都答上了。
聊天环节,让我提问,问了一下整场的表现,对于深挖项目的建议。
整场一个小时差不多。面试官挺和蔼,挺年轻,会笑(不知道是不是在嘲笑我某些愚蠢的点),然后所有问题也基本都是开放性,逐步深入引导回答。自我感觉一般,算法答得不够好,很多点口条不够顺,回答得很磕绊,语句冗余。祈求三面!!!
题目 题目链接
题解 数学公式。
会线性代数的看低下这个也可以。
实在忘了咋求了,直接百度的。。。
代码 #include<bits/stdc++.h> using namespace std; int main() { double a, b, m, c, d, n; cin>>a>>b>>m>>c>>d>>n; cout << (m*d-b*n)/(a*d-b*c) <<' '<< (a*n-c*m)/(a*d-b*c); return 0; }
将public static void main(String args[])所在的类名改为与文件名一致即可。
微信搜索 “写点代码的明哥”,关注更多关于 Go 与 K8S 的干货文章
系列导读:
1、Go 1.18 系列篇(一):如何升级 Go 1.18 ?
2、Go 1.18 系列篇(二):一文掌握泛型的使用
3、Go 1.18 系列篇(三):一文掌握 Go 工作区模式
1. 什么是模糊测试? 单元测试,大家应该都写过吧?单元测试,需要开发者根据函数逻辑,给定几组输入(入参)与输出(返回)的数据,然后 go test 根据这些数据集,调用函数,若返回值与预期相符,则说明函数的单元测试通过。
但单元测试的代码,也是由开发者写的一段一段代码,只要是代码,就会有 BUG,就会有遗漏的场景。
因此即使单元测试通过,也不代表你的程序没有问题。
可见,测试场景的数据集对于测试有多重要,而 Fuzzing 模糊测试就是一种用机器根据已知数据源,来自动生成测试数据的一种方案。
本文借用官方的一个例子来讲解。
2. 简单的示例 在开始之前,先初始化项目
go mod init github.com/iswbm/fuzz 然后在该项目中添加 main.go,内容如下
package main import "fmt" func Reverse(s string) string { b := [] byte(s) for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 { b[i], b[j] = b[j], b[i] } return string(b) } func main() { input := "
1、当值为null时,求平均数 聚合函数会把NULL排除在外,但count(*)例外,并不会排除NULL,但count(book_price)不会排除null
如果对book_price这个字段计算求平均值的话,结果为30
SELECT round(avg(book_price),2) FROM `t_book`; 是因为数据库聚合的时候会删除NULL列,然后计算:(20+35+25+20+40+30+50+20)/8=30,注意分母是8不是10
如果需要将NULL值也作为分母来计算的话,需要使用COALESCE()函数将NULL值转换为其他值(如0),
SELECT round(avg(coalesce(book_price,0)),2) FROM `t_book`; 则计算方式为:(20+35+25+20+40+30+50+20)/10=24
2.当值为0时,求平均数 SELECT round(avg(book_price),2) FROM `t_book`; 计算方式为:(20+35+25+20+40+30+50+20)/10=24
若需要将值为0的数据去掉,不做计算的话,可以使用nullif()函数
#nullif(book_price,0)------》 若book_price=0话,返回null,而不是0 SELECT round(avg(nullif(book_price,0))) FROM `t_book`; 计算方式为:(20+35+25+20+40+30+50+20)/8=30
3、特殊情况:当值为0时,且求平均值的结果也为0时,如下图 其结果为:
这样的查询结果若展示到前端,可能会有影响,出现undefined的情况,如下图
需要解决此问题的话,可以用case搜索函数,将结果为null的转换为0进行展示
select (case when round(avg(nullif(book_price,0))) is null then 0 else round(avg(nullif(book_price,0))) end) book_price FROM `t_book`; 结果为:
教师信息管理系统 目录
1.概述
1.1选题背景
1.2功能要求
1.3系统功能解决的问题
2.需求分析
2.1应用需求分析
2.2功能需求分析
3.概念结构设计
3.1抽象出系统的实体
3.2设计分E-R图
4.逻辑结构设计
5.数据库物理设计与实施
5.1表的创建
5.2部门信息表
5.3员工信息表
5.4薪资信息表
5.5奖惩信息表
6.数据操作要求及实现
6.1 数据查询、更新和删除等操作
6.2 视图
6.3 触发器
6.4 存储过程
7.总结
8.附件
摘要
高校教师信息管理是高等院校师资队伍建设工作的一个重要内容,它具有信息量大、操作繁琐等特点。随着现代化高校建设的快速发展,档案管理工作量日益增加,传统的手工操作方式无论从质量还是速度上都难以满足新的工作需要。计算机技术的发展,为数据库的管理与维护提供了方便。此高校教师信息管理系统,实现对教师档案数据的录入、编辑、存档等一系列功能,把办公人员从繁杂的事务性工作中解脱出来,使教师档案管理工作能实现自动化、信息资源化和管理科学化。
1.概述 1.1选题背景 目前国家的教育体制正处在不断改革、创新的阶段,我国教育部门充分吸取国外优秀的教学模式,结合国内多年的办学经验,逐步探索出适合中国特色的教学形式,国家教育部面向各级各类学校开展了全面学分制改革。教育部为了实现党的十五大所确定的目标与任务,落实科教兴国战略,特制定了《面向21世纪教育振兴行动计划》,其中讲到“开发高质量教育软件,重点建设全国远程教育资源库和若干个教育软件开发生产基地”。因此,各院校迫切需要对自己的现有教务管理系统进行改进和提高,根据国内大学的现在管理模式,结合国际新的思想观念,在校园网络环境下建设先进的、与国际水平接轨的信息化管理平台。提高学校管理工作的现代化水平,推广现代教育技术在教学实践中的运用,促进教育整体质量和办学效益的提高。使之成为学校公共信息服务体系的重要组成部分。在这样的大环境下,开发和完善高校教务信息管理系统是目前各高校的迫切需求。
1.2功能要求 实现部门、职称、职务的基本信息的管理;
实现教师信息的管理; 实现教师婚姻状况和教育经历的管理; l 实现教师的奖惩管理; 创建触发器,实现增添或删除部门人员时自动修改相应部门的员工人数;
创建存储过程根据提交的部门编号,查看该部门的部长;
建立数据库相关表之间的参照完整性约束。
1.3系统功能解决的问题 一:提高管理人员的工作效率。
二:对大量的数据信息进行统筹规划
三:降低处理数据信息时出现的错误率。
四:方便系统的后期维护。
2.需求分析 2.1应用需求分析 90年代中期,由于Internet 的迅速普及,使Intranet成为Internet技术在企业管理信息系统中的应用和延伸,形成了集计算机,计算机网络、数据库、分布式计算等于一体的信息技术综合体,它打破了时间和地域的界限,使信息交流变得快捷、准确,为建立现代企业管理信息系统提供了充足的条件。高校教职工管理系统在此基础上延伸、扩展,使之上下、内外全面贯通。高教教职工管理系统是在适应市场需求的客观前提下,为了满足各高校管理自己学校所在的教职员信息而开发的。该系统的是终目的是要将各位职员的信息放到网络上,以方便管理。
系统采用模块化程序设计方法,既便于系统功能的各种组合和修改,又便于未参与开发的技术维护人员补充、维护。该系统具备数据库维护功能,及时根据用户需求进行数据的添加、删除、查看等操作。
2.2功能需求分析 根据分析,该管理系统必须具备如下几个功能:
1.能够记录教职工各种基本资料;员工各种信息的输入,包括员工的基本信息,学历信息,婚姻状况信息,职称等
2.系统使用者能够查询信息,能进行对各员工成员的增加以及对于辞退,退休员工的信息删除;
3.保障数据库安全,优化数据库。
4.界面的友好性。
3.概念结构设计 3.1抽象出系统的实体 根据设计高校教师信息管理系统的需要,可以抽象出以下实体:
1.员工信息
2.部门信息
3.奖惩信息
4.薪资信息
3.2设计分E-R图 工资实体属性图
MVVM 和 MVVMLight介绍 MVVM是Model-View-ViewModel的简写。类似于目前比较流行的MVC、MVP设计模式,主要目的是 为了分离视图(View)和模型(Model)的耦合。 它是一种极度优秀的设计模式,但并非框架级别的东西,由MVP(Model-View-Presenter)模式与 WPF结合的应用方式时发展演变过来的一种新型架构。 立足于原有MVP框架并且把WPF的新特性糅合进去,以应对PC端开发日益复杂的需求变化。 结构如图所示:
相对于之前把逻辑结构写在Code Behind 里面的方式,MVVM几乎完全解耦了视图和逻辑业务的关系,通过数据绑定和命令来处理UI属性及事件驱动。 同理,ViewModel的视图交互业务逻辑处理导致的属性变更也会通知到View前端,让View前端实时更 新。Model中存放数据模型和数据逻辑、业务逻辑。 这种类型的双向绑定非常优秀,View的变动,会自动反应到ViewModel上,反之亦然。目前JS前端框 架AngularJS也是采用这种设计模式。 MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大优点:
低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上, 当View变化的时候Model可以不变,当Model变化的时候View也可以不变。 2. 可重用性:可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。 3. 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面 设计,使用Expression Blend可以很容易设计界面并生成xml代码。 4. 可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写 如果你目前正在进行微软的 WPF 、Windows Phone、Windows 8、SilverLight相关项目的开发,很有必要了解一下MVVM Light框架。 它轻量(相对于Prism),专注(仅负责MVVM架构模式的实现,没有其他多余的组件),高效(使 用简易,省时减力),能够帮助你更好的开发你的应用。
如何在你的WPF应用中使用MVMLight 主要使用方式有两种; 一种是去官网上下载MVVMLight Toolkit,安装之后,VS模板中会出现MvvmLight项目模板,你可以 直接使用该项目模板来创建项目了。 里面会包含默认的ViewModelLocator和MainViewModel,MainViewModel就是你Main视图的 ViewModel了,而ViewModelLocator是一个全局的ViewModel加载注册器,这个第二篇会详细说到。
另一种方式就是去NuGet上安装,这无疑是最便捷的事了。在NuGet 工具箱上搜索 MVVM Light,可以看到两个项目,一个是MVVM Light , 一个是 MVVM Light libraries only。
当前版本是5.3,说明MVVM Light的更新速度还是挺快的,Prerelease中还有 V5.4 的 ALAPHA 版 本。 Nuget上这两个项目的区别就是MVVM Light除了必要的GalaSoft 组件之外,还会额外添加相关分层文件目录形成简单的MVVMLight成型框架 如图它会帮你生成ViewModel文件夹,里面包含MainViewModel和ViewModelLocator文件
至此,一个基于MVVMLight的WPF项目框架基本搭建完成了
resetFields作用实际上是将表单元素置为初始值
使用resetFields清空表单,有时候会出现再次打开表单,还是会出现上一次的值的情况
解决方案 1.在打开弹窗时,在$nextTick中赋值,因为此时Dialog已经初始化(已经mounted)
confirmEdit(row) { console.log(row, '编辑') this.dialogVisible = true this.$nextTick(() => { this.formData = { type: 1, phone: '', name: '', dateTimeArr: [] } }) } 2.关闭弹窗时,不使用resetFields(),
直接赋值:
this.formData = {}
家里有个树莓派一直想在公司时能连上,但是苦于家里网络没公网ip,就找到了这个工具
安装 frp 首先去frp release这边下载相对应的包,例如我的树莓派v4是armv7l用的arm包,服务器是amd64用的amd64包,不知道架构的可以输入uname -m查看
穿透目标客户端和服务端 以随便一个包为例,红框的是客户端用的,蓝的是服务端用的
接下来把红蓝各自放在客户端和服务端单独文件夹里,然后chmod 777启动文件,唯一要修改的配置文件是客户端frpc.ini里的server_addr为服务器ip,其余的都使用默认配置和端口
启动 先在服务端启动frps,这里会输出红框的前2段
然后启动客户端,连上服务器会输出上图的第三段
最后第三台电脑使用ssh -p 6000 $用户@$服务器ip就可以连上穿透目标客户端了
关于守护进程我用的pm2,下的包有带systemd配置,具体怎么弄建议再搜
MyISAM 和 InnoDB 的区别 MySQL 5.5 之前,MyISAM 引擎是 MySQL 的默认存储引擎,可谓是风光一时。虽然,MyISAM 的性能还行,各种特性也还不错(比如全文索引、压缩、空间函数等)。但是,MyISAM 不支持事务和行级锁,而且最大的缺陷就是崩溃后无法安全恢复。
5.5 版本之后,MySQL 引入了 InnoDB(事务性数据库引擎),MySQL 5.5 版本后默认的存储引擎为 InnoDB。
1.是否支持行级锁
MyISAM 只有表级锁(table-level locking),而 InnoDB 支持行级锁(row-level locking)和表级锁,默认为行级锁。
也就说,MyISAM 一锁就是锁住了整张表,这在并发写的情况下是多么滴憨憨啊!这也是为什么 InnoDB 在并发写的时候,性能更牛皮了!
2.是否支持事务
MyISAM 不提供事务支持。
InnoDB 提供事务支持,具有提交(commit)和回滚(rollback)事务的能力。
3.是否支持外键
MyISAM 不支持,而 InnoDB 支持。
🌈 拓展一下:
一般我们也是不建议在数据库层面使用外键的,应用层面可以解决。不过,这样会对数据的一致性造成威胁。具体要不要使用外键还是要根据你的项目来决定。
4.是否支持数据库异常崩溃后的安全恢复
MyISAM 不支持,而 InnoDB 支持。
使用 InnoDB 的数据库在异常崩溃后,数据库重新启动的时候会保证数据库恢复到崩溃前的状态。这个恢复的过程依赖于 redo log 。
🌈 拓展一下:
MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性。MySQL InnoDB 引擎通过 锁机制、MVCC 等手段来保证事务的隔离性( 默认支持的隔离级别是 REPEATABLE-READ )。保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。 5.
一、获取授权码 1、以QQ邮箱为例,页面首部找到设置 2、开启POP3/SMTP服务 3、获取授权码 二、SpringBoot集成邮件发送 1、环境配置 添加依赖 <!-- springboot 邮件mail --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> <version>${springboot.version}</version> </dependency> application.properties # 邮件 spring.mail.default-encoding= utf-8 # 配置 SMTP 服务器地址 spring.mail.host= smtp.qq.com #发送方邮件名 spring.mail.username= xxxx@qq.com #授权码 spring.mail.password= xxxxxx 邮箱类型SMTP服务器地址端口号QQ邮箱smtp.qq.com465或587sina邮箱smtp.sina.cn465或587126邮箱smtp.126.com465或994aliyun邮箱smtp.aliyun.com465或994163邮箱smtp.163.com465或994yeah邮箱smtp.yeah.net465或994 application.yml(与application.properties任选其一既可) spring: #邮箱基本配置 mail: #配置smtp服务主机地址 host: smtp.qq.com #发送者邮箱 username: xxxxxxx@qq.com #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 password: xxxxxxxxxxx #端口号465或587 port: 587 #默认的邮件编码为UTF-8 default-encoding: UTF-8 #其他参数 properties: mail: #配置SSL 加密工厂 smtp: ssl: #本地测试,先放开ssl enable: false required: false #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 debug: true 2、代码编写 MailRequest实体 public class MailRequest implements Serializable { /** * 接收人 */ private String sendTo; /** * 邮件主题 */ private String subject; /** * 邮件内容 */ private String text; /** * 附件路径 */ private String filePath; public String getSendTo() { return sendTo; } public void setSendTo(String sendTo) { this.
文章目录 说明书部署客户端安装 rsync 服务编写配置文件创建 rsync 用户创建目录并赋权创建认证用户和密码文件启动 rsync查看 rsync 是否启动成功 部署服务端安装 rsync 服务创建 rsync 用户创建目录并赋权创建认证用户和密码文件测试 rsync 文件同步客户端查看文件 安装 lsyncd 服务编写配置文件启动 lsyncd 服务测试 lsyncd 功能 说明书 rsync rsync 是一个开源的实用程序,可提供快速增量文件传输rsync 官网和 sync 命令是完全两个玩意,sync 是将内存 buff 中的资料强制写入磁盘,rsync 是增量文件传输 lsyncd Lsyncd监视本地目录树事件监视器接口( inotify 或 fsevents )它聚合并组合事件几秒钟,然后生成一个(或多个)进程来同步更改,(默认情况下是 rsync )lsyncd 2.2.1 要求所有源计算机和目标计算机上的 rsync >= 3.1lsyncd github lsyncd + rsync 可以用来做数据的备份,也可以代替 nfs 做 web 服务器的共享根目录
192.168.16.100 这个节点用来充当服务端的角色,192.168.16.107 和 192.168.16.108 用来充当客户端的角色(当服务端指定目录内发生修改[增删改]操作后,将修改的操作同步给客户端)
需要整理一下场景和思路
192.168.16.100 需要部署 lsyncd 和 rsync (因为 lsyncd 是一个采用 linux 内核的 inotify 触发机制去调用 rsync 做增量文件传输)lsyncd 需要编写配置文件rsync 不需要编写配置文件 192.
1、引用 Human beings face ever more complex and urgent problems, and their effectiveness in dealing with these problems is a matter that is critical to the stability and continued progress of society.
2、代码块 如果使用Tab键对段落进行缩进,这段文本在预览模式下也会被识别为代码块。 如果使用Tab键对段落进行缩进,这段文本在预览模式下也会被识别为代码块。 3、行内代码 一行中被 反引号 括起来的文字会以代码格式显示。
4、数学公式 行内公式用单$
简单语法:$E=mc^2$ E = m c 2 E=mc^2 E=mc2LaTex语法:$$\begin{bmatrix}x\\y\end{bmatrix}$$
[ x y ] \begin{bmatrix}x\\y\end{bmatrix} [xy]
可使用公式编辑器:在线LaTeX公式编辑器 公式换行 在以
\begin{aligned} …… \end{aligned} \begin{split} …… \end{split} 为首尾的公式内,以\\表换行,以&表对齐,如:
$$\begin{aligned} KPI&=(N+S)W \\ PI&=N+S \\ I&=W \end{aligned}$$ K P I = ( N + S ) W P I = N + S I = W \begin{aligned} KPI&=(N+S)W \\ PI&=N+S \\ I&=W \end{aligned} KPIPII=(N+S)W=N+S=W
首先:利用canvas的beginPath、moveTo、lineTo、closePath方法去绘制一个你想要的图形!
ctx.beginPath() ctx.moveTo(points[0][0], points[0][1]) points.forEach((item, i) => { if (i != 0) { ctx.lineTo(item[0], item[1]) } }) ctx.closePath() ctx.strokeStyle = "rgba(15, 206, 233, 1)"; ctx.stroke() 遇到的问题:这时候一定要用 stroke() 来结束绘制;(这里就是我遇到的坑 我没有用stroke收尾直接填充图片 用fill()结束 没有效果 也尝试了其他方式 都不行!)
然后:再去填充图片 用createPattern方法去填充图片!
ctx.fillStyle = ctx.createPattern(img, 'repeat') ctx.fillStyle = "rgba(80, 168, 225, 0.69)" ctx.fill() 这里可能就有一些对canvas不熟的小伙伴 再次遇到坑!
遇到的问题:img如何配置 配置完img 没有效果! 直接上代码!
let img = new Image(); img.src = require('../assets/images/map/carway.png') img.onload = function () { ctx.beginPath() ctx.moveTo(points[0][0], points[0][1]) points.forEach((item, i) => { if (i !
计算机网络与网络安全 1.TCP/IP 五层网络架构 物理层:接收识别比特流,透明地传送比特流,数据单位是比特。规定了机械特性、电气特性、功能特性、过程特性。
数据链路层:在两个相邻结点间的链路上传送帧。
网络层:负责处理分组在网络中的活动,如分组的选路,协议有 IPV4、IPV6、ICMP。
传输层:在两个主机的通信中提供传输服务,选择合适的路由,使源主机运输层所传下来的分组,能够通过网络中的路由器找到目的主机。协议有TCP、UDP、SCTP。
应用层:定义应用进程间的通信和交互规则。协议有DNS、SSH、SMTP、FTP。
OSI七层网络架构
Open System Interconnect意为开放式系统互联。应用层=会话层+表示层+应用层
2.ip地址与mac地址 mac地址为48位,ip地址为32位。
IPV4地址为32位,IPV6地址为128位。
3.ARP欺骗 address resolution protocol是一种局域网协议,通过解析IP地址获取MAC地址。
主要有两种数据包:arp请求、arp应答包。
主机A把arp请求包发给交换机,交换机以广播的形式发送请求包给主机C,
主机C将arp应答包返回MAC地址。
由于在arp协议过程不存在认证,只要主机C发送应答包就会被A接收,记录在arp缓存表中。攻击者可以利用arp对网关和另一台主机进行欺骗,更改ARP缓存表,从而实现对该主机的流量监听。
4.TCP/UDP TCP/UDP 都属于传输层协议,用于在程序之间传输数据。
TCP基于连接(belike打电话)稳定可靠,比如发邮件、浏览网页等。
其过程为:三次握手-->传输确认-->四次挥手
三次握手:
四次挥手:
UDP基于非连接(belike写信)
速度快、性能损耗低、简单地对数据包进行封装,从网卡发出去。
5.HTTP与HTTPS HTTP即超文本传输协议,其使用可扩展语义和自描述消息格式,传输部分交给TCP协议。HTTPS 中的S即TLS(SSL)加密协议,在应用层与传输层加入了一层安全层,对请求报文和响应报文都做加密。
HTTPS传输过程:
浏览器拿证书浏览器发对称(会话)密钥给服务器两端用会话密钥进行传输 6.DDOS攻击Distributed Denial of Service SYN flood利用了TCP协议三次握手的缺陷,伪造大量源IP地址,向服务器发送大量SYN包,此时服务器端会返回SYN/ACK包并等待回应,因此会使服务器无法响应正常请求。
7.DNS解析 DNS domain name system,服务器记录ip与域名的关系
DNS安全问题:
攻击者获得用户ip伪造请求,使用户接收到DNS服务器,而成DDOS攻击;DNS缓存污染,修改DNS服务器缓存引导用户到其他网页;DNS信息劫持,DNS报文包数据被截获被篡改成虚假IP作为应答返回给请求者。 计算机操作系统 1. 进程调度算法Process Scheduling Algorithms (1)FCFS SJF
(2)高优先权调度算法 抢占式调度算法/非抢占式调度算法
(3)高响度比优先调度算法 动态优先权优先级=(服务时间+等待时间)/服务时间=1+等待时间/服务时间
(4)基于时间片的轮转调度算法 2. 进程状态 3.中断与异常 中断是指 CPU 对系统发生某事件时的这样一种响应: CPU 暂停正在执行的程序,在保留现场后自动地转去执行该事件的中断处理程序;执行完后,再返回到原程序的断点处继续执行。
POI Word生成图表:POI Word 图表、柱状图、条形图、折线图、饼图_u014644574的博客-CSDN博客_poi word 图表 1、pom.xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.4</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.13</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.19</version> </dependency> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>ooxml-schemas</artifactId> <version>1.4</version> </dependency> 2、POI EXCEL 图表-折线图 package test; import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xddf.usermodel.PresetLineDash; import org.
VIM中字符串的替换
字符串的替换
1. vim 中可用 :s 命令来替换字符串,具体如下: :s/str1/str2/ 替换当前行第一个 str1 为 str2 :s/str1/str2/g 替换当前行中所有 str1 为 str2 :m,ns/str1/str2/ 替换第 n 行开始到最后一行中每一行的第一个 str1 为 str2 :m,ns/str1/str2/g 替换第 n 行开始到最后一行中所有的 str1 为 str2 (注:m和n 为数字,若m为 .,表示为当前行开始;若n为$,则表示到最后一行结束) 如果使用 # 作为分隔符,则中间出现的 / 不会作为分隔符,比如: :s#str1/#str2/# 替换当前行第一个 str1/ 为 str2/ :%s+/oradata/apras/+/user01/apras1+ (使用+ 来 替换 / ): /oradata/apras/替换成/user01/apras1/ 2. 其他:%s/str1/str2/(等同于 :g/str1/s//str2/) 替换每一行的第一个 str1 为 str2 :%s/str1/str2/g(等同于 :g/str1/s//str2/g 和 :1,$ s/str1/str2/g ) 替换文中所有 str1 为 str2 从替换命令可以看到,g 放在命令末尾,表示对搜索字符串的每次出现进行替换;不加 g,表示只对搜索
LibreCAD的基本使用 1、概述2、文件创建2.1 设置文件模板2.2 设置网格2.3 精度设置2.4 绘制直线2.5 图层设置2.6 标注使用2.7 字符串2.8 画笔精灵2.9其它设置 3、打印3.1 单张打印3.2 多张图纸打印 4、中文字体支持5、总结 1、概述 LibreCAD是一个开源软件,无版权风险,不用破解激活,可以创建DXF格式的文档,软件大小只有二十多M,比autocad动不动上G的大小要精简的多。对于一些比较简单的图纸还是可以胜任的。对于那些公司不让用盗版软件,然后限于岗位限制无法申请到autocad的license的小伙伴是一个比较好的选择。此文档中使用的软件版本为2.2.0-RC2。
在Librecad官方论坛里,管理员明确说明了此软件可以进行商用画图,没有任何限制。
2、文件创建 本次要绘制的图纸如下图。
2.1 设置文件模板 设置文件模板,文件模版就是一个dxf 文件可以进行单独编辑和创建。
插入A3图框,插入的图框是一个图快,需要选中修改,拆分后方可编辑。另外可以自行创建图快,这样可以复用标准元件,提升效率。也可以对原A3模板进行修改精简。
2.2 设置网格 使用时,可以开启网格显示,关闭自动缩放网格。
在图纸选项中勾选显示网络,x和y设置为5,如果设置为自动,那么在放大缩小图纸时,网格会发生改变。设置完成后,栅格为5,且不会因为缩放发生变化。正交格子为2D视图,等角格子为3D视图。
等交格子为三维示意图 ,一个简单的示意图如下
设置为5的显示效果。开启栅格后,再开启栅格捕捉,非常适合各种框图的绘制。
设置为自动的显示效果,会自动变为10。
2.3 精度设置 精度设置,负号要占用一位精度,比如说精度是0.000,那么在使用@命令时,@1.031,2.141是可以用的,但是@1.031,-2.141就不能用,输入这种指令后,软件也不报错,也不给你定位点。
2.4 绘制直线 绘制直线,绝对坐标系,绝对坐标系在红十字叉位置。线的长度为600mm。
绘制直线,相对坐标系,设置相对参考原点,@命令,相对坐标系在红点处。@300<90意思是相对于相对原点长度300,角度为90度。此为极坐标系,输入@300,300 表示在第一点位置x方向偏置300,在y方向偏置300。或者输入300…300 是同样的作用,这样就可以使用数字键盘,不用找@符号和,了,会方便快捷很多。
绝对坐标系输入,300,300表示在绝对坐标系下跳到300,300的点,输入u为撤销命令,输入c为闭合命令。
设置正交走线图标,中下部分像电视一样的图标可以用来打开关闭上下左右侧的工具栏。
修剪操作,选中部分保留,未选中部分剪切掉。
绘制圆形,选择第一项。也可以选择其它项,在顶侧的新出现的弹框中,可以输入半径等。
使用圆心半径绘制圆形,在顶侧提示框中输入半径数据
特性,改变圆的相关参数,可以改变圆心位置以及半径,这样通过绝对坐标系快速调整圆的位置。
2.5 图层设置 增加标注图层,#为打开构造,此时线无限长,方便对齐,双击某层,即选中某层。也可右键菜单对涂层进行编辑。在图层使用中,绘图时不要使用0层,0层的是无图层的意思,只用来构建图块用。
2.6 标注使用 标注层相关参数修改,依据零件大小,设置统一缩放率,让标注与图纸看起来比例比较协调。
2.7 字符串 添加文本串,如果使用文本则不方便调整字体大小,太窄字会挤到一起,太宽则会很难看,推荐用文本串。
修改-》特性,修改文本串。
绘制完成后最后的成品图纸,达到预期,可以使用画笔精灵对颜色进行管理,选中多个对象使用画笔精灵里的颜色右键应用到所选对象。
2.8 画笔精灵 画笔精灵,可以一次改变多个对象的颜色。
2.9其它设置 默认打开自动适应窗口,勾选此项后,每次打开图纸都会铺满整个工作空间。可以勾选激活图层时,修改选中实体的图层。作用时,选中实体后,再点击图层,实体会对应切换到相应的图层,这在大规模改变实体图层时非常有用。
开启标签模式,这样在一个软件中,可以显示多个图纸,通过layout设置可以设置标签的样式以及所在的位置 。
导出为图片是正常的,但是导出为PDF则显示一片空白。建议使用打印成PDF。
选中为草图,所有文本以及填充都不可见。
输入命令cal打开命令行里的计算器,再次输入一次为关闭,可以在绘图过程中做一些简易的计算。
设置标准比例,将如下长度系数由原来的1设置为2时,标准的长度由原来的300变为600。
目录
SPA(Single Page Application) 单页面应用 1. 单页面应用与多页面应用对比
2. 单页面应用步骤
3. SPA路由跳转
SPA(Single Page Application) 单页面应用 单页面是指整个应用程序只有一个唯一完整的 HTML 页面,而其它所谓的页面,其实都是组件片段而已,切换页面也只是切换一个 HTML 中显示不同的组件片段。在今后所有的开发项目都是单页面应用。
1. 单页面应用与多页面应用对比 多页面应用
单页面应用
请求次数
每切换一次页面,都向服务器端重新发送请求;反复切换页面就会反复发送请求,请求次数多。
在首次加载时,就将唯一完整的HTML页面和所有其余页面组件一起下载下来,即使反复切换页面也不需要反复向服务器发送请求,请求次数绝对少。
公共资源
每次切换页面,都要重新请求页面中的bootstrap.css、jquery.js、bootstrap.js等多个页面都要用到的资源,请求次数多加载慢。
每次切换页面时,唯一完整的HTML外壳没有切换,所以不会重复发送请求,下载css和js文件,请求次数又少了很多,同时加载效率高。
加载效率
每次切换页面,都要删除旧的整棵DOM树,重建整棵DOM树,效率低。
每次切换页面时,因为只跟换部分组件片段显示,整个页面没有更换,DOM树也只更换部分节点,不用重建整棵DOM树,效率高。
页面切换动画
几乎不可能实现页面切换动画,因为页面切换需要同时看到前一个页面的后一半以及后一个页面的前一半;多页面应用不可能两个页面同时存在,所以无法实现。
比较容易实现页面切换动画,因为单页面应用的所有页面组件已经同时保存在客户端了,同时显示也是有可能的。
2. 单页面应用步骤 (1)先创建唯一完整的 HTML 页面(一个支持 vue 基本结构的空页面)
<script src="js/vue.js"> <body> <div id="app"> </div> <script> new Vue({ el: "#app", }) </script> </body> (2)创建所有"页面"组件文件
a. 项目中,有几个"页面",就要创建几个页面组件文件;
b. 所有页面组件都要集中放在一个名为 views 的文件夹中;
c. 每个页面组件其实都是一个子组件;
d. 在唯一完整的 HTML 页面顶部引入页面组件;
图片像素大小怎么调整?相信还不明白像素是什么意思吧,这是一种比较专业的说要像素是组成图片的最小单元,单位是px。举一个例子,图片尺寸为500*400,是指图片的宽度是500像素,高度是400像素,所以我们常说的修改图片像素就是修改图片的尺寸。在图片使用过程中经常需要调整图片像素,不过很多小伙伴还不知道如何调整。
修改图片像素是一个比较基础的电脑操作技能,使用率还是比较高的,下面我就来教大家详细的修改方法吧,支持批量统一调整图片像素,适合经常需要处理大批量图片的小伙伴,提高处理效率,建议有需要的小伙伴仔细往下阅读哦。
需要使用的工具:优速图片格式转换器
工具下载地址:https://download.yososoft.com/jimp/2.0.1/jimp_2.0.1.exe
具体的操作步骤如下:
步骤1,先在电脑上下载需要使用的“优速图片格式转换器”工具,然后打开使用,选择左边的【更改尺寸】功能,从这里进行图片像素的修改。
步骤2,点击【添加文件】蓝色按钮,将需要调整像素的图片添加到软件中,支持批量处理,所以可以同时可以多张图片哦。
步骤3,进行设置,修改方式有两种:按比例,就是将图片像素按照设置的缩放比例进行放大或者缩小;按尺寸,则是将图片像素调整成设置的宽度和高度。具体方式根据自己的需求选择。
步骤4,点击右上角的【开始转换】红色按钮启动软件我,完成调整后软件会自动打开输出文件夹,方便我们查看修改后的图片。
步骤5,从结果可以看到,所有图片的像素尺寸全部调整成了相同的大小。
其实很多人常说的调整图片像素就是调整图片的尺寸大小,如果还有小伙伴不知道如何操作,就请看看上面的详细操作步骤吧,步骤比较简单好用,批量处理更能帮助我们提高办公效率,是不可多得的办公使用技巧,快去试一试吧。好了,今天关于“图片像素大小怎么调整”的分享就到此结束了,感谢大家的支持。
在TestDB数据库中,编写一个存储过程proc_test_func,要求如下:
1)输入参数 一个整型的输入参数 @value
2)要求在一个select语句返回:
@value的绝对值,
此绝对值的平方,
此绝对值的平方根(保留两位小数),
此绝对值的自然对数(保留两位小数),
以此绝对值的为半径的圆的面积(保留两位小数),
别名依次为:abs, sq, sqrt,log, square
测试语句:
proc_test_func -35;
proc_test_func 0;
proc_test_func 15;
代码如下:
create procedure proc_test_func @value int as begin declare @abs int declare @sq int declare @sqrt float declare @log float declare @square float set @abs = abs(@value) set @sq = SQUARE(@abs) set @sqrt = ROUND(sqrt(@abs),2) set @log = ROUND(LOG(@abs),2) set @square = ROUND(SQUARE(@abs)*PI(),2) select @abs 'abs',@sq 'sq',@sqrt 'sqrt',@log 'log',@square 'square' end
来自东哥IT笔记
现在很多CPU都支持多核,甚至是手机都已经开始支持多核了。而Python的GIL(Global Interpreter Locko)则使得其没法使用这些多核带来的优势。还好从Python2.6开始,引入了multiprocessing模块,我们终于可以使用多核带来的便利了。
使用多进程的优点使用多进程的缺点使用multiprocessing来创建多进程Process的子类化创建进程池 本文并不是一个multiprocessing的全面的介绍,假如你想全面的了解它,可以参见官方的文档:
https://docs.python.org/2/library/mul
使用多进程的优点 使用多进程有很多优点:
多进程使用独立的内存空间相比于线程,代码更加直观能够使用多个CPU/多核避免GIL子进程可以被kill(和thread不同)multiprocessing有和threading.Thread类似的接口对CPU绑定的进程比较好(加密,二进制搜索,矩阵乘法等) 使用多进程的缺点 使用多进程也有一些缺点:
进程间通信更加复杂内存的占用大于线程 使用multiprocessing来创建进程 multiprocessing是用来模拟threading.Thread类工作的。下面就是一个使用它的例子:
import multiprocessing import random import time def worker(name: str) -> None: print(f'Started worker {name}') worker_time = random.choice(range(1, 5)) time.sleep(worker_time) print(f'{name} worker finished in {worker_time} seconds') if __name__ == '__main__': processes = [] for i in range(5): process = multiprocessing.Process(target=worker, args=(f'computer_{i}',)) processes.append(process) process.start() for proc in processes: proc.join() 首先第一步需要import multiprocessing模块,另外两个import分别是为random和time服务的。
worker函数就是用来假装做一些事情,传入一个name的参数,没有什么返回,他首先打印name的值,然后随机sleep一段时间用来模拟做一段很长时间的工作,最后打印work finish。
紧接着,你使用multiprocessing.Process创建了5个进程,他的使用和threading.Tread()比较类似,你告诉Process哪个目标函数需要调用,以及会传入什么参数给他们,然后你调用了start函数来启动进程。另外你会把这些进程加入到一个list中。
最后,你遍历这个list,调用join方法,这个方法其实就是告诉Python等到进程结束。
Process的子类化 multiporcessing模块中的Process类是可以子类化的,他和threading.
第1章 层叠、优先级和继承 1.1 层叠 层叠规则
1.1.1 样式表的来源 用户代理样式表:浏览器默认样式。
作者样式表:自己设置的样式。
作者样式覆盖用户代理样式,因为作者样式的优先级更高
!important声明 在声明的后面、分号的前面加上!important,该声明就会被标记为重要的声明
color: red !important; 总体的优先级
作者的!important作者用户代理 1.1.2 理解优先级 浏览器将优先级分为两部分:HTML的行内样式和选择器的样式
行内样式 如果用HTML的style属性写样式,这个声明智慧作用于当前元素。实际上行内元素属于“带作用域的”声明,它会覆盖任何来自样式表或者<style>标签的样式
选择器优先级 不同类型的选择器有不同的优先级。优先级的准确规则如下:
如果选择器的ID数量更多,则它会胜出(即它更明确)。如果ID数量一致,那么拥有最多类的选择器胜出。如果以上两次比较都一致,那么拥有最多标签名的选择器胜出。 Attention! 伪类选择器和属性选择器与一个类选择器的优先级相同
通用选择器(*)和组合器(>、<、~)对优先级没有影响
优先级标记 常用的表示优先级的方式
用数值形式来标记,通常用逗号隔开每个数。比如,“1,2,2”表示选择器由1个ID、2个类、2个标签组成。优先级最高的ID列为第一位,紧接着是类,最后是标签。
有时,还会用4个数的标记,其中将最重要的位置用0或1来表示,代表一个声明是否是用行内样式添加的。此时,行内样式的优先级为“1,0,0,0”。它会覆盖通过选择器添加的样式,比如优先级为“0,1,2,0”(1个ID和2个类)的选择器。
1.1.3 源码顺序 如果两个声明的来源和优先级相同,其中一个声明在样式表中出现较晚,或者位于页面较晚引入的样式表中,则该声明胜出。
链接样式和源码顺序 //顺序不可改变 a:link { color: blue; text-decoration: none; } a:visited { color: purple; } a:hover { text-decoration: underline; } a:active { color: red; } 书写顺序之所以很重要,就是因为层叠。像上述的代码如果顺序发生变化,这个效果就会遭到破坏。
层叠值 如果一个声明在层叠中“胜出”,它就被称作一个层叠值。元素的每个属性最多只有一个层叠值。
1.1.4 两条经验法则 (1)在选择器中不要使用ID。
报错内容 FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:Got exception: org.apache.hadoop.hive.metastore.api.MetaException You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'OPTION SQL_SELECT_LIMIT=DEFAULT' at line 1) 解决办法 第一种,hql语句有问题(大多数是这个) 再检查一遍自己写的Hql语句。
第二种,yarn资源不足 调整hadoop配置文件yarn-site.xml中yarn.nodemanager.vmem-pmem-ratio的值:
<property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>2048</value> <description>default value is 1024</description> </property> 调整该参数,上述问题可得到解决。
文章目录 基本框架基本属性文本与背景主题修改 点击效果图片变换颜色变换 基本框架 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:layout_width="200dp" android:layout_height="100dp"/> </LinearLayout> 基本属性 在上面的xml文件中Ctrl+左键点进Button可以看到该类是继承自TextView类的,也就是说在TextView部分讲到的都可以用在Button上。
文本与背景 在这里我们就简单的设置下按钮上的文本为"Push Me",背景颜色设置为紫色(这两个资源都被保存在values文件夹的三个xml文件里),但奇怪的是文本都被强制转换成了大写,而设置背景也无效。
主题修改 问题出在主题文件themes.xml上,我们需要进入该文件,将textAllCaps设为false,就可以取消强制大写,即加入下面的代码:
<item name="textAllCaps">false</item> 然后我们还需要把基础主题文件由
<style name="Theme.MyButton" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> 改为
<style name="Theme.MyButton" parent="Theme.MaterialComponents.DayNight.DarkActionBar.Bridge"> 这样就可以让我们的设置生效了:
虽然设置了按钮的基本属性,但是现在这个按钮看上去跟TextView也没什么区别,点击也毫无反应,接下来我们就要设置一下点击效果。
点击效果 本次要实现的效果主要是点击以后按钮的背景随之更换,所以我们在res->drawable文件夹下新建一个Drawable Resource文件,起名为background_shift。可以看到,该文件的根节点为图片选择器selector。
图片变换 然后我们加入一点图片资源,点击res,右键new->Vector Asset,进入这个界面后点击Clip Art选择一个喜欢的图标,比如我选择了WiFi:
同时我另导入了一张WiFi关闭的图标。
导入后,就可以在background_shift文件中使用了,在这里我通过state_pressed设置按下时显示WiFi,不按下时显示WiFi关闭,代码如下:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_baseline_wifi_24" android:state_pressed="true"/> <item android:drawable="@drawable/ic_baseline_wifi_off_24" android:state_pressed="false"/> </selector> 写好了background_shift.xml,就可以在activity_main.xml中使用了,将Button的background属性设置为该资源即可实现背景变换。
颜色变换 做颜色变换与图像变换类似,不同之处在于资源存放位置不同。在res文件夹,我们新建一个color文件夹,右击rec,在new->Directory中新建文件夹,取名color
之后在color中也建立一个Drawable Resource文件,然后设定按下时为蓝色,默认为红色:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="#ff0000ff" android:state_pressed="true"/> <item android:color="
似乎最近能看到和阿里云盘相关的信息不少,前几天TJ君才刚和大家一起聊过基于阿里云盘的WebDAV服务(阿里云盘能玩出怎么样的花活呢?做一个webdav协议的服务器怎么样?)
今天呢TJ君又看到了一个阿里云盘小白羊版,觉得很有意思,来和大家分享。
阿里云盘小白羊版,🐏,其实就是基于阿里云盘网页版开发的开源PC版。
小白羊支持win7-11,macOS,linux等多个平台,目前已经完成的功能有:
多账号登录
常用文件操作(新建文件夹、收藏、重命名、复制、移动、删除、详情、视频雪碧图)
在线播放原始视频
在线播放转码视频
在线预览图片
在线预览文本
在线预览 word/excel/ppt/pdf、
连接到远程 Aria2 下载
上传文件
上传文件夹
批量改名
在线解压
回收站
收藏夹
分享文件
导入阿里云分享链接
缩略图列表
网盘内文件搜索
视频文件洗码
未来正在开发计划中的功能有:
相册功能
网盘和相册间文件互相复制
文件同步盘
重复文件扫描
帐号间文件复制
很多小伙伴会问,那么这个小白羊跟其他的客户端有什么不一样的地方呢?
TJ君观察下来,首先小白羊的特点之一就是快!
作者做过测试,以上传和下载4.4万个json格式小文件(共24GB)为例,传统客户端需要分别用时41分钟+59分钟,如果使用小白羊版本的话,只需24分钟+25分钟,差不多快了一倍左右。
而如果试验对象换成33个大文件(共90GB)的话,对应的结果则分别是3+72分钟和1+38分钟,也是差了一倍左右。
除了快,小白羊还有一些独特的好处:
支持同时登录多个账号管理
特有文件夹树,可以快速方便的操作
支持直接在线播放网盘里的各种格式的视频并且是高清原画,支持外挂字幕/音轨/播放速度调整,比官方的格式更多更清晰
可以显示文件夹体积,可以文件夹和文件混合排序(文件名/体积/时间),并且文件名排序时更准确!
可以通过远程Aria2功能把文件直接下载到远程的VPS/NAS上
可以批量的对 大量文件/多层嵌套的文件夹 一键重命名
可以快速复制文件,可以直接预览视频的雪碧图,可以直接删除文件
支持数万文件夹和数万文件的管理,支持一次性列出文件夹里包含的全部文件
支持单次上传/下载 一百万 量级的文件/文件夹
我们再来看下小白羊的庐山真面目。
怎么样?想尝试一下小白羊的小伙伴,赶紧来下载吧!
点击下方卡片,关注公众号“TJ君”
回复“小白羊2022”,获取仓库地址
关注我,每天了解一个牛x、好用、有趣的东东
往期推荐
增强使用功能的Steam开源工具箱一枚
基于Docker的开源端到端开发者平台
阿里云盘能玩出怎么样的花活呢?做一个webdav协议的服务器怎么样?
定义栈的两种方式 Java中有一个栈的方式为
Stack<Integer> stack = new Stack<>(); 我一般也会使用这个,今天查看JavaAPI文档,发现官方文档中说到
用这个使用栈更推荐,话不多说,先来个小目标-“进行一亿次操作”,先用我们常用的方式试试。
Stack<Integer> stack = new Stack<>(); long l = System.currentTimeMillis(); for(long i = 0;i<(long) 1000000000;i++){ stack.push(10); Integer pop = stack.pop(); } long l1 = System.currentTimeMillis(); System.out.println("时间为:"+(l1-l)); 时间为:17887
时间为17秒
Deque<Integer> stack1 = new ArrayDeque<>(); long l = System.currentTimeMillis(); for(long i = 0;i<(long) 1000000000;i++){ stack1.push(10); Integer pop = stack1.pop(); } long l1 = System.currentTimeMillis(); System.out.println("时间为:"+(l1-l)); 时间为:1474
只用了1.4秒
由此可见,两者差距特别大。
下面看原因
在推荐的使用中,该pop方法是非线程安全的,但是在Stack中是线程安全的。
这里就类似于 HashTable与HashSet的区别,HashTable是线程安全的,而HashSet是非线程安全的。
以上仅个人见解,如有错误感谢指正。
题目:
解题思路: 1. 先要声明两个变量x ,y;其中 x 获取用户输入,y根据关系式获得赋值。也可声明一个变量,不过看起来就没两个变量那么清晰
2. 利用scanf函数获取用户输入。
3.用条件语句,来确定 y 关于 x 的函数。
4. 利用printf()输出 y值 。
注:此题可以用变量可以是float double 等类型,这里介绍两种方法
注意事项: 1)利用条件语句时,条件 1 <= x < 10,在if条件语句 要写成 x >= 1 && x < 10;而非1 <= x < 10
2)关系式 y =2x - 1; 写成代码的形式要把2x中的乘号写出,即 2 * x
参考代码:
i :int类型的变量
#include <stdio.h> int main(void) { int x, y; scanf("%d", &x); //获取用户输入 if (x < 1) //这里的if语句可以是多种形式,可以是三个if语句 也可以是if else if else嵌套 y = x; if (x >= 1 && x < 10) y = 2*x -1; if (x >= 10) y = 3*x - 11; printf("
目录
一、什么是泛型
二、泛型方法
三、泛型接口
四、通配符
4.1、通配符
4.2、上限通配符
4.3、下限通配符
4.4、类型擦除
一、什么是泛型 泛型:就是指在类定义时不会设置类中的属性或方法参数的具体类型,而是在类使用时(创建对象)再进行类型的定义。会在编译期检查类型是否错误。
类声明后的<>中这个T被称为类型参数,用于指代任意类型,实际上这个T只是个代表,写什么都可以。表示此时的value1,value2都是在类定义时没有明确类型,只有在使用时才告知编译器类型。出于规范,类型参数用单个的大写字母来代替,常见如下:
T:代表任意类E:表示Element的意思,或是异常K:与V搭配使用V:与K搭配使用 泛型的使用:
若此时value1和value2的类型不一定相同,就定义多个类型参数:
注意:非静态内部类会复用外部类的泛型参数,静态内部类不会复用外部类的泛型参数。 二、泛型方法 此处的泛型方法指的是有自己的类型参数
泛型方法始终以自己的类型参数为准,和类中的类型参数无关:
为了避免混淆,一般定义泛型方法时,尽量避免使用类中使用过的类型参数字母:
三、泛型接口 泛型接口:
子类在实现接口时有两种选择,①要么继续保留泛型,②要么定义子类时明确类型 ①保留泛型
②定义子类时明确类型
四、通配符 4.1、通配符 <?> 一般用在方法参数,表示可以接受该类所有类型的泛型变量。
例如:
注意:<?>只能调用对象的getter方法来获取属性,由于此时根本无法确定传入对象的类型,因此无法调用对象的setter来设置值。 4.2、上限通配符 <? extends 类> 表示?可以指代任何类型,但是该类型必须是后面类的子类。
例如:
此时表示?<=Number,此时?可以是Number类本身,或者Number的子类,除此之外其他类型都不可以。
注意:?表示可以接收Number及其子类,但是子类之间不能互相转换,所以上限通配符仍然不能调用对象的setter方法设置一个具体的属性值。
extends可以用在泛型类的定义上:
此时T可以指代任意Number类及其子类的类型。
4.3、下限通配符 <? super 类> 此时?表示可以指代任意类型,但是该类型必须是后面类的父类。
例如:
此时表示?必须是String及其父类,所有此时?只能指代String或Object。
注意:下限通配符可以调用对象的setter方法设置一个具体的属性值,无论?是什么类型,规定好的下限类型一定可以通过向上转型变为父类。 4.4、类型擦除 类型擦除:所有泛型类型参数,若没有设置泛型上限,则编译之后统一擦除为Object类型,若设置了泛型上限,则编译之后统一擦除为相应的泛型上限。
第十二届蓝桥杯c++b组(第二场) 试题A 求余 #include<iostream> using namespace std; int main() { cout << 2021 % 20; return 0; } //答案:1 试题B 双阶乘 #include<iostream> using namespace std; int main() { int n = 2021, res = 1; for(int i = 2021; i >= 1; i -= 2) { res = res * i % 100000; } cout << res; } //答案:59375 试题C 格点 #include<iostream> using namespace std; int res; int main() { for(int i = 1; i <= 2021; i ++) for(int j = 1; j <= 2021; j ++) if(i * j <= 2021) res ++; cout << res; return 0; } //答案:15698 试题D 整数分解 思路:隔板法,可以将题目类比为2021个小球,中间放四个隔板,每个隔板变化极为一种方式,所以可以推出结果为C(2020, 4)
这篇文章中,将向你展示如何使用阿帕奇服务器 实例来服务多个站点。基于环境是 Fedora 27 虚拟机,配置了阿帕奇2.4.29。如果你用另一个发行版或不同的 Fedora 版本,那么你使用的命令以及内容和文件配置的位置可能会有所差异。
阿帕奇服务器的所有配置文件都位于 /etc/httpd/conf 和 /etc/httpd/conf.d。默认站点的数据位于 /var/www 中。对于多个站点,就需要提供多个位置,每个位置对应主机的站点。
基于虚拟主机名称
使用基于虚拟主机名称,你可以为多个站点使用一个 IP 地址。现代 Web 服务器,包括阿帕奇服务器,使用指定 URL 的 hostname 部分来确定哪个虚拟 Web 主机响应页面请求。这仅仅需要比一个站点更多的配置。
即使只从单个站点开始,那也建议你将其设置为虚拟主机,这样以后就能更轻松地添加更多站点。
准备原来的网站站点
设置第二个站点之前,我们需要为现有网站提供基于名称的虚拟主机。如果现在没有站点, 那么需要返回并立即创建一个 。
如果有了站点,将以下内容添加到
/etc/httpd/conf/httpd.conf 配置文件的底部(添加此段内容是我们需要对 httpd.conf 文件进行的唯一更改):
DocumentRoot /var/www/html
ServerName www.site1.org
这将是第一个虚拟主机配置节,它应该保持为第一个,以使其成为默认定义。这意味着通过 IP 地址或解析为此 IP 地址但没有特定命名主机配置节的其它名称对服务器的 HTTP 访问将定向到此虚拟主机。所有其它虚拟主机配置节都应跟在此节之后。
你还需要使用 /etc/hosts 中的条目设置你的网站以提供名称解析。通常,这可以使用你使用的任何名称服务来完成。通过在 /etc/hosts 中的 localhost 行添加一个新名称来完成此操作。添加两个网站的条目,方便你以后不需再次编辑此文件。结果如下:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 www.site1.org www.site2.org
让我们将 /var/www/html/index.html 文件改变得更加明显一点。
Hello World
Web site 1.
重新启动 HTTPD 服务器,已启用对 httpd 配置的更改。然后,我们从命令行使用 Lynx 文本模式查看网站。
一.switch语句
switch (表达式) {
case 常量 1:
语句;
break;
case 常量 2:
语句;
break;
default:
语句;
}
遇到 break 关键词,它会跳出 switch 代码块。
default 关键词规定不存在 case 匹配时所运行的代码: 练习 var level = +prompt("请输入令狐冲的成绩"); switch (level) { case 1: alert("恭喜荣当武林盟主"); break; case 2: alert("恭喜喜提武当掌门"); break; case 3: alert("恭喜喜提峨眉掌门"); break; default: alert("逐出师门"); } 二.比较switch和多重if结构
相同点
都可以实现多分支结构
不同点
switch
只能处理等值的条件判断,且条件是整型变量或字符变量的等值判断
多重if 处理在else部分还包含其它if结构,特别适合某个变量处于某个区间时的情况
三.while循环
while ( 循环条件 ) {
循环操作
} while 循环在每次循环之前,会先对条件表达式进行求值,如果条件表达式的结果为 true,则执行{ }中的代码,如果条件表达式的结果为 false,则退出 while 循环,执行 while 循环之后的代码。
思路: 正则表达式+ 切片操作 一、找出关键词的位置 二、利用字符串的切片功能 目前想到有三种情况: 1、当关键词位于开头时,从下标为0的开始切片 2、当关键词位于结尾时,切片取到最后一个字符 3、当关键词位于中间时,取前后指定位数字符 import re string = 'The append method appends a DataFrame-like object at the end of the current DataFrame.append ' pattern = 'app' num= 6 # 截取 关键词 前后 6 个字符 for m in re.finditer(pattern, string): print(m.start(), m.end()) start=m.start() end=m.end() if m.start()-num<0: # 情况一 关键词位于开头 start=0 print(string[start:end+num]) elif m.end()+num >len(string): # 情况二 关键词位于结尾 end=len(string)-1 print(string[start-num:end]) else: # 情况三 关键词位于中间 print(string[start-num:end+num]) 输出
因为当我们把对象存入到底层为散列表结构的集合时,首先判断hashCode值,碰到相同的hashCode值之后再进行equals()进一步判断,这样保证如果两个对象是相等的,它们的equals()方法应该返回true,hashCode()也应该返回相同的结果。
遵守hashCode方法的常规约定。因为不能百分百确定这个类之后是否会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中用到,所以说重写equals()方法之后要尽量重写hashCode()方法。
注:hashCode方法的常规约定:
在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。 如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。 以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。 实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。) 当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
下面案例展示在hashSet中添加相同的元素时只重写equals()的情况:
package com.xiaoyuan.object; import java.util.HashSet; import java.util.Set; /** * Copyright: Copyright (c) 2022/3/29 Asiainfo-Linkage * * @Description: Equals()方法的测试类 * @ClassName: EqualsTest * @version: v1.0.0 * @author: wenronghui * @date: 2022/3/29 16:05 * <p> * Modification History: * Date Author Version Description * ---------------------------------------------------------* * 2022/3/29 wenronghui v1.
F . 案例 4-1.1:根据后续和中序遍历输出前序遍历
Description
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
Input
第一行给出正整数N (≤30),是树中结点的个数。随后两行,每行给出N 个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
Output
在一行中输出Preorder: 以及该树的先序遍历结果。
Samples
Input 复制
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
Output
Preorder: 4 1 3 2 6 5 7
先贴一篇dalao模拟的题解
整体思路:由后序遍历找到根节点,然后在中序遍历中找到分割点,然后递归遍历左右子树即可。
非建树做法: #include<bits/stdc++.h> using namespace std; const int N=1010; int post[N],mid[N]; void Pre(int *post,int *mid,int l){ if(l<=0) return ; cout<<" "<<post[l-1]; int i;//定义左子树的长度 for(i=0;i<l;i++) if(mid[i]==post[l-1]) break;//在中序遍历中找到分割点 Pre(post,mid,i);//由于我们定义根节点为post[l-1]所以这里我们传长度i Pre(post+i,mid+i+1,l-i-1);//由于左子树长度为i那么去下刚输出的根节点就是l-i-1 } /* 7 2 3 1 5 7 6 4 //post 1 2 3 4 5 6 7 //mid 4 1 3 2 6 5 7 */ int main(){ int n; cin>>n; for(int i=0;i<n;i++) cin>>post[i]; for(int i=0;i<n;i++) cin>>mid[i]; cout<<"
今天用svn上传文件的时候出了这么个错误。下面写一下解决方法。
将准备上传到的文件夹右键,选择TortoiseSVN里面的Clean up,把Break write locks前面的勾给勾上,如图:
然后OK,再重新上传文件就好了。
主要参考大佬博客:
https://zhuanlan.zhihu.com/p/86718461https://blog.csdn.net/u010451780/article/details/108356447 1) 重要参数 zParametersBundlingDefault.txt s_numLocalNonLinIterations = 2; //局部非线性优化迭代次数s_numLocalLinIterations = 100; //局部线性优化迭代次数,重要s_numGlobalNonLinIterations = 3; //全局非线性优化迭代次数s_numGlobalLinIterations = 150; //全局线性优化迭代次数s_downsampledWidth = 80; //用于Correspondence Filtering中的dense verification中,如果设置的不恰当,会导致在跟踪过程中,容易跟踪失败,导致重建的稠密模型缺失s_downsampledHeight = 60;s_sensorIdx = 8; //输入数据模式,1~7代表不同的深度相机实时扫描输入,8代表离线.sens文件s_RenderMode = 1; //程序运行时窗口实时展示的模式,Tab键显示菜单,输入不同数字或字母显示不同模式;s_maxNumImages = 1200;//最大帧数s_submapSize = 10;//每个localBundle最大帧数 zParametersDefault.txt s_maxNumKeysPerImage = 1024; //每一帧图像上检测的最多的sift特征点的个数。s_integrationWidth = 320; //使用的帧size,需根据自己数据的分辨率修改s_integrationHeight = 240;s_maxNumImages = 1200; //最大帧数s_submapSize = 10; //每个localBundle最大帧数s_maxNumKeysPerImage = 1024; //每帧最大特征点数s_marchingCubedMaxNumTriangles = 6000000; //生成mesh时最大的面片数,设置过小可能导致重建的mesh残缺破破烂烂的 2) 程序梳理 Fredver.cpp是主程序入口,bundlingThreadFunc开启多线程分层优化特征提取匹配过滤实现位姿估计,startDepthSensing从传感器读取数据并重建。
main() FriedLiver.cpp:程序入口
g_RGBDSensor = getRGBDSensor();//根据你设置的s_sensorIdx来判断你输入的数据的形式,是深度相机还是.sens文件。g_RGBDSensor->createFirstConnected(); //这个函数主要是读取输入的.sens文件中的数据,彩色图,深度图,pose,还有info.txtg_imageManager = new CUDAImageManger();std::thread bundlingThread(bundlingThreadFunc); //开启多线程,进行跟踪和优化 如果已经处理的最后一帧是localBundle的第一帧,则等待上一次solve优化完如果已经处理的最后一帧是localBundle的最后一帧,则开始新的solve优化 std::thread(bundlingOptimizationThreadFunc); //11帧为一个chunkbundlingOptimization(); g_bundler->process(); optimizeLocal()processGlobal()optimizeGlobal() 等待新的输入数据,处理输入processInput,通知DepthSensing startDepthSensing(g_bundler, getRGBDSensor(), g_imageManager); //调用DX进行渲染,从传感器中读取数据,重建 startDepthSensing() DepthSensing.
Vue.js 过滤器的基本使用(filter) vue中的过滤器分为两种:局部过滤器和全局过滤器。全局过滤器定义在vue类中,句柄过滤器定义在vue实例中。
1、定义无参全局过滤器
Vue.filter('msgFormat', function(msg) { // msg 为固定的参数 即是你需要过滤的数据 return msg.replace(/单纯/g, 'xxx') }) 完整示例
<div id="app"> <p>{{ msg | msgFormat}}</p> </div> <script> // 定义一个 Vue 全局的过滤器,名字叫做 msgFormat Vue.filter('msgFormat', function(msg) { // 字符串的 replace 方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则 return msg.replace(/单纯/g, 'xx') }) </script> 2、定义有参全局过滤器
<div id="app"> <p>{{ msg | msgFormat('疯狂','--')}}</p> </div> <script> // 定义一个 Vue 全局的过滤器,名字叫做 msgFormat Vue.filter('msgFormat', function(msg, arg, arg2) { // 字符串的 replace 方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则 return msg.replace(/单纯/g, arg+arg2) }) </script> 3、局部过滤器
mybatis-plus中有两种代码生成器,若想看官网也自行点击跳转->点击官网首页“快速开始”后在目录就可看到。这里演示的是官网上旧的代码生成器
1、导入pom依赖
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.3.1</version> </dependency> 注意,这里只导入生成器的generator类包,还需要mybatis其他包请自行导入。
2、创建一个测试类
//创建globalConfig对象 GlobalConfig globalConfig = new GlobalConfig(); //设置全局配置 globalConfig.setActiveRecord(true)//AR模式,一个模型类对应一个数据库中的一个表 .setAuthor("设置每个文件头部注释的作者显示")//设置作者 .setIdType(IdType.AUTO)//设置主键生成策略,这里是自动增长 .setOutputDir("E:\\idea\\life\\src\\main\\java")//设置生成路径,这里是全路径,不管你项目java目录下有没有其他page都没有影响,但是为了不必要的异常,最后包中不要有其他文件 .setFileOverride(true)//设置生成文件覆盖 .setServiceName("%sService")//设置生成的serivce接口的名字,这里是设置了接口的名称,例如AdminServiceImpl,这里前缀%s为你数据库表,建立的文件名称都是驼峰标识的 .setBaseResultMap(true) //设置基本的结果集映射 .setBaseColumnList(true);//设置基本的列集合 //设置数据源的配置 //数据源就根据你自己配置更改吧 DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver") .setUrl("jdbc:mysql://localhost:3306/life?serverTimezone=UTC") .setUsername("root").setPassword("root"); // 进行策略配置 StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setCapitalMode(true)//设置全局大写命名 .setNaming(NamingStrategy.underline_to_camel)//数据库表映射到实体的命名策略 .setTablePrefix("")//设置表名前缀 .setExclude();//生成的表,setExclude():这里是除什么在外,还有setInclude(“指定表”),当然两个都可以为空,这里是指定不生成的表为空,也就是全部配置 // 进行包名的策略配置,这里自己指定自己需要的 PackageConfig packageConfig = new PackageConfig(); packageConfig.setParent("com.csh") .setMapper("mapper") .setService("service") .setController("controller") .setEntity("bean") .setXml("mapper"); //整合配置 AutoGenerator autoGenerator = new AutoGenerator(); autoGenerator.setGlobalConfig(globalConfig).setDataSource(dataSourceConfig).setStrategy(strategyConfig) .setPackageInfo(packageConfig); autoGenerator.execute(); 最后附上mybatis generator的应用
前言 在DJango项目开发中遇到了一个问题,已经写好的接口(A接口)需要在另一个接口(B接口)中调用,但是写好的这个接口必须要传递request参数,且接口返回的是JsonResponse对象。
A接口部分代码如下:
def get_monthly_usage(request): """计算月使用率""" if request.method == 'GET': return Http404 module_name = request.POST.get('module_name', '') date = request.POST.get('date', '') ..... return JsonResponse(row_datas, safe=False) 解决办法 使用request.POST.copy()
复制 request body 数据 到 data 中,对data进行修改
B接口代码如下:
def get_all_modules_usage(request): '''获取所有模组的使用率''' all_modules_name = list(Licenses.objects.values_list('moduleName')) all_data = list() for m in all_modules_name: # 修改request中的POST数据,然后传递给 get_monthly_rate data = request.POST.copy() data['module_name'] = m[0] data['date'] = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m') request.POST = data res = get_monthly_usage(request) # 由于get_monthly_usage返回的是JsonResponse对象,必须加上以下代码 data_formatt = eval(res.
在线硬件检测工具:
# 测试网址1 主要检测显卡显示效果
volumeshader_bm
# 测试网址2 可以检测cpu GPU 屏幕等
精大师在线显卡测试_首页 | 网页版GPU性能测试工具
一.Junit介绍 Junit是一个Java语言的单元测试框架,简单理解为可以用于取代java的(部分)main方法。Junit属于第三方工具,需要导入jar包后使用。
二.Junit的基本使用(重点) a.在当前模块下创建lib文件夹
b.把junit的jar包,拷贝到lib的文件夹中
c.把jar包添加到图书馆中
package com.itheima.demo01Junit; import org.junit.Test; /* junit的作用:可以单独的运行某一个方法(对方法进行测试) 使用步骤 1.导入junit的jar包 2.在要运行的方法上边,添加一个@Test注解(需要导包) 3.点击方法左边的绿色三角或者鼠标右键点击方法,选择Run 方法,运行方法 点击类左边的绿色的三角或者鼠标右键点击类名,选择Run 类名,可以运行类中所有被@Test修饰的方法 鼠标右键点击模块,选择'Run All Tests',可以运行模块中所有类里被@Test修饰的方法 */ public class Demo01Junit { @Test public void show01(){ System.out.println("show01方法"); } @Test public void show02(){ System.out.println("show02方法"); } @Test public void show03(){ System.out.println("show03方法"); } } 三.Junit的注意事项 package com.itheima.demo01Junit; import org.junit.Test; /* Junit的注意事项 1.没有添加@Test注解的方法,不能使用Junit运行的 2.Junit只能运行public修饰的,没有参数,没有返回值的非静态方法 */ public class Demo02Junit { //1.没有添加@Test注解的方法,不能使用Junit运行的 public void show01(){ System.out.println("Demo02Junit show01方法"); } //java.lang.Exception: Method show02() should be public 方法show02应该被public修饰 //@Test private void show02(){ System.