①生命周期:
生命周期描述
Activity:
OnCreate()->OnStart()->OnResume->OnPause()->OnStop()->OnDestory()
Fragment:
OnAttach()->OnCreate()->OnCreateView()->OnActivityCreate()->OnStart()->OnResume()->OnPause()->OnStop()->OnDestoryView()->OnDestory()->OnDetach()
②Fragment依赖于Activity存在,A是F的容器
③一个A里可有多个F
④一个F(模块)可以被多个A复用
⑤通信:
F与F:可以通过获得Activity得到对应FragmentManager来得到F实例进行通信
F与A:F可以直接获取A
A与A:Intent,Handler,EventBus(实现复杂),RxBus(需要额外依赖),广播,LiveDataBus(基于LiveData监控实现,有生命周期感知)
基层OnCreate是用Bundle读取数据:Bundle底层是ArrayMap,ArrayMap适合小数量操作,HashMap用Serializable序列化,Bundle用Parcelable序列化,P比S性能高
注:Intent携带数据(执行传递),需要数据是基本类型或者可序列化,Bundle用作数据包
注:Fragment特点:
①模块化:将代码写在各自Fragment中,方便将不同UI分离
②可重用:多个A可复用一个F
③可适配:依据硬件不同屏幕尺寸、方向实现不同布局,如:可以再一个页面使用两个F分别显示列表、详情,而用A就需要呈现两个页面
题目链接:
https://codeforces.com/gym/103446
视频讲解:
https://www.bilibili.com/video/bv1994y1f76o
代码:https://hytidel.lanzoub.com/b030vuwli
密码:fkgp
2021ICPC上海区域赛题解DEGIK E. Strange Integers 题意 给定 n ( 1 ≤ n ≤ 1 e 5 ) n\ \ (1\leq n\leq 1\mathrm{e}5) n (1≤n≤1e5)个数 a 1 , ⋯ , a n ( 1 ≤ a i ≤ 1 e 9 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 1\mathrm{e}9) a1,⋯,an (1≤ai≤1e9)和一个参数 k ( 0 ≤ k ≤ 1 e 9 ) k\ \ (0\leq k\leq 1\mathrm{e}9) k (0≤k≤1e9),问从中至多可以选出几个数使得选出来的数两两之差的绝对值不小于 k k k.
对于ip地址我们前面通过多次文章,大家都有一定的理解,有部分朋友还是对子网掩码、ip地址的网段有些疑问,那么今天我们一起来解下这方面的内容。
一、什么是子网掩码?
在了解ip地址的网段之前,我们先来了解子网掩码,很多对网络了解不深的朋友都对子网掩码有些迷惑, 不了解它是用来干什么的?
子网掩码不能单独存在,它必须结合IP地址一起使用。子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分。
说的通俗的话,就是用来分割子网和区分那些ip是同一个网段的,那些不是同一网段的。
例如,两个人都叫张三,但一个张三是张家村的,另一个张三是张村的,那么如何区分这两个张三分别是属于那个村的呢?得让村长来区分,就可以准确的把各自的张三领回村,那么子网掩码就相当于村长,它就是用来区分ip该ip地址是属于那个网段的。
在实际项目中,我们通常会遇到这样的ip地址。
ip地址:192.168.1.1 子网掩码:255.255.255.0
ip地址:192.168.1.2 子网掩码:255.255.255.0
我们可以直接的判断,他们是同属于一个网段的ip地址。
那么对于下面这样的呢?
ip地址:192.168.1.1 子网掩码:255.255.255.0
ip地址:192.168.1.2 子网掩码:255.255.0.0
这两个ip地址虽然在不看掩码的情况下,比较像,但他们并不是同一个网段内的。
这个可以从子网掩码来判断,
192.168.1.1 255.255.255.0是属于192.168.1.0网段的。
而192.168.1.2 255.255.0.0是属于192.168.0.0网段。
二、如何根据掩码来确定ip地址网段
上面我们已经举例了解了子网掩码的作用,接下来我们再来了解如何确定子网掩码和判断ip地址的网段。
通常我们在划分vlan的时候会使用以下例子:
例1:
创建vlan1:ip地址:192.168.1.1 子网掩码:255.255.255.0
创建vlan2: ip地址:192.168.2.1 子网掩码:255.255.255.0
那么他们是不是在同一个网段呢?平时配置ip地址较多的朋友,可以直观的判断,他们并不是属于同一个网段,那么如何计算呢?要想判断两个ip地址是不是在同一个网段,只需将ip地址与子网掩码做与运算,如果得出的结果一样,则这两个ip地址是同一个子网当中。
详细计算
将ip地址192.168.1.1转换为二进制
11000000 10101000 00000001 00000001
将子网掩码255.255.255.0转换成二进制
11111111.11111111.11111111.00000000
然后将两者相“与(and)"运算:
11000000 10101000 00000001 00000001
11111111.11111111.11111111.00000000
然后得到:
11000000 10101000 00000001 00000000
转换成网络号就是:192.168.1.0
将ip地址192.168.2.1转换为二进制
11000000 10101000 00000010 00000001
将子网掩码255.255.255.0转换成二进制
11111111.11111111.11111111.00000000
然后将两者相“与(and)"运算:
11000000 10101000 00000010 00000001
11111111.11111111.11111111.00000000
然后得到:
11000000 10101000 00000010 00000000
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失败是成功之母,笑一笑一切都会过去。
26你想出了比书上更好的方法。
27你思考问题的角度别具一格,让我欣赏!
28看,你不是回答得很好吗?多给自己一些信心,你会更棒的!
29你真行,大家都要向你看齐!
30你思考的方向对了,假如再深入一些就更好了!
31别灰心,别放弃,机会正向我们招手呢!
32真能干,能将你的想法用操作演示出来吗?
33别紧张,你会成功的!
34你的想法比老师的好!
35只要你再仔细一些,一定会改掉这个坏习惯。
36你的回答让人有耳目一新的感觉,其他同学能从另外方面回答吗?
37错了,并不可怕。从他的错误之处,大家又有了新的想法,这不就是错误的价值吗?
38你的脑筋动得真快,声音又那么响亮,谢谢你为大家开了一个好头。
39其实你的想法很不错,能大胆地介绍给大家吗?
40一道题你能用那么多的方法来解决,老师好佩服你!
41你的办法很好,你能把这件事认真完成吗?
42你这样看着我,定有心里话要对老师说,对吗?
43你的回答真有创意。
44想好了再说,你肯定行的!
45你真能干,都快成我的老师了!
46没关系,假如有困难,我们下课后继续讨论。
47你不仅自己行,还帮助别人行!
48你已学会了和别人合作,真了不起!
49静下心,慢慢想,一定会有令人满意的答案!
50你真的同意别人的观点,是否有自己的见解?
51相互学习交流,才会有长进。
52这么难读的句子,你却读得这么棒,你一定花了不少功夫!
53只有爱动脑筋的孩子,才会有这么出色的回答。
54你不但会动脑筋,动手能力也很强!
55啊!你的课外知识真丰富!都可以成为我的老师了。
56你已经说出一部分了,继续往下说好了!
57“天生我材必有用。”请相信,你能行!
了不起,你们想的办法与书上一模一样!
你的想象真丰富。
58你有一双小音乐家的耳朵。
59你的歌声真甜,像一只声音清脆的小百灵。
60说得如此生动,你真不简单!
61请将你自己的发现,大声告诉大家好吗?
62你的朗读太出色了,就像个小播音员。
63你倾听得真仔细,耳朵真灵,这么细微的地方你都注意到了!
64你的表达特别清楚,让大家一听就懂!
65你的思维很独特,你能具体说说自己的想法吗?
66你真聪明,用以前学过的知识解决了今天的难题!
67不要气馁,老师会一直支持你的!
最近使用到这个辅助函数时,忘了好多,温习一下mapState
普通手写计算属性:
computed:{ count(){ // 计算属性渲染的时候 {{count}}对的 count()错误写法 return this.$store.state.count } school(){ return this.$store.state.school }, subject(){ return this.$store.state.subject } }, Vuex中有封装好了的函数,帮我们生成计算属性,
组件中引入Vuex之后,在组件中从Vuex引入这个'test'函数,---->{mapState}
import {mapState} from "vuex" mapState,优化计算属性,下面写下mapState的几种写法,首先得理解,你让mapState这个函数帮我们生成计算属性,那么它怎么生成,以及它生成的计算属性是哪个,这样我们就得告诉他一些信息,(要生成的计算属性的名,还有计算属性的值 即去仓库中找某个state的值)
mapState()函数里面写一组组的key-vlaue形式,key就是我们的计算属性名,value就是值
ps: {school:school} 不能这样写因为没有school没有这个变量,而且school:'school',前面的school可以加'' ,因为对象中的key-value形式,js运行时本身会加上'',只是平常我们省略了,
这样 mapState生成的是一个对象,而 computed也是一个对象,所以要用es6展开运算符
computed :{ ... mpaState({school:'school',subject:'subject'}), } js展开运算符理解
这样mapState对象写法就Ok了 ,还有一种简写方法,数组写法,
computed:{ ...mapState({school,subject}), } school并不是 school:school 简写,因为没有shool这个变量,这样写是因为这里school可以即指向计算属性名,和值
9.5 Python csv 文件的写入操作 9.5.1 with open( ) as … with open() as ... 是对原有 open() 和 close() 的优化。
使用with open() as ...语句时,代码块运行完毕后,程序会自动关闭文件,不用再写 close()语句来关闭文件。
用法是把open()函数放在 with 后面,把变量名放在as后面,结束时要加冒号 :,然后把要执行的代码缩进到with open() as ...下方的代码块中。
具体语法你可以参考下图:
在open close 方法中,我们将 open() 返回的文件对象以 变量f = open ( ) 的形式赋值给了变量f。
在 with open( ) as... 中,我们没有使用 变量 = 的形式,而是直接将变量f放在了 as 后面。
with open(file_path, 'w', encoding='utf-8') as f: 用open函数以写入的方式打开文件,将返回的文件对对象赋值给变量f。
9.5.2 什么是csv 文件 csv 全称是 “Comma-Separated Values” 。
考试重点 1. 密码体制分类 对称密码体制和非对称密码体制;
2. DES和AES算法的特点 (结构、密钥长度,分组长度,DES弱密钥)及其过程(置换过程,S盒查表过程),AES的轮结构
DES DES结构 首先是一个初始置换IP,用于重排明文分组的64比特;
相同功能的16轮变换,每轮都有置换和代换;
第16轮的输出分为左右两半并被交换次序;
最后经过一个逆初始置换产生64比特密文;
DES结构图如下:
密钥长度:56
分组长度:64
DES弱密钥:待续
了解即可
DES 分组长度64比特,使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。
使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。
AES(也称Rijndael) 分组长度和密钥长度都可变;各自可独立地指定为128比特、192比特、256比特。
DES使用了Feistel结构,AES没有使用Feistel结构;
轮函数由4个不同的计算部件组成:
字节代换,非线性结构,因为有S盒;⭐行移位,扩散;列混合,列混淆在GF运算,引入不可约多项式;轮密钥加 DES 16轮,AES 10轮;
AES S盒和DES S盒区别 S盒使明文的统计信息消失在密文中;
DES的S盒压缩数据,不可逆;
AES的S盒是代换,可逆的;
AES的S盒,第一个字节对应行,第二个字节对应列;
⭐DES S盒(必背) DES加密过程中S盒运算是不可逆的操作,那么DES的加密算法的逆过程——解密算法,该如何实现呢?
答:DES算法是基于Feistel密码结构的,其加密和解密过程是相同的,只是轮密钥的使用顺序相反而已,所以无需加密过程可逆。
3. 密码分析的类型及方法 该答案来源于网络,不确定是否正确
四种类型:
唯密文攻击(Ciphertext—only attack);已知明文攻击( Known – plaintext attack);选择明文攻击( Chosen – plaintext attack);选择密文攻击( Chosen – ciphertext attack); 三种方法:
大家都说,算法就是大厂刷人的需求,小公司招到一个脑回路正常,思路清晰的人都很难得了。确实是这样的,大厂面试就没有不问算法题的,java面试算法要刷吗?当然,你不刷,自然就过不了。如果准备冲击大厂的,还是多做准备吧。
java面试算法要刷吗?
最近这段时间输出较少,主要都去忙着面试了。忙活了大概一个月的时间,也面了不少公司,基本尘埃落定。当然啦,在有些公司的面试过程中也是碰了一鼻子灰,也得出一个结论:算法还是要从平时抓起。
面试了这么些个公司,根据对算法的考察调性我将它们分为了三种类别。
第一类公司是先聊项目,技术点。面试结束的时候出 1 - 2 道算法题。
第二类公司是个奇葩,上来二话不说开始做算法题,算法题做不完不聊别的,这意味着算法题挂了就拜拜。
第三类公司呢,基本不做算法题,干聊项目,系统设计,注重实战经验。
你可能会说,既然这样我如果不会算法,那我就试试第三类公司就好了。然而我要告诉你的是,我前后总共试了十多家公司,只有一家公司整个面试流程中没有做算法题,它家虽然没有聊算法,但是对平时使用到的技术点和系统设计能力进行了地毯式的考察。所以综合来看,为了在面试中拿到不错的成绩,还是要掌握算法这个基本功。
掌握算法只为了攻克面试吗?
当然不是。上述提到的第三类公司里面,关于技术深度会问非常多的原理性方面的问题,例如上面说到的 MySQL 为什么采用 B+ 树?Reids 中的 Sorted Set 为什么要采用跳跃表作为存储结构。你可能会想,我不知道它们的底层实现原理,我一样可以写代码写到飞起,功能很快的做出来。
但是假如你们系统的业务量迅速增长,那么你系统里面的每一行代码都有可能成为系统的性能瓶颈,而你又对代码中使用的数据结构和算法不理解,此时你可能会束手无策,慌乱的 Google 查原因,但是如果你能事先掌握这些知识,出现性能问题时候你就可以游刃有余的干掉他,避免成为一个 Google Oriented Programmer。
举个例子,假设现在需要你实现这样一个功能,统计接口响应时间的 95 线和 99 线(调用链监控系统 CAT 中的一个小功能),如果有 100 个请求即为请求时间从小到大排序,第 95 个 和 99 个请求的响应时间。如果你的基本功不扎实,很可能你会采用一个 ArrayList 来存储这个 100 个请求的时间,然后每次去将它们排序然后获取到第 95 和 99 的响应时间,但是假如你知道 Java 还为我们提供了 TreeSet 或者 PriorityQueue,你会发现这是一个更明智的选择,计算的时候不用每次去重复的去排序所有请求的响应时间大小。就这样积小成多,你会慢慢的从一个 CRUD Boy 转变为一个会思考、有技术深度的 Tech Boy。
说到这里憨厚老实的 Tech Boy 应该已经蠢蠢欲动安耐不住学习的欲望了,但是部分闷骚 Boy 可能会想,害,算了吧,我就是混口饭吃的,还是做个安安静静的 CRUD Boy 吧。
双边带抑制载波传输(DSB-SC) 双边带抑制载波传输(DSB-SC)是通过幅度调制(AM)使得频率关于载波频率对称分布,且将载波电平降低到最低程度(理想情况下完全抑制)的传输方式。
在DSB-SC调制中,与AM不同的是,不会传输载波;因此,大部分功率分布在边带,这意味着相同的功率下,DSB-SC比AM能够传输的基带信号能量更高。
DSB-SC传输是双边带减幅载波传输的一种特殊情况。它用于无线电数据系统。
频谱 DSB-SC从根本上说是无载波的调幅,因此减少了功率的浪费,让它的效率达到了50%。这相对于最大效率为33.333%的普通AM传输(DSB)在效率上有所提升,因为功率的2/3用在传输载波和含有相同信息的双边带的另一个边带了。单边带(SSB)抑制载波的效率为100%。
DSB-SC信号频谱图:
产生(调制) DSB-SC由混频器产生的。这是由载波信号乘以消息信号构成的。该过程的数学表示如下所示,其中用到了积化和差公式。
解调 解调是通过将DSB-SC信号与载波信号相乘得到的。得到的信号然后通过一个低通滤波器以取出低频分量产生原始消息信号。如果调制指数小于1,DSB-SC可以像AM一样,用简单的包络检波器解调。全深度调制需要载频重置。
上面的公式表明,通过调制信号乘以载波信号,得到的是原始消息信号加上另一项的版本。由于 ω c \omega_c ωc >> ω m \omega_m ωm 第二项的频率要比原始消息信号高得多。一旦此信号通过低通滤波器,高频率分量被去除,只留下原始消息。
失真与衰减 对于解调,解调振荡器的频率和相位必须与调制振荡器完全相同,否则将发生失真或衰减。
要得到此效果,需要以下条件:
要发送的消息信号: f ( t ) f(t) f(t)
调制(载波)信号: V c c o s ( ω c t ) V_{c}cos(\omega_{c}t) Vccos(ωct)
与调制信号的频率和相位偏差很小的解调信号, V c ′ c o s [ ( ω c + Δ ω ) t + θ ] V_{c}^{'}cos[(\omega_{c} + \Delta\omega)t + \theta] Vc′cos[(ωc+Δω)t+θ]因此得到的信号为:
一、实验目的 1、掌握连续时间信号离散化的方法(即采样),并能利用Matlab编程加以仿真实现;
2、掌握连续时间信号的傅立叶变换和离散时变换的仿真实现方法;
3、学会利用傅里叶变换和离散时间信号的傅立叶变换的方法对连续时间信进行频谱的分析;
4、掌握连续时间信号经理想采样后信号的频谱变化;
5、验证带限信号的时域采样定理,并加深对定理及与其相关的概念、名词的理解
二、实验原理 1、连续时间信号的采样
连续时间信号xa(t)以时间间隔T (即采样周期)采样后所得到的离散时间信号可表示为xa(nT),即xa(t)只保留t=nT时的值,这里n只能取整数。从数学观点而言,时间间隔T对离散时间信号的各采样点只起间隔大小的作用,对顺序无作用,因而xa(nT)还可表示为x(n)。则采样后所得到的离散时间信号x(n)与其对应的连续时间信号xo (t)的关系可表示为:
x(n)=xa(t)|t=nT
对连续时间信号进行采样得到离散时间信号的过程,在Matlab中以对e 100进行均匀采样为例,可用如下代码来进行实现:
Ts=0.0005;%设置采样周期 n=-25:1:25; %设置采样的起始时刻点 x=ex1(1000*abs(n*Ts));%按公式给定的连续时间信号得到离散时间信号xn 2、采样后信号频谱的变化
从频域的角度来看,采样前后的信号频谱也是不一样的,采样后的信号频谱Xs(jΩ)是采样之前的信号频谱Xa(jΩ)的周期延拓,延拓周期为2π/T。同时,Xs(jΩ)的幅度是Xa(jΩ)的幅度的fs=1/T倍。即:
假定Xa(jΩ)是带限信号,画出了上述的关系:
3、时域采样定理
从频域的角度分析,并结合图2.1,要保证信号采样不丢失信息,则需避免频谱的混叠失真。那么,在被采样信号是带限信号的前提下,对采样周期了(或采样频率f) 就要有一定的要求,这要求即 为时域采样定理。时域采样定理也称为奈奎斯特采样定理,可描述为:对一个有限带宽信号进行采样,如果采样顿率大于或等于信号最高频幸两倍时,得到的采样信号频请是原信号频增无混叠失真的周期延拓,因此可以由采样后的信号恢复原信号。
4、傅立叶变换的计算机计算方法
信号的频域分析是信号分析的基本手段之一。对信号进行频谱分析,从数学上讲就是进行傅立叶变换,对于连续时间信号而言,傅立叶变换公式是积分形式,具体如下:
而对于离散时间信号(序列)而言,傅立叶变换公式为求和的形式,具体如下:
不管是连续时间信号还是离散时间信号,频谱一般都是关于频率的连续函数,即均为连续谱。在Matlab中,积分一般采用离散化的求和方式进行近似计算,而求和则可借助矩阵乘法进行。因而中的积分和公式(2-4) 中的求和都可以借助矩阵乘法运算进行实现,具体计算及画图程序示例如下:
(1)连续时间信号的傅立叶变换
Dt=-0.0005;t=-0.005:Dt:0.005; Xa=exp(-1000*abs(t));%生成连续时间信号 Wmax=2*pi*2000;500;k=0:1:K;W=k*Wmax/K; Xa=xa*exp(-j*t’*W)*Dt%/续时间信号的傅位叶变换 Xa=abs(Xa); W=_flipIr(W),W(2:501)]; Xa=[fliplr(Xa),Xa(2:501)]; plot(W/(2*pi* 1000),Xa* 1000); xlabel(频率(KHZ) ); ylabel(Xa(jW)); (2)离散时间信号的傅里叶变换
Ts=0.0005;n=-25:1:25; x-exp(-1000* abs(n* Ts)); %对连续时间信号进行理想采样 K=500;k=0:1 :K;w=pi*k/K; X=x*exp(j*n'*w); %离散时间傅立叶变换 X= abs(X); w=[-fliplIr(w),w(2:K+1)]; X=[flipIr(X),X(2:K+1)]; plot(w/pi,X); xlabel(频率(rad));ylabel(X1(w)); 三、实验步骤、数据记录及处理 本实验以信号的采样为基础,借助傅立叶变换进行采样前后信号的频谱分析,在此基础上验证时域采样定理。具体的实验内容和实验步骤如下:
1、生成连续时间信号x(t)=-1000,绘制其在5ms到+5ms之间的波形,时间轴间隔为0.05ms。
2、编程实现x。(t)的傅立叶变换(即连续时间傅立叶变换),并绘制其在-2KHz到+2KHz之间的幅度谱图,频率轴频率间隔设置为8Hz。
3、用采样频率f, = 5000Hz对x(t)=e-100进行理想采样,得到采样后离散时间信号x(n),绘制出采样后的信号序列。
4、编程实现采样后离散时间信号x(n)的傅立叶变换(离散时间傅立叶变换),并绘制其幅度谱图。
5、对采样前后的信号时域图形和频谱图进行分析,总结采样前后信号频谱之间的关系。
以下是本人整理的C++基础知识点,内容并不包含全面的C++知识,只是对C++重点内容、特点进行整理和归纳。
5.1 C++多态和虚函数介绍 虚函数的作用 让基类指针能够访问派生类的成员函数 构成多态 虚函数声明 在基类成员函数的声明前面增加 virtual 关键字 定义时不用 虚函数产生多态的原因 有了虚函数,当基类指针指向基类对象时就使用基类成员(函数和变量),指向派生类对象时就使用派生类成员 虚函数的存在,基类指针有了多种形态或表现方式,所以称为多态 指针多态和引用多态 指针多态:指向灵活,多态一般是说指针 引用多态:指向单一,多态体现不足 多态的用途 一个指针变量 p 就可以调用所有派生类的虚函数,减少指针数量 5.2 C++虚函数注意事项以及构成多态的条件 虚函数的注意事项 只在声明处加 virtual ,定义处不用 只需将基类中的函数声明为虚函数 这样所有派生类中具有遮蔽关系的同名函数都将自动成为虚函数 只有派生类的同名函数覆盖基类的虚函数,并且函数原型相同才能构成多态 将构造函数声明为虚函数没有意义 析构函数可以声明为虚函数,而且有时候必须要声明为虚函数 构成多态的条件 存在继承关系 继承关系中有同名虚函数,并且是覆盖关系(函数原型相同) 通过基类指针调用虚函数 5.3 C++虚析构函数的必要性 构造函数不能是虚函数的原因 派生类不能继承基类的构造函数,没有意义 在执行构造函数之前对象尚未创建完成,虚函数表不存在,也没有指向虚函数表的指针,所以没法调用 某些情况下,析构函数必须要声明为虚函数的原因 基类指针p指向动态生成的派生类对象, 如果基类析构函数不是虚函数,【delete p】操作时,只会调用基类虚构函数,不调用派生类析构函数 造成内存泄漏 如果基类析构函数是虚函数,【delete p】操作时,会调用派生类的析构函数,同时派生类的析构函数会隐式调用基类的析构函数 不会造成内存泄漏 基类析构函数多数情况下应该声明为虚函数的原因 派生类的析构函数也会自动成为虚函数,编译器会根据指针的指向来选择函数,所以会调用派生类析构函数,再调用基类析构函数 否则就有内存泄露的风险 5.4 C++纯虚函数和抽象类 纯虚函数 纯虚函数特点 纯虚函数不需要在本类内实现,把类变成抽象类 只有类的成员函数才能声明为纯虚函数,普通函数不能(编译报错) 纯虚函数语法 virtual 返回值类型 函数名 (函数参数) = 0; 例子:virtual float area() = 0; 抽象类 什么是抽象类 包含纯虚函数的类称为抽象类 抽象类的特点 抽象类自身无法实例化 抽象类中的纯虚函数是不完整的,没有函数体,无法分配空间,也无法调用 抽象类通常是作为基类,让派生类去实现纯虚函数 派生类必须实现纯虚函数才能被实例化 纯虚函数给派生类提供的强制约束条件,不实现就不能实例化 抽象类的作用 约束派生类的功能 必须要实现抽象类中的纯虚函数,否则不能实例化 实现多态 用基类指针访问派生类成员(变量和函数) 5.
package main import ( "context" "io/ioutil" "log" "math" "time" "github.com/chromedp/cdproto/emulation" "github.com/chromedp/cdproto/page" "github.com/chromedp/chromedp" ) func main() { // 禁用chrome headless opts := append( chromedp.DefaultExecAllocatorOptions[:], chromedp.NoDefaultBrowserCheck, //不检查默认浏览器 chromedp.Flag("headless", true), chromedp.Flag("blink-settings", "imagesEnabled=true"), //开启图像界面,重点是开启这个 chromedp.Flag("ignore-certificate-errors", true), //忽略错误 chromedp.Flag("disable-web-security", true), //禁用网络安全标志 chromedp.Flag("disable-extensions", true), //开启插件支持 chromedp.Flag("disable-default-apps", true), chromedp.NoFirstRun, //设置网站不是首次运行 chromedp.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36"), //设置UserAgent ) allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...) defer cancel() // 创建上下文实例 ctx, cancel := chromedp.
1、关于windows10写的QT配置OpenCV 去看这个博客:https://blog.csdn.net/qq_41185569/article/details/109219705
和这个b站视频https://www.bilibili.com/video/BV1hu411z7nL?spm_id_from=333.337.search-card.all.click
2、做完上述步骤之后,我们来配置opencv_contrib 注意,opencv_contrib与opencv的版本必须一致。
最后一版CentOS 8只会更新到2021年12月31日,现在官方源已经停止维护,需要更改到stream源
阿里云开源镜像站资源目录 在各个开源镜像站找到centos 8-stream目录
找到对应源填入仓库,必要的源是BaseOS和AppSream,其余可以后续自行填入/etc/yum.repos.d
如果不能打开配置安装源,需要先配置磁盘和网络
接下来就可以正常安装系统了
文章目录 目录
文章目录
前言
一、Vuex是什么?
二、初始化
三、Vuex组成 (一)
state
1.定义 2. 原始调用
3. 辅助函数 - mapState
(二)mutations
1.定义 2.原始调用
3.辅助函数 - mapMutations
(三)actions
1.定义 2.原始调用
3.辅助函数 -mapActions
(四)getters
1.定义
2.原始调用
3.辅助函数 - mapGetters
(五)Module
总结
1.vuex由五部分组成:
2.有四个辅助函数:
前言 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
一、Vuex是什么? 简单来说vuex是采用集中式管理组件依赖的共享数据的一个工具,它可以解决不同组件数据共享问题。
【注意】
修改state状态必须通过mutations
mutations只能执行同步代码,类似ajax,定时器之类的代码不能在mutations中执行
执行异步代码,要通过actions,然后将数据提交给mutations才可以完成
state的状态即共享数据可以在组件中引用
组件中可以调用action
二、初始化 第一步:npm i vuex --save => 安装到运行时依赖 => 项目上线之后依然使用的依赖 ,开发时依赖 => 开发调试时使用
开发时依赖 就是开开发的时候,需要的依赖,运行时依赖,项目上线运行时依然需要的
第二步: 在main.js中 import Vuex from 'vuex'
一、使用 Executors 创建线程池
Executors是一个线程池工厂类,里面有许多静态方法,供开发者调用。
/* 该方法返回一个固定线程数量的线程池,该线程池池中的线程数量始终不变。 * 当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。 * 若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务 * 默认等待队列长度为Integer.MAX_VALUE */ ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1); /* 该方法返回一个只有一个线程的线程池。 * 若多余一个任务被提交到线程池,任务会被保存在一个任务队列中,等待线程空闲,按先入先出顺序执行队列中的任务 * 默认等待队列长度为Integer.MAX_VALUE */ ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); /* * 该方法返回一个可根据实际情况调整线程数量的线程池。 * 线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。 * 若所有线程均在工作,又有新任务的提交,则会创建新的线程处理任务。 * 所有线程在当前任务执行完毕后,将返回线程池进行复用 */ ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); /* 该方法返回一个ScheduledExecutorService对象,线程池大小为1。 * ScheduledExecutorService接口在ExecutorService接口之上扩展了在给定时间内执行某任务的功能, * 如在某个固定的延时之后执行,或者周期性执行某个任务 */ ExecutorService newSingleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor(); /* * 该方法也返回一个ScheduledExecutorService对象,但该线程池可以指定线程数量 */ ExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(1); Executors 的静态方法都是基于 ThreadPoolExecutor 类实现的,相当于 ThreadPoolExecutor 的 语法糖。
但这几个静态方法都存在一个弊端,因为会在创建线程池的同时隐式创建等待队列,而队列的长度默认是 Integer.
1 眼图概述 1.1 串行数据的传输 由于通讯技术发展的需要,对数据带宽的需求日益增加,使得电子系统从传统的并行总线转为串行总线。串行信号种类繁多,如 PCI Express、SPI、USB 、SATA等,其传输信号类型时刻在增加。为何串行总线目前应用越来越广泛呢?相比并行数据传输,串行 数据传输的整体特点如下:
1 信号线的数量减少,成本降低
2 消除了并行数据之间传输的延迟问题
3 时钟是嵌入到数据中的,数据和时钟之间的传输延迟也同样消除了
4 传输线的 PCB 设计也更容易些
5 信号完整性测试也更容易
实际中,描述串行数据的常用单位是:波特率和 UI。串行数据传输示例如下:
图1 串行数据传输示例
例 如,比特率为 3.125Gb/s 的信号表示为每秒传送的数据比特位是 3.125G 比特,对应的一个单位间隔即为 1UI。1UI表示一个比特位的宽度,它是波特率的倒数,即 1UI=1/(3.125Gb/s)=320ps。现在比较常见的串行信号码形是 NRZ 码,因此在一般的情况下对于串行数据信号,我们的工作均是针对 NRZ 码进行的。
1.2 眼图的形成原理 眼图,是由于示波器的余辉作用,将扫描所得的每一个码元波形重叠在一起,从而形成眼图。眼图中包含了丰富的信息,从眼图上可以观察出码间串扰和噪声的影响,体现了 数字信号整体的特征,从而可以估计系统优劣程度,因而眼图分析是高速互连系统信号完 整性分析的核心。另外也可以用此图形对接收滤波器的特性加以调整,以减小码间串扰,改善系统的传输性能。
目前,一般均可以用示波器观测到信号的眼图,其具体的操作方法为:将示波器跨接 在接收滤波器的输出端,然后调整示波器扫描周期,使示波器水平扫描周期与接收码元的周期同步,这时示波器屏幕上看到的图形就称为眼图。示波器一般测量的信 号是一些位或某一段时间的波形,更多的反映的是细节信息,而眼图则反映的是链路上传输的所有数字 信号的整体特征,两者对比如下图所示:
图2 示波器中的信号与眼图
如果示波器的整个显示屏幕宽度为 100ns,则表示在示波器的有效频宽、取样率及记忆体配合下,得到了100ns下的波形资料。但是,对于一个系统而言,分析这么短的时间内的信号并不具有代表性,例如信号在每一百万位元会出现一次突波(Spike),但在这 100ns时间内,突波出现的机率很小,因此会错过某些重要的信息。如果要衡量整个系统的性能, 这么短的时间内测量得到的数据显然是不够的。设想,如果可以以重复叠加的方式,将新的信号不断的加入显示屏幕中,但却仍然记录着前次的波形,只要累积时间 够久,就可以 形成眼图,从而可以了解到整个系统的性能,如串扰、噪声以及其他的一些参数,为整个系统性能的改善提供依据。 分析实际眼图,再结合理论,一个完整的眼图应该包含从“000”到“111”的所有状态组,且每一个状态组发生的次数要尽量一致,否则有些信息将无法呈现在屏幕上,八种状态形成的眼图如下所示:
图3 眼图形成示意图
由上述的理论分析,结合示波器实际眼图的生成原理,可以知道一般在示波器上观测到的眼图与理论分析得到的眼图大致接近(无串扰等影响),如下所示:
图4 示波器实际观测到的眼图
如果这八种状态组中缺失某种状态,得到的眼图会不完整,如下所示:
图5 示波器观测到的不完整的眼图
通过眼图可以反映出数字系统传输的总体性能,可是怎么样才能正确的掌握其判断方 法呢?这里有必要对眼图中所涉及到的各个参数进行定义,了解了各个参数以后,其判断 方法很简单。
1.3 眼图参数定义 通过上述对眼图形成理论的分析,我们可以知道眼图中通常显示的是 1.
调用 select() 相关函数编程时,委托内核对需要监测的文件描述符进行检测,检测的内容可以理解为两个方面:
用于的监听套接字文件描述符用于通信的套接字文件描述符 不论哪种文件描述符对应的缓冲区发生改变,内核都会将文件描述符数组对应值置1。
问题来了
当只有监听文件描述符对应缓冲区发生变化,而通信文件描述符没变化时,调用 select() 会有返回值 1. 因为只有一个文件描述符发生变化。
而编写程序的逻辑是先判断是否是监听文件描述符发生变化,如果是,要通过其生成一个用于通信的文件描述符。此时其实我们这一轮的工作已经完成,直接下轮循环调用 select() 即可,也可对。但如果没有直接下轮循环,而是继续去进行遍历文件描述符数组进行读写操作的判断,并且遍历文件描述符数组是从 0 开始的,就会出问题:read: Transport endpoint is not connected。
分析
这个问题是因为我们读取的是用于监听的文件描述符的缓冲区。因为我们这一轮循环只有一个文件描述符发生了变化,也进行了判断 发生变化的文件描述符就是监听文件描述符,接收连接 其实工作已经完成。结果继续遍历去读写数据,还是从文件描述符的头部 0 开始遍历,必然又会遍历到监听文件描述符为 1. 此时 read() 就会报错。
解决方案
方案1:
判断发生变化的文件描述符为 监听描述符 并完成连接业务后,进行一次判断,判断 select() 的返回值是否为 1,为 1 则说明这次委托检测只有客户端连接进来了,没有客户端往服务器端写数据。则和连接进来的客户端建立连接后将其加入下次监听行列就好了,就可以下次循环了。
if (FD_ISSET(lisfd, &tmp)) { // 找到连接进来的客户端对应的文件描述符,进行连接 struct sockaddr_in cliaddr; int len = sizeof(cliaddr); int comfd = accept(lisfd, (struct sockaddr*)&cliaddr, &len); // 将用于通信的文件描述符 添加到需要委托内核检测的数组集合中 FD_SET(comfd, &rdset); // 更新下次内核遍历时,需要遍历到的地方 maxfd = comfd > maxfd ?
一、概要 不知道大家在开发WPF中有没有遇到过这种情况,在编写XAML的时候会发现多人编辑或自己修修改改会导致XAML文件的内容异常的乱比如这样。
我们需要手动的去缩进空格或者换行,会导致这种比较蠢的事情浪费我开发时间。这里向大家推荐一款XAML格式化神器解决这个头疼而且还费时间的事情。
二、详细步骤 第一步,在VS2019中找到扩展。
第二步,打开管理扩展界面。
第三步,在右侧搜索框输入XAML会自动搜索出XAML Styler
第四步,下载安装
第五步,重启VS2019
第六步,在XAML文件中点击右键查看安装是否成功
使用前:
使用后:
diygw拖拽自动生成App,大家只需要动动自己的鼠标、键盘轻松几步就能打造自己的专属APP。支持自动生成uniapp源码、微信小程序源码、支付宝小程序源码等。
大家可以在基础组件里拖动组件到页面设计区,右边属性进行修改。
组件模板里系统内置了一系列的模板,大家只需要选中对应的模板,点击下即可增加到设计区。
页面模板,本APP直接使用页面模板中的个人模板,轻松点下整个模板就是自己的了。修改下个人相关信息,就打造出一个自己的专属简历APP。
DIY官网可视化工具做好的可视化拖拽开发工具无须编程 零代码基础 所见即所得设计工具轻松制作微信小程序、支付宝小程序、Vue3、H5、WebApp、UNIAPP、单页动画