字符串相乘(字符串,leetcode43)-------------------c++实现 题目表述 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
样例 输入: num1 = “2”, num2 = “3”
输出: “6”
条件 1 <= num1.length, num2.length <= 200
num1 和 num2 只能由数字组成。
num1 和 num2 都不包含任何前导零,除了数字0本身。
思路 利用加法做乘法(leetcode415是加法)
ac代码 c++: class Solution { public: string addstring(string a,string b){ int i=a.size()-1,j=b.size()-1; string result; int nextmember=0; while(i>=0||j>=0||nextmember!=0){ int x=(i>=0?a[i]-'0':0); int y=(j>=0?b[j]-'0':0); result.push_back((x+y+nextmember)%10+'0'); if((x+y+nextmember)>=10) nextmember=1; else nextmember=0; i--,j--; } reverse(result.begin(),result.end()); return result; } string multiply(string num1, string num2) { if(num1.
目录 一、简介接线 二、原理3、代码段3.1、sg90.c3.2、main.c 一、简介 舵机是一种位置(角度)伺服的驱动器,适用于需要角度不断变化并可以保持的控制系统,可以根据控制信号来输出指定的角度(常见的有0-90°、0-180°、0-360°)。
实质是一个伺服马达。又分为模拟舵机和数字舵机。
模拟舵机:需要不断发送目的地PWM信号,才能旋转到指定位置。(想转10°,要不断发送10°PWM信号直到指定位置才能停止)数字舵机:只需给一个目的地PWM信号,即可旋转到指定位置。(想转10°,发送一次10°PWM信号就可以转到10°)
接线 红色----VCC
棕色----GND
橙色----信号线(连接到单片机输出PWM的引脚)
二、原理 舵机的控制一般需要一个20ms的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分,对应控制180°舵机的0-180°,呈线性变化。
给它提供一定的脉宽,它的输出轴就会保持在一个相对应的角度上,无论外界转矩怎样改变,直到给它提供一个另外宽度的脉冲信号,它才会改变输出角度到新的对应的位置上。舵机内部有一个基准电路,产生周期20ms,宽度1.5ms的基准信号,有一个比较器,将外加信号与基准信号相比较,判断出方向和大小,从而产生电机的转动信号。
控制电路板接受来自信号线相应的PWM控制信号,进而控制电机转动,电机带动一系列齿轮组,减速后传动至输出舵盘。舵机的输出轴和位置反馈电位计是相连的,舵盘转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板根据所在位置决定电机的转动方向和速度,从而达到目标停止。
以180度角度伺服为例,那么对应的控制关系是这样的(t为高电平时间):
t=0.5ms(占空比2.5%)---------0°;
t=1.0ms(占空比5%)-----------45°;
t=1.5ms(占空比7.5%)---------90°;
t=2.0ms(占空比10%)---------135°;
t=2.5ms(占空比12.5%)-------180°;
即:高电平时间=0.5ms+(角度/180°)×2ms
3、代码段 根据PWM周期为20ms = (7200*200)/72000000=0.02。故TIM_Period=199,TIM_Prescaler=7199。
以转动45°为例,占空比为5%,所以TIM_SetCompare1的 TIMx 捕获比较 1 寄存器值就为200-200*5% = 190。
以下是代码展示,仅供参考:
3.1、sg90.c void TIM1_PWM_Init(void)//自动重装载值 预分频系数 { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(SG90_TIM_CLK, ENABLE);// //使能定时器1的时钟 RCC_APB2PeriphClockCmd(SG90_GPIO_CLK , ENABLE); //使能GPIO外设时钟使能 //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形 GPIO_InitStructure.GPIO_Pin = SG90_Pin; //TIM_CH1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHz GPIO_Init(SG90_Port, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = 199; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K TIM_TimeBaseStructure.
因为涉及到组件传值和表单双向绑定问题,要将后端返回的数据从value渲染为对应的text,免不了修改原数据,原数据就算赋值给别的变量,其内存地址还是一致,那样一旦在js中修改其中任意一项,提交时会造成返回和提交的数据格式不一致,从而出现修改和详情弹窗的各种bug,为了渲染正确的下拉框和树形结构绑定的数据,于是在项目中使用了深拷贝...
错误示范:
editrow(val) { this.editFormData = {}; this.editFormData = val; this.editDialogVisible.show = true; this.editFormData.data=123; //此时val中对应的数据也会改变! } deepClone
export default function deepClone(target){ // 定义一个变量 let result; // 如果当前需要深拷贝的是一个对象的话 if (typeof target === "object") { // 如果是一个数组的话 if (Array.isArray(target)) { result = []; // 将result赋值为一个数组,并且执行遍历 for (let i in target) { // 递归克隆数组中的每一项 result.push(deepClone(target[i])); } // 判断如果当前的值是null的话;直接赋值为null } else if (target === null) { result = null; // 判断如果当前的值是一个RegExp对象的话,直接赋值 } else if (target.
JWT简介 token进行用户身份验证流程:
①客户端使用用户名+密码请求登录
②服务端收到请求验证用户名和密码
③验证成功后,服务端发送一个token给客户端
④客户端将token保存起来
⑤后续请求资源需要携带这个token
⑥服务端进行token验证,验证成功则执行请求
token相比于session优点:
①节约服务器资源,对移动端友好
②支持跨域访问(跨域名访问):cookie无法跨域,而token放到请求头中可不使用cookie,故跨域后不存在信息丢失问题(即发送token不是针对某个域名单独进行,任何域名使用的token可以相同,而cookie对不同域名不同处理)
③无状态:用token后,服务端不需要存储session信息,因为token包含了所有登录用户的信息,可减轻服务端压力
④更适合CDN
⑤更适用于移动端
⑥无需考虑CSRF(cookie中跨站请求伪造,即盗取cookie信息进行冒名登陆)
JWT:JSON Web Token,token的一种具体实现方式
本身就是一个字符串,将用户信息保存到JSON字符串并编码后得到(有签名信息)
JWT结构 由三部分组成:①标头(Header)②有效载荷(Payload)③签名(Signature)
传输时会将三部分分别进行Base64编码后,用‘.’进行拼接形成字符串
Header
JWT头是一个描述JWT元数据的JSON对象,alg表示签名用的算法,typ表示令牌的属性(统一JWT)
{ "alg": "HS256", "typ": "JWT" } Payload
有效载荷是JWT主体内容部分,也是JSON对象,包含需要传递的数据,有如下七个字段:
①iss:发行人
②exp:到期时间
③sub:主题
④aud:用户
⑤nbf:在此之前不可用
⑥iat:发布时间
⑦jti:JWT ID,用于标识该JWT
上述是JWT预定义可以选用的字段,还可以额外自定义私有字段。
给字段赋值拼接为JSON后就作为JWT的Payload部分。
注:JWT默认情况下是未加密的,只用Base64算法,可以通过内容获取传递的信息,故类似密码等用户敏感信息不能通过JWT传递。
Signature
签名哈希部分是对上述两部分数据的签名,需要使用base64编码后的header和payload数据,通过指定算法生成哈希,确保数据不被篡改。
首先需要指定一个秘钥,该密码保存在服务器中,使用签名算法(默认HMAC SHA256)生成签名。
作用
header和payload可以直接用base64获得原文。
header用于获取哈希签名使用的算法,payload获取具体数据
signature作为上述的整合,作用是检验token是否被篡改,利用获得的算法和秘钥对前两部分加密,比对加密后数据和客户端发送的是否一致。
JWT java使用 首先引入依赖:
compile 'com.auth0:java-jwt:3.4.0' JWT生成token:
public void testGenerateToken(){ // 指定token过期时间为10秒 Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.SECOND, 10); String token = JWT.
各位小伙伴们,因微信公众号推送机制的变化,请一定要把公众号设置为星标,否则,你可能看不到陆大湿分享的资源了
关于更新 本次更新用户登录接口以及收藏空白等bug,下载链接已经更新,之前支付过的可以重新下载,案例未更新,演示小程序:陆大湿源码
更新内容:
1、微信小程序用户昵称突然变成了“微信用户”,而且头像显示灰色。
2、修复收藏列表点击进入后空白无内容
3、优化更新界面
微信小程序用户昵称突然变成了“微信用户”,而且头像显示灰色,这是微信官方对接口进行了调整,从4月28日起旧的接口将获取到匿名的信息,所以显示就是“微信用户”与灰色头像。
如下图:
A接口调整 今天就是为了解决这个问题才写的这篇文章,前段时间一直想去修改,但是太忙了一直拖到今天。修改的方式其实算比较简单,使用的getUserProfile接口。调整说明:uniapp官方getuserprofile接口说明。
部分代码:
B接口修改 调整点击授权登录后:
授权成功后:
后台用户数据:
C源码下载 下载地址1:https://download.csdn.net/download/wapqke/18965119 下载地址2:【修复收藏功能、更新登录接口】资源变现小程序独立版-陆大湿源码 (ludeqi.com) https://www.ludeqi.com/1508/
如果是之前安装过后端可以不用修改,如果是初次安装,看之前的安装方法。
只看后端部分安装:资源变现小程序安装说明
前端按照以下方法:
将mp-weixin解压后导入开发者工具,将https://feng.ludeqi.com修改自己的域名,一共2个位置。位置:mp-weixin/common/main.js和mp-weixin/pages/login/login.js。
更多资源,扫码关注公众号:
相关推荐:
最火表情包小程序源码以及安装说明
资源变现小程序独立版开源无授权
如何搭建成语答题小程序详细教程
恋爱话术V3 5.0新版小程序源码与安装
超详细的外卖CPS小程序搭建教程
本篇文章来源于微信公众号: 陆大湿
协程(二) ucontext setjmp和ucontext哪个更好
https://stackoverflow.com/questions/5536913/c-setjmp-h-and-ucontext-h-which-is-better
https://stackoverflow.com/questions/15014647/why-was-ucontext-added-to-and-then-removed-from-posix
代码学习 风云写的协程代码(不搬运了)
https://github.com/cloudwu/coroutine/
站在巨人肩膀 将风云的手动resume,改为loop发现风云的_save_stack()在编译参数-On下是有问题的,我改为整段stack保存我在树莓派的Makefile中运行的时候,要么coredump,要么栈错位,百思不得其解,还以为ucontext在aarch64兼容不好。其实就是上一个问题,我加了-O3,真是运气。然后发现了个问题,stack的占用不小,远远大于_save_stack()计算的差值,虽然在swapcontext前,只拷贝那一小段,但是stack之后的数据会自己填充。(至于为什么,我也不清楚,寻找答案中…)关于makecontext后面的可变参数类型,虽然说是int,但64位的平台也支持指针
https://man7.org/linux/man-pages/man3/swapcontext.3.html On architectures where int and pointer types are the same size (e.g., x86-32, where both types are 32 bits), you may be able to get away with passing pointers as arguments to makecontext() following argc. However, doing this is not guaranteed to be portable, is undefined according to the standards, and won't work on architectures where pointers are larger than ints.
问题:每次重启idea后,发现保存的git密码,mysql密码等需要重新输入
方案:修改idea默认配置
步骤:点击“Appearance & Behavior》System Settings > Passwords”选项后,在右侧设置框中的"Save passwords:"模块中,不要勾选“Do not save, forget passwords after restart”选项,选择其他项,点击“ok”按钮。
看图:
其他:这里也可勾选In KeePass (我用的mac有In native Keychain选项)。
最近改了一个之前的项目,为了简化CRUD加上了mybatis-plus,结果发现dao层接口找不到对应的xml文件了,出现了异常
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):XXX
就很奇怪,因为之前引入mybatis-plus都是正常的,然后还检查了一遍接口和xml可能存在问题的地方,都是正常,最后回归还是觉得是引入mybatis-plus导致的,调查之后发现是pom文件导包的问题引起的:
引用 mybatis-plus 包
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.1.0</version> </dependency> 引用 mybatis-plus-boot-starter 包
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3.4</version> </dependency> 引入包的不同,application.properties(yml)的mapper.xml 的文件引用路径配置也不同:
# mybatis mapper路径 适用于 mybatis 和 mybatis-plus mybatis.mapper-locations=classpath*:mappers/*.xml # mybatis-plus mapper路径 适用于 mybatis-plus-boot-starter mybatis-plus.mapper-locations=classpath*:mappers/*.xml xml文件路径为 src\main\resources\mappers,如图:
我引入的是 mybatis-plus-boot-starte 没有追加 mybatis-plus.mapper-locations 的配置,从而导致接口与xml文件没有映射上,所以根据引用的包添加不同的配置,就没有问题了。
前言 从构思到实现,试过语法分析树和抽象语法树,写起来不是特别顺利,然后换了思路,以一种直观的方式进行词法分析(可能时间复杂度较高,没计算过)。
项目地址 Github
参考链接 在实现的过程中也发掘到几篇不错的blog
构建抽象语法树
构建正则引擎
正则表达式转有限状态自动机
前文 支持语法 表达式匹配例子c单个非运算字符ca, b, z\c字符c的字面值\\“s”串s的字面值".\“.除换行符以外的所有字符*.out[s]字符串s中的任意一个字符[abc], [a-z], [0-9][^s]不在字符串s中的任意一个字符[^abc]r1r2r1后加上r2abc(r)与r相同(ab)r{m, n}最少m个,最多n个r重复出现r{1, 5}r1 | r2r1或r2a | br*和r匹配的零个或多个串连接的串a*, [abc]*r+和r匹配的一个或多个串连接的串a+, [0-9]+r?零个或一个ra?, (ab)? 注解1:c匹配的是非元标识字符, 即除(\ " . ^ …) 代表特定意义的字符。 \c 匹配的是元标识字符的字面值, 即 ‘.’ 匹配除换行符以外的字符, 加上 ‘\.’ 表示匹配一个小数点 ‘.’ 。
注解2: r*口语为kleene闭包(克林闭包),r+口语为正闭包,r?口语为???(我也不知道)。
注解3:在上个版本中支持[^s],但由于在当前版本改动了规则的继承层次,导致无法直接实现此功能(或许有方法,笑)。
注解4:构建 ‘.’ 元标识符时,会有bug(绘制出NFA就明白了)。
注解5:在当前版本中,没有构建符号表,因为算是测试版本,返回的Token的实例也很‘直接’。
注解6:在当前版本中,有正则表达式到不确定有穷自动机的转换;不确定的有穷自动机 转 确定的有穷自动机没办法实现,需要一点小改动才可。子集构造法的三个函数有,转换类也有(注解了),在正文部分会提及如何。
正文 语法分析树,抽象语法树 ,规则与定式
什么是有限状态自动机?
|
有限状态自动机是一个五元组
M = ( Q , Σ , δ , q 0 , F ) M=(Q, Σ, δ, q0, F) M=(Q,Σ,δ,q0,F)
虽然打log非常方便但是gdb功能强大,有很多print不及的功能,比如找到某个函数的调用栈。
gdb调试qemu其实很简单,就是 gdb --arg qemu-system-aarch64 + 命令行,这样就可以调试了。用b设置断点,r来run,c连续执行,bt来回溯调用栈。但是会出现一些意想不到的状况,比如出现:
Thread 6 "qemu-system-aar" received signal SIGUSR1, User defined signal 1.
经谷歌解决方法是: (gdb)handle SIGUSR1 noprint nostop。接着就比较顺畅了。
一个单元格对于某些设备来说是不够的。为了达到所需的电压,电池串联连接以增加电池的电压。为了达到预期的容量,电池并行连接,通过增加安培小时(Ah)来获得高容量。这种电池组合称为电池。
有时候,电池组在两种配置中同时使用,以获得所需的电压和高容量。这种结构在笔记本电池中可以找到,它有4个3.6 v 的锂离子电池串联起来得到14.4 v,每个电池彼此并联,得到6800毫安时的双倍容量。
笔记本电池配置。
连接在配置中的电池应该具有相同的电压和容量,因为较弱的电池导致不平衡。在串联结构中,电池和电池链中的薄弱环节一样强,因此高容量的电池不能比较弱的电池充电更多。较弱的电池也会先放电和充电,这也会导致设备出现过放电和过充电等问题。
单电池配置
单电池配置是最简单的电池组。这种配置可以在挂钟、内存备份和手表中使用。这些都是低功耗设备,所以他们使用1.5 v 的硷性电池。移动电话和平板电脑也有3.6 v 锂离子电池的单芯配置。下面的图片显示了锂离子电池的单电池配置。
正如我们所看到的,单个锂离子电池的标称电压为3.6伏。镍基电池的标称电压为1.2 v,硷性电池电池的标称电压约为1.5 v。另一种锂基电池的电压在3.0 v 到3.9 v 之间,锂磷酸盐为3.2 v,锂钛酸盐为2.4 v,锂锰和其他锂基电池通常使用3.7 v 或更高的电压。
系列配置
串联结构用于单个电池电压不足的场合。串联配置是通过连接一个细胞的正片到另一个细胞的负片来实现的,如下图所示。4个3.6 v 的锂离子电池串联在一起,可以产生14.4 v 的电压,这种结构被称为4s,因为4个电池串联在一起。
电池的数量可以根据单个电池的电压而改变。铅酸蓄电池的额定电压为2伏,因此需要串联六个电池才能达到12伏。六个电压为1.5 v 的碱性电池串联在一起,可以给你9伏电压。
如果设备需要一个奇数的电压,例如10伏,那么三个锂离子电池可以串联。但是当设备需要8.5伏的锂离子电压时,你需要知道设备的规格。如果它可以处理10v,那么它可以直接连接; 否则,一个降压或升压是用来达到8.5 v。
如果一个电池串联是错误的,电池匹配是一个挑战,在老化包在电池更换时。新的电池比其他电池有更高的容量,从而导致不平衡。这就是为什么电池组通常更换单位。
如下图所示,BMS (电池管理系统)或其控制器可以通过测量电池各点的电压来确定故障电池。其中一个电池出现故障,电池电压由3.6 v 降至2.8 v。由于这个原因,电池电压崩溃,并且设备会因为低电量信息而提前关闭。你可以通过更换这个电池来修理你的电池组。
并行配置
如果设备需要更高的电流,但是没有足够的空间容纳电池,则电池并联连接以满足更高的电流容量要求。该装置可以使用平行配置,以适应大电流能力在一个小的空间。并联的四个单元结构称为 P4,并联的三个单元结构称为 P3。下面的图片显示了 p4配置。电池组中的电压保持不变,但是电流容量(Ah)增加了。
产生高电阻或开路的电池在并联电路中的关键性不如串联电路,但是失效的电池会降低总的电流容量。另一方面,电短路更严重,因为有缺陷的电池从其他电池吸收能量,引起火灾。短波通过反向极化或枝晶生长发生。大型电池包括一个保险丝,当电池短路时可以断开它。在下面的图片中,蓝盒子中的第三个电池失效,容量降低到1500毫安时。它不影响电压,但降低了总容量。
串并联结构
在这种配置中,单元以串联和并联方式连接。串并联结构可以在尽可能小的尺寸下给出所需的电压和容量。你可以在下面的图片中看到两个3.6 v 3400mAh 电池并联连接,使电池容量从3400mah 提高到6800mah。由于这些并联组件串联在一起,电压也会从3.6 v 翻倍到7.2 v。这个电池组的总功率现在是48.96 Wh。这种配置称为2sp2。如果配置包括8个配置为4sp2的单元,两个单元并联,这个并联组合的四个单元串联在一起。这个电池组产生的总功率是97.92 Wh。
电池的保护
IEC 62133协调了便携式应用的镍基和锂基电池和电池的安全要求。锂离子电池是同类电池中最危险的一种,因为电池的化学成分具有炸药。电池需要保护,以防止任何损害,由于大电流放电,过充,温度上升等。保护可以内置在电池的结构中,或者可以使用外部保护电路断开电池。
电池内置保护装置
一些电池在电池结构中带有安全功能。下图展示了18650锂离子电池的安全特性。PTC (正热系数)是指在常温下电阻非常低。但当温度超过临界值时,电阻增大,电流减小。当温度低于临界范围时,PTC 就处于正常电阻下。
CID (电流中断装置)是一种熔丝型装置,当电池压力、温度或电压范围超过其极限时,它会永久性地切断电路。如果内部压力增加约1,000千帕,则顶部阀瓣与金属箔断开,与电流断开。在顶部有一个排气口,可以释放气体,并可以再次关闭。
蓄电池保护电路
Yarn安装 查看node环境 $ node -v 8.1x $ npm -v 6.x 安装yarn # 国内源 $ npm i yarn tyarn -g # 后面文档里的 yarn 换成 tyarn $ tyarn -v # 阿里内网源 $ tnpm i yarn @ali/yarn -g # 后面文档里的 yarn 换成 ayarn $ ayarn -v 验证 $ yarn global add vue-cli # 全局安装vue-cli $ vue -V @vue/cli 4.5.15 Thinking in JackDan
协程 概念 什么是协程
https://stackoverflow.com/questions/553704/what-is-a-coroutine
协程与线程的区别
https://stackoverflow.com/questions/1934715/difference-between-a-coroutine-and-a-thread
并行与并发的区别
https://stackoverflow.com/questions/1050222/what-is-the-difference-between-concurrency-and-parallelism
Python3.5 协程原理
https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/
https://github.com/xitu/gold-miner/blob/master/TODO/how-the-heck-does-async-await-work-in-python-3-5.md
协程和并发的一门有趣课程
http://www.dabeaz.com/coroutines/
代码学习 使用生成器来实现一个并发网络应用程序(链接里最底下那篇很长的代码,不搬运了)
https://python3-cookbook.readthedocs.io/zh_CN/latest/c12/p12_using_generators_as_alternative_to_threads.html
看不懂就背,默写,我就是这么过来的
站在巨人肩膀 调度器的实现,可参考epoll+reactor模型yield和send()的配合真的抽象,需熟悉二者的参数和返回值是怎么回事!让协程跑起来必须先send(None),或者next()实现了NewTask类,方便添加新的task实现了TimeWait类,用的是最小堆,为了防止task的添加顺序混乱,元组成员是(超时绝对时间,自增id,task)发现个bug,新增将_ioloop()作为task加入到_ready中 from collections import deque import heapq import socket import select import time class YieldEvent: def handle_yield(self,sched,task): pass def handle_resume(self,sched,task): pass class Scheduler: def __init__(self) -> None: self._numtasks = 0 self._ready = deque() self._waiting = {} self._timer_id = 0 self._timer = [] self._epoll = select.epoll() pass def _ioloop(self): while True: timeout = None now = time.
data中的数据如下 data: { num:10, count: 100, zhangsan:{ name:'张三', age: 12, } } 添加监听 监听data中的num属性
回调函数有两个参数,第一个是变量改变之后的值,第二个是变量改变之前的值。
watch: { num:function(newVal, oldVal){ console.log('num的值发生了变化:'+this.num); }, } handler方法和immediate属性 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 所监听的值发生改变时才执行监听计算。 那我们想要一开始就让他最初绑定的时候就执行该怎么办呢? watch 代码如下:
watch: { count: { handler(newVal, oldVal) { console.log('count的值发生了变化:'+this.count); }, // 代表在wacth里声明了count这个方法之后立即先去执行handler方法 immediate: true } } 当我们给 count 绑定了一个handler方法,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler。 而immediate:true代表如果在 wacth 里声明了 newVal 之后,就会立即先去执行里面的handler方法,如果为 false就不会在绑定的时候就执行。
deep属性 watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听,比如我们 data 里有一个zhangsan属性: 默认情况下 handler 只监听zhangsan这个属性它的引用的变化,我们只有给zhangsan赋值的时候它才会监听到。 如果我们需要监听zhangsan里的属性age的值呢?这时候deep属性就派上用场了!
watch: { zhangsan: { handler(newVal, oldVal) { console.
一、函数 #include <stdio.h> int main() { int num1 = 0; int num2 = 0; int sum = 0; printf("输入两个操作数:>"); scanf("%d %d", &num1, &num2); sum = num1 + num2; printf("sum = %d\n", sum); return 0; } 上述代码,写成函数如下: #include <stdio.h> int Add(int x, int y) { int z = x+y; return z; } int main() { int num1 = 0; int num2 = 0; int sum = 0; printf("输入两个操作数:>"); scanf("%d %d", &num1, &num2); sum = Add(num1, num2); printf("
描述 给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。
注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。
数据范围:字符串长度:1≤s≤150
进阶:时间复杂度:O(n^3) ,空间复杂度:O(n)
输入描述: 输入两个只包含小写字母的字符串
输出描述: 输出一个整数,代表最大公共子串的长度
示例1 输入:
asdfas werasdfaswer 输出:
6 解题思路: 直接暴力求解了,没用动态规划。
先将两个字符串的短串和长串区分开来,然后从短串的长度开始找子串(此时为原短字符串),遍历长串在这个长度下的子串,查看是否有匹配的子串,如果有,就可以终止查找,否则将短串的子串长度减1,找出这个长度下的短串子串和长串子串,若有就终止,没有的话搜索子串长度再减1,继续查找。代码如下:
#include <stdio.h> #include <string.h> #define N 150 int main() { char str1[N],str2[N],son1[N],son2[N]; scanf("%s%s",str1,str2); int len1=strlen(str1),len2=strlen(str2); int i,j,k,m,n,flag=0; if(len1>len2) //将str1和str2互换,保证str1为短字符串 { strcpy(son1,str1); strcpy(str1,str2); strcpy(str2,son1); i=len1;len1=len2;len2=i; } i=0; while(len1-i) { for(j=0;j<=i;j++) //短串的子串首字符的下标 { m=0; for(k=j;k<j+len1-i;k++) son1[m++]=str1[k]; son1[m]='\0'; for(k=0;k<=i+len2-len1;k++) //长串的子串首字符的下标 { m=0; for(n=k;n<k+len1-i;n++) son2[m++]=str2[n]; son2[m]='\0'; if(!strcmp(son1,son2)) { flag=1; break; } } if(flag) break; } if(flag) break; i++; } printf("
04741自考计算机网络原理知识点总结、考点串讲、考前复习 引言第一章 计算机网络概述1.计算机网络基本概念与网络结构1.1 计算机网络的概念; 1.2 计算机网络结构1.3 数据交换技术1.4 计算机网络性能1.5 计算机网络体系结构1.6 计算机网络与因特网发展简史 第二章 网络应用2.1 网络应用体系结构2.2 网络应用通信基本原理2.3 域名系统(DNS)2.4 万维网应用2.5 Internet 电子邮件2.6 FTP2.7 P2P应用2.8 Socket编程技术 第三章 传输层3.1 传输层基本服务3.2 传输层的复用与分解3.3 停-等协议与滑动窗口协议3.4 用户数据报协议(UDP)3.5 传输控制协议(TCP) 第四章 网络层4.1 网络层服务4.2 数据报网络与虚电路网络4.3 网络互连与网络互连设备4.4 网络层拥塞控制4.5 Internet网络层4.6 路由算法与路由协议 第五章 数据链路层与局域网5.1 数据链路层服务5.2 差错控制5.3 多路访问控制协议5.4 局域网5.5 点对点链路协议 第六章 物理层6.1 数据通信基础6.2 物理介质6.3 信道与信道容量6.4 基带传输6.5 频带传输6.6物理层接口规程 第七章 无线与移动网络7.1 无线网络7.2 移动网络7.3 无线局域网IEEE 802.117.4 蜂窝网络7.5 移动IP网络7.6 其他典型无线网络简介 第八章 网络安全基础8.1 网络安全概述8.2 数据加密8.3 消息完整性与数字签名8.4 身份认证8.5 密钥分发中心与证书认证机构8.6 防火墙与入侵检测系统8.7 网络安全协议 引言 本文主要针对【04741】计算机网络原理这门课程的自考考试,注重知识点总结、考点串讲、考前复习。
简介 Docker Swarm 是一套管理 Docker 集群的工具,它将一群 Docker 宿主机变成一个单一的、虚拟的主机。Swarm 使用标准的 Docker API 作为其前端访问入口,换言之,各种形式的 Docker 工具 (如 Compose Krane Deis docker-py Docker 本身等)都可以很容易地与 Swarm 进行集成。
使用 Swarm 管理 Docker 集群时,会有一个 swarm manager 及若干的 swarm node, swarm manager 上运行 swarm daemon ,用户只需要与 swarm manager 通信即可,然后 swarm manager 根据 discovery service 的信息选择一个 swarm node 来运行container。
在这里插入图片描述注意:swarm daemon 只是 个任务调度器它本身不运行容器,它只接收 Docker client 发送过来的请求,调度合适的 swarm node运行 container ,这意昧着,即使 swarm daemon 由于某些原因挂掉了,已经运行起来的容器也不会有任何影响
Raft一致性算法 保证节点存活的一个协议,后面会讲到!
Docker Swarm 特点 Swarm 对外以 Docker API 接口呈现,这样带来的好处是,如果现有系统使用Docker Engine ,则可以平滑地将 Docker Engine 切到 Swarm 上,无须改动现有系统Swarm 对用户来说,之前使用 Docker 的经验可以继承过来,非常容易上手,学习成本和二次开发成本都比较低 ,同时, Swarm 本身专注于 Docker 集群管理,非常轻量,占用资源也非常少 ,Batteries included but swappable ,简单来说,就是插件化机制,Swarm中的各个模块都抽象出了 API ,可以根据自己的特点进行定制实现Swarm 身对 Docker 命令参数支持得比较完善, Swarm 目前与 Docker 是同步发
引言 你是否有过类似的烦恼?想从一个列表中取出若干个不重复的元素,但是不知道要如何去重?
这里提供一种叫random shuffle的方法。
random shuffle 原理 shuffle有洗牌的意思,该方法也类似洗牌,从一个列表的前缀中随机取一个位置,和前缀的末尾做交换,这样对于每一位,都类似洗牌把它随机插进前面某个位置,就能实现把整个列表打乱成随机的分布,最后我们只需要取打乱后列表的前 i i i位,即是不重复的了。
实现 template <typename T> vector<T> my_random_shuffle(vector<T> input) { static mt19937 rnd(time(NULL)); for(uint64_t i=1; i<input.size(); i++) { swap(input[i], input[rnd()%i]); } return input; } 测试 对 1 − 100 1-100 1−100进行random shuffle,统计每个位置出现的值的期望,一共随机1e5次,观察每个位置的期望值。
测试方式 int main(int argc, char *argv[]) { int n=100; int t=1e5; vector<double> input(n); vector<double> ans(n,0); for(int i=0;i<n;i++) { input[i]=i+1; } for(int i=0;i<t;i++) { int j=0; for(auto x:my_random_shuffle(input)) { ans[j]+=x; j++; } } for(auto &x:ans) { x/=t; } for(int i=0;i<n;i++) { cout<<ans[i]<<"
函数式编程 所谓的函数式编程指定的式 方法的参数列表可以接收函数对象例如:add(10,20)就不是函数式编程,add(函数对象) 这种格式就叫做函数式编程我们将来编写Spark/Flink大量业务代码时,都会使用到函数式编程。下面的这些操作式学习的重点 函数名功能foreach遍历集合map对集合进行转换flatmap进行扁平化操作filtter过滤出指定的集合sorted对集合元素按照默认排序sortBy按照指定字段排序sortWith自定义排序groupBy按照指定条件分组reduce聚合操作fold折叠计算 foreach 案例代码
def main(args: Array[String]): Unit = { // 定义一个列表 val list1 = List(1,2,3,4) // 遍历每个元素,并且对每个元素进行操作,x为遍历的每个元素 list1.foreach( (x:Int) => println(x)) list1.foreach(x => println(x)) list1.foreach(println(_)) } 映射(map) 案例代码
def main(args: Array[String]): Unit = { val list1 = List(1,2,3,4) val test = list1.map((x:Int) => { //x=>(1,2,3,4) 遍历x "*" * x }) //(1,2,3,4) =>(*,**,***,****) // 类型推断 val test1 = list1.map(a => "*" * a) // 下划线 val test2 = list1.