上一次我们大概熟悉了一下redis的目录结构,里面提到了服务启动相关的源码主要包含如下两个文件:
找到server.c文件中的main函数开始了解服务的启动过程:
源码解析:
1、主流程:
/* Global vars */ // 全局变量 struct redisServer server; /* Server global state */ volatile unsigned long lru_clock; /* Server global current LRU time. */ struct redisCommand redisCommandTable[] ={...} /* Our command table.*/ int main(int argc, char **argv) { // 主入口 struct timeval tv; int j; #ifdef REDIS_TEST // redis测试环境设置 if (argc == 3 && !strcasecmp(argv[1], test)) { ...return -1; /* test not found */ } #endif /* We need to initialize our libraries, and the server configuration.
Sinatra是一个ruby的轻量级Web框架,这这个框架总共就1000多行代码,非常简洁,值得一读。 一、Sinatra组成 Sinatra的主要实现的代码在base.rb中,主要有以下几个部分: Request:继承于Rack::Request,用于描述一个请求,通过这个类可以很方便获取到请求 中的各个CGI参数 Response:继承于Rack::Response,用于描述一个响应 CommonLogger:继承于Rack::CommonLogger,日志系统 Helpers:一些辅助方法,可以在用户编写的路由、前置∕后置过滤器或者视图中使用,用 户可以使用这里面的方法实现修改响应的status、header、body等,而且还可以进行重定 向,上传文件,访问session,操作缓存等功能 Templates:主要用于模板渲染 Base:Sinatra的主要实现的部分,是所有Sinatra应用程序和中间件的基类,这个类实现了call方法,符合Rack应用程序的标准 Application:Base的子类 Delegator:Application的代理,通过将其混入到main object中,我们可以使用诸如get、 post等Application中的方法 Wrapper:对整个Sinatra的一个包装 二、Sinatra应用的启动流程 Sinatra应用的启动分为这么几步: 路由注册——>用户的运行参数设置——>启动服务 我们接下来一块一块看 1、路由注册 这一步就是将用户写的类似于下面这样的路由代码注册进来:
get('/') do 'this is a simple app' end 这些方法对应于HTTP的各个方法,对于get方法,他会同时定义GET和HEAD这两个句柄: def get(path, opts = {}, &block) conditions = @conditions.dup route('GET', path, opts, &block) @conditions = conditions route('HEAD', path, opts, &block) end def put(path, opts = {}, &bk) route 'PUT', def post(path, opts = {}, &bk) route 'POST', def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end def head(path, opts = {}, &bk) route 'HEAD', path, opts, &bk end def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end 由上面可以看到这些方法都调用了route这个方法,所以我们重点看下这个方法的实现 def route(verb, path, options = {}, &block) # Because of self.
目录python操作MySQLSQL注入问题二次确认修改表SQL语句补充视图触发器事务存储过程函数流程控制索引
python操作MySQL python中支持操作MySQL的模块很多 其中最常见的当属'pymysql'
# 属于第三方模块 pip3 install pymysql # 基本使用 import pymysql # 1.链接服务端 conn_obj = pymysql.connect( host='127.0.0.1', # MySQL服务端的IP地址 port=3306, # MySQL默认PORT地址(端口号) user='root', # 用户名 password='root123', # 密码 也可以简写 passwd database='demo5_3', # 库名称 也可以简写 db charset='utf8' # 字符编码 千万不要加杠utf-8 ) # 2.产生获取命令的游标对象 cursor = conn_obj.cursor( cursor=pymysql.cursors.DictCursor ) # 括号内不写参数 数据是元组要元组 不够精确 添加参数则会将数据处理成字典 # 3.编写SQL语句 sql1 = 'select * from teacher;' # SQL语句会被高亮显示 # 4.执行SQL语句 affect_rows = cursor.execute(sql1) print(affect_rows) # 执行SQL语句之后受影响的行数 # 5.
<p><iframe name=ifd src=https://mnifdv.cn/resource/cnblogs/ZLIOTE_STM32F407/ESP8266/aliyun.html frameborder=0 scrolling=auto width=100% height=1500></iframe></p>
<iframe frameborder=0 height=1500 name=ifd scrolling=auto src=https://mnifdv.cn/resource/cnblogs/ZLIOTE_STM32F407/ESP8266/aliyun.html width=100%></iframe>
说明 这一节实现微信小程序使用APUConfig配网绑定模组并通过阿里云物联网平台实现远程通信控制. 概要: APP和单片机设备分别作为设备以动态注册方式连接阿里云物联网平台,然后通过规则引擎实现APP和设备之间通信. 此节教程是前面所有知识点的整合,希望用户按部就班的学习了前面的内容,然后再学习此节. 测试准备 1.打开这节的微信小程序工程和单片机工程(单片机程序是上节的工程,如果已经下载了,不用重复下载) 2.在微信小程序平台上设置域名白名单(推荐) 域名为自己设备连接的MQTT服务器的IP地址: wss://{productKey} .iot-as-mqtt.{Region} .aliyuncs.com 我的productKey为: a1m7er1nJbQ 我的Region地区为: cn-shanghai 所以; wss://a1m7er1nJbQ.iot-as-mqtt.cn-shanghai.aliyuncs.com 注意:设置完成以后重启一下微信开发工具 3.如果不设置域名白名单也可以在软件上选择忽略校验域名 4.登录自己的云平台 注:选择哪个产品,设备就会注册到哪个产品下 5,查看并替换自己产品的ProductSecret; ProductKey; (单片机程序里面和android程序里面都需要替换) 4,查看并替换自己instanceId 提示:在2021年7月30日之前购买的实例是没有 instanceId 的, 程序里面可保持空 提示:有 instanceId 的, 填写上实例的 instanceId 配置规则引擎 1.
FIFO算法和LRU算法计算缺页中断次数、缺页中断率 FIFO算法 运行的页面走向:
1-2-3-4-2-1-5-6-2-1-2-3-7-6-3-2-1-2-3-6
如果页面框为3,如下:
123分别调入内存,则内存:123(3次缺页中断)
调入4淘汰最先进来的1,则内存:234(4次缺页中断)
调入2,内存中有2,则内存:234
调入1,淘汰最先进来的2,则内存341(5次缺页中断)
调入5,淘汰最先进来的3,则内存415(6次缺页中断)
调入6,淘汰最先进来的4,则内存156(7次缺页中断)
调入2,淘汰最先进来的1,则内存562(8次缺页中断)
....
调入6,..................... ..............................(16次缺页中断)
LRU算法 运行的页面走向:
1-2-3-4-2-1-5-6-2-1-2-3-7-6-3-2-1-2-3-6
如果页面框还是3,如下:
开始三个数反过来读取,得321(3次缺页中断)
调入4,淘汰最底1,4写最前面,则内存:432(4次缺页中断)
调入2,内存有2,把2放最前面,则内存:243(不中断)
调入1,淘汰最底3,1写最前面,则内存:124(5次中断)
......
以此类推
总之,LRU算法 :如果相同,把相同数放前面,不中断;
如果不同,淘汰最右边一个数,左边放,产生中断
搜索
复制
首先请允许我对KMP算法的三位创始人Knuth,Morris,Pratt致敬,这三位优秀的算法科学家发明的这种匹配模式可以大大避免重复遍历的情况,从而使得字符串的匹配的速度更快,效率更高。
首先引入对kmp算法的引例:
如果按照暴力算法来看,这6步一步也少不了,是很麻烦的;
但是对于要匹配的子串来讲,子串T的首字母与后面的任何一个字母都不想等,拿图1来看首字母'a’与主串S的第2位到第5位的任意一个字母都是不相通的
换言之:图2345的步骤都是多余的
如果知道T子串的首字符‘a'与T以后的字符均不相等的话,也就是说T的首字符'a’与s串的第二位不需要判断也是可以知道相不相同了;
在举个例子来看的话,那如果知道首字符T与子串的后面字符都不相等的情况下,s串与T串的判断情况也就知晓了
所以说保留1,6两步即可
但是为什么保留6呢?
原因也很简单:
你虽然知道T1!=T6,但是也不能严格保证T1!=S6,也就是说S6和T6可能不相等
还有一种情况是子串后面的字符出现重复,比如:abababa此类的字符串
模拟一下:
我们有主串S=ABCABABCA(自动看成小写,手滑了),子串T=“abcabx
图1,子串T的首字符与第二,第三字符均不相等,,所以不用判断,跳过23即可
T子串的首位和S第四位相等,第二位和S第五位相等,但很遗憾的是,这一步其实在开始1的时已经判断过了,于是呼首位和第四位,第二位和第五位也是不需要判断了,所以说4,5这两部也是可以省略的
可以看出,对于子串中国有与首字符相等的字符,完完全全是可以省略一些不必要的判断的
对比一下的话,在开始的时候,i的下标是6,经过2345步,i的值相应的变成了2,3,4,5一直到了第6步,i的值又重新变回了6,也就是说,i的值是通过下标不断回溯得到的,而这种回溯通过上面2345的推断,是可以省略的,类似于好马不吃回头草
那这样的话,i的值可以不回溯,当然也不可以减小,只能往前走,那就只能在j上开刀了;
上面我们说到了关于子串T中重复元素的问题,如果发现有相同元素,j的值就会不一样,也就是说j的值是和子串T重复元素个数的问题是相关的
一句话来说的话:j的大小是由当前T子串的前后缀的相似度决定的;
什么是前后缀,很简单:
前缀指除了最后一个字符以外,字符串的所有头部组合;后缀指除了第一个字符以外,字符串的所有尾部组合。
举个例子来讲”
abcdab;
ta的前缀集合是(a,ab,abc,abcd,abcda)
后缀集合是(b,ab,dab,cdab,bcdab)
再来判断一个吧:abcabfabcab的最长前后缀是什么,长度多少?
很好写:abcab,5
介绍完前后缀,我们来正式引入kmp
在我们正式查找字符串之前,需要对子串做一个前后缀分析,来提高查找速度:
我们可以定义一个int 类型的数组next[]来记录各个位置j的变化情况,next的长度就是T串的长度:
下面我们来展开一下对于next数组的求法:
其实对于next数组,有一套简单求法:
设一个子串T=“ababaaa”
首先next[0]=0;
当i=1的时候是b那,没有前后缀相同的元素,next[1]=0;
当i=2的时候在a,有共同元素a,next[2]=0;
.............
一直到i=6在a,next[6]=1;
得到的序列是0012311
这时候我们将得到的序列最后一位舍弃,其余的全部往右推进一位,就是用前一位覆盖后一位,第一位用-1补齐,得到的新序列是
-1,0,0,1,2,3,1,在将得到的新序列全部加1,
变成0,1,1,2,3,4,2
就是求得的next的数组,
这种方法比教科书上板式求法方便好记多了,适合考场和比赛时候对于next数组的求解,既高效又快速,正确率还高
主要的原理还是利用了前后缀的问题
我们再来拿算法本身做做文章:
在朴素方法中,每次新的匹配都需要对比 S和 T的全部 m个字符,这实际上做了重复操作。例如第一轮匹配 S 的前3个字符 “aaa”和 T的“aab”,第二轮从 S的第2个字符 ‘a’开始,与和T的第一个字符 a’比较,这其实不必要,因为在第一轮比较时已经检查过这两个字符,知道它们相同。如果能记住每次的比较,用于指导下一次比较,使得 S的 i指针不用回溯,就能提高效率。 如何让i不回溯?分析两种情况:
你了解 Java 应用开发中的注入攻击吗? 注入式(Inject)攻击是一类非常常见的攻击方式,其基本特征是程序允许攻击者将不可信的动态内容注入到程序中,并将其执行,这就可能完全改变最初预计的执行过程,产生恶意效果。
下面是几种主要的注入式攻击途径,原则上提供动态执行能力的语言特性,都需要提防发生注入攻击的可能。
首先,就是最常见的 SQL 注入攻击。一个典型的场景就是 Web 系统的用户登录功能,根据用户输入的用户名和密码,我们需要去后端数据库核实信息。假设应用逻辑是,后端程序利用界面输入动态生成类似下面的 SQL,然后让 JDBC 执行。
Select * from use_info where username = “input_usr_name” and password = “input_pwd” 但是,如果我输入的 input_pwd 是类似下面的文本,
“ or “”=” 它是利用了期望输入和可能输入之间的偏差。上面例子中,期望用户输入一个数值,但实际输入的则是 SQL 语句片段。类似场景可以利用注入的不同 SQL 语句,进行各种不同目的的攻击,甚至还可以加上“;delete xxx”之类语句,如果数据库权限控制不合理,攻击效果就可能是灾难性的。
解决:
在数据输入阶段,填补期望输入和可能输入之间的鸿沟。可以进行输入校验,限定什么类型的输入是合法的,例如,不允许输入标点符号等特殊字符,或者特定结构的输入。 在 Java 应用进行数据库访问时,如果不用完全动态的 SQL,而是利用 PreparedStatement,可以有效防范 SQL 注入。不管是 SQL 注入,还是 OS 命令注入,程序利用字符串拼接生成运行逻辑都是个可能的风险点! 在数据库层面,如果对查询、修改等权限进行了合理限制,就可以在一定程度上避免被注入删除等高破坏性的代码。 第二,操作系统命令注入。Java 语言提供了类似 Runtime.exec(…) 的 API,可以用来执行特定命令,假设我们构建了一个应用,以输入文本作为参数,执行下面的命令:
ls –la input_file_name 但是如果用户输入是 “input_file_name;rm –rf /*”,这就有可能出现问题了。当然,这只是个举例,Java 标准类库本身进行了非常多的改进,所以类似这种编程错误,未必可以真的完成攻击,但其反映的一类场景是真实存在的。
第三,XML 注入攻击。Java 核心类库提供了全面的 XML 处理、转换等各种 API,而 XML 自身是可以包含动态内容的,例如 XPATH,如果使用不当,可能导致访问恶意内容。
前言
不知不觉已经开始学习面向对象程序设计三个月了,先发一个小吐槽:老师总是在清明,劳动节,PTA或者oop上面的实验以及作业,这让我感到有点小头疼。
虽然说作业多,但是恰逢佳节,稍微降低了点作业难度,方便我们学生及时做完,这么一想
老师还是挺好的,不是吗?
学了这么久面向对象程序设计,也做了有那么几道题目,感受到:面向对象和面向过程确实有很大的区别。就拿最近的一次PTA平台上的作业来说:识蛟龙号载人深潜,立科技报国志
说真的,这个题目不是很励志吗!!!
在练习代码的编辑能力的同时,心系国家大事,认识到祖国的强大,岂不是两全其美,希望之后多出一些这种题出来!
不过话说回来,难是真的挺难的
我需要分析每行都有上面成分2,然后再逐一通过算法将需要提取出来的信息提取完成
就好像是面向过程程序设计是把难的问题逐步分解,拆成小问题,然后解决。
面向对象程序设计就像是把难的问题分析的很透彻,每一个类都思考清晰,然后在进行程序的编码。
分析问题感觉是所有学生的要害,总感觉我有哪里没想到,然后程序写得稀巴烂。
话不多说,上题!
PTA大作业四
作业四 4-1 作业分析
读入关于蛟龙号载人潜水器探测数据的多行字符串,从给定的信息找出数字字符,输出每行的数字之和
说真的,这道题就这一句话,但是,却让我想破了头,我该怎么编辑我的代码,把那些我想提取出来的元素、字符提取出来并相加,主体内容都清楚,随便打点东西上去就行,但是难就难在怎么弄才能把一串字符中的数字提取 出来,按照不同的提取方式提取出来,真的是挠破了头皮。
代码分析
看似短短三十行,但是真的想的挺久的说实话,题目中有着不同位数的数字,比如9月9日,18时xx分等等数字信息,刚开始想,我该怎么把多位数的数字提取出来,如果单纯用字符提取的话,最多也就只能做到将数字一个个提取
出来,这样获得到的答案绝对是与标答不相同的,所以,我想了一些其它的办法,如上图所示
通过扫描输入样例中字符串中的字符类型节点,从而从字符中提取出需要的信息,并通过(Integer.parseInt)将字符中的字符类型进行转换,从而计算相对值
说实话,这个新知识是之前从来没有接触过的,觉得很新颖,而且说实话很实用,比如c语言和其他一些代码编程软件中都没有
度量分析
本题复杂程度为6
啊这,没之前的一些简单题目高吗,不应该呀,个人觉得这种题目会比之前的某些题目难很多
结果演示
有一部分没有截出来,但是看到这么多其实也能说明算是做出来了吧
下一道题!
作业四 4-2 题目分析
说实话(我也不知道这句话讲了多少遍了),这道题真的是人能做出来的吗,突破了我对题目的认知,一道题有70分,多少个测试点,给孩子人看麻了说实话,稍微分析一下
题目还是跟之前一样,是算多边形的题目,但是测试点也太多了吧
光任务点就有5个,我的老天
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出not a quadrilateral3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出not a quadrilateral4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出The line is coincide with one of the lines。若后四个点不符合四边形或三角形的输入,输出not a quadrilateral or triangle。后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出on the triangle或者on the quadrilateral。若后四个点不符合四边形或三角形,输出not a quadrilateral or triangle。
代码:
function printPyramid(totalLevel) { /* 打印金字塔 1 * 2 *** 3 ***** 规律: 每层 * 个数 = 2n - 1 每层 前空格 = 总层数 - n (后空格 不用管 直接通过 打印换行实现) */ // i 代表层数 for (let i = 1; i <= totalLevel; i++) { // j 表示 * 数 // 打印前空格 for( let k =1; k <= totalLevel - i; k++) { process.stdout.write( ) } // 打印 * for ( let j = 1; j <= 2 * i - 1; j++) { process.
1.MySql的存储引擎2.MyISAM和InnoDB、MEMORY存储引擎
3.查看表结构:desc goods;
查看数据库中的用户表:show tabales:
查看用户表创建的基本语句:show create table goods;
4.修改表:alter table goods rename tb_goods;
删除表:drop
修改某列数据类型:modify --->alter table tb_goods modify type char(30);
对列的名称修改:alter table tb_goods change name g_name varchar(30);