目录
1.什么是MVC?
2.MVC购物车案例
2.1.数据库的设计
2.2.需要开发的界面
2.3.购物车样式设计
2.4.购物车具体实现代码
第一步:进入购物首页页面绑定数据
第二步:点击加入购物车进入我的购物车页面
第三步:加入到我的购物车,对商品数量的更改以及商品总价的计算
第四步:实现删除我的购物车商品的功能
1.什么是MVC? MVC全名是Model(模型) View(视图) Controller(控制器)。是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
Model(模型)表示应用程序核心(比如数据库记录列表)。
View(视图)显示数据(数据库记录)。
Controller(控制器)处理输入(写入数据库记录)。
2.MVC购物车案例 购物车效果展示:
功能:
购物首页:点击加入购物车,进入我的购物车页面(商品直接加到我的购物车),也可直接点击我的购物车进入(查看加入到购物车的商品)。
我的购物车:可进行对商品数量的更改以及商品总价的计算、以及删除购物车商品的操作。
2.1.数据库的设计 sp_user用户表 用户ID(uuid)用户名称(uuid)用户密码(uuid)用户地址(uuid)用户电话(uuid)1admin123长沙8888882sb321郴州999999 sp_goods商品表 商品ID(gid)商品名称(gname)商品单价(gprice)1可乐32方便面4.53饼干15 sp_cart购物车表 商品编号(cid)商品名称(gname)商品单价(gprice)商品数量(gcount)商品总价(cprice)购买用户ID(uuid)1可乐313admin2饼干15115sb --sp_user用户表
create table sp_user(
uuid number primary key,--用户ID
uname varchar2(20) unique,--用户名称
upwd varchar2(20),--用户密码
uaddress varchar2(50),--用户地址
utel varchar2(50)--用户电话
)
--sp_goods商品表
create table sp_goods(
gid number primary key,--商品ID
gname varchar2(20) not null,--商品名称
gprice float not null--商品单价
)
--往sp_goods商品表里面插入的数据
insert into sp_goods(gname,gprice)
调试对于写程序的人而言,是一项必不可少的技能。这篇文章就是写程序的基础——调试
首先我们打开一个代码开始调试,这里用的代码比较简单
调试之前需要在序号上打断点(直接点击要查看那一行的序号就ok),如下图
如果不打断点程序会运行完
再点击工具栏中的勾✔(或者快捷键f5再或者工具->调试)
调试开始后,程序运行时会停在你的第一个断点存在的那一行代码上,且底下会出现一个调试选项
这样就可以根据所需来调试你的代码,当然这样时不够的,因为这时候的我们无法看到数据的值,只能看到函数的执行步骤。需要看到具体数值我们可以调出调试框
视图->浮动项目管理器(点击关闭,这样浮动项目管理器就会存在我们程序的左侧)
接下来我们就可以用添加查看来添加我们想要查看的值,这里可以添加多个,也可以添加表达式
(也可以鼠标长按鼠标左键选中需要看的再点击添加查看就可以不用输入)
所查看的数值会随着你的函数改变而改变
如果调试会闪退或者没有调试信息,看一下是否设置好
再工具->编译选项->代码生成/优化->连接器->产生调试信息改为yes
最后,是演示代码的调试逐步展示和演示代码(演示不重要可以不看)
#include<stdio.h>
int main()
{
int a=2,b=0,c=0;
scanf("%d",&b);
a=b+a+2;
b=b+1;
c=a+b;
printf("c = %d",c); }
什么是游戏盾呢
游戏盾是DDoS高防IP产品系列中针对游戏行业的安全解决方案。 游戏盾专为游戏行业定制,针对性解决游戏行业中复杂的DDoS攻击、游戏CC攻击等问题。
游戏盾的原理是什么
全新一代云防系统,为所有TCP业务提供防御解决方案,全面支持Windows、Linux、Unix、MacOS、IOS、Android等平台,端游,手游APP,EXE封装、SDK接入,分钟级集成智能链路加速,多节点无缝切换,完美解决DDoS、CC等网络攻击,真正做到用户无感体验。
游戏盾有哪些功能呢
超大流量型DDoS攻击防护。游戏盾包含抗D节点,提供可弹性扩缩的分布式云防护节点,当发生超大流量攻击时,可根据影响范围,迅速将业务分摊到未受影响的节点。
精准防御CC攻击。通过创新的报文基因技术,在用户与防护节点之间建立加密的IP隧道,准确识别合法报文,阻止非法流量进入,可彻底防御CC攻击等资源消耗型攻击。
游戏盾在用户SDK集成,EXE集成,DLL集成后接入,拥有最快的调度能力和加密能力。
游戏盾的优势是什么呢
T级防御系统
分布式云节点防御集群,可跨地区、跨机房动态扩展防御能力和负载容量,轻松达到T级别防御,还能彻底解决游戏行业特有的TCP协议的CC攻击问题,防护成本更低,效果更好!
完美隐藏源机
自研核心技术架构形成一道天然屏障,从源头彻底隐藏源机IP和端口,漏洞扫描和网络攻击无从下手,攻击流量无法直接到达源机,保障后端服务器稳定运行和数据安全。
通用防御架构
全平台支持,通用防御产品。适合所有TCP端类应用,EXE封装、SDK接入,支持Windows、iOS、Android系统,分钟级集成。
当业务遭遇大规模DDoS和CC攻击,导致单个或多个高防云节点延迟过大或进入黑洞时,网盾调度中心能自动感知并无缝切换其他可用节点,0延迟0误封,用户无感体验。
杜绝DNS劫持
客户端集成游戏盾后,所有数据包基于游戏盾节点转发并加密,结合独家研发的私有协议认证,可有效免疫DNS劫持。
部署配置灵活
无需投入任何硬件设备,只需几个步骤即可接入,集成方式灵活,支持EXE打包、DLL引用、SDK开发。部署过程对于玩家和用户透明,不影响原有业务流程。
package xinghuo; //阿克曼 (Ackmann)(Ackmann) 函数 A(m,n)A(m,n) 中,m,nm,n 定义域 //是非负整数 (m≤3,n≤10),函数值定义为: //akm(m,n)=n+1 ( m=0 时 )。 //akm(m,n)=akm(m-1,1) (m>0,n=0 时 )。 //akm(m,n)=akm(m-1,akm(m,n-1) ;(m,n>0 时 )。 import java.util.Scanner; public class Main3 { public static void main(String[] args) { Scanner scan=new Scanner(System.in); int a1[]=new int[2]; for(int i=0;i<2;i++) {a1[i]=scan.nextInt();} System.out.println(akm(a1[0],a1[1])); } public static int akm(int m,int n) { if(m==0) { return n+1; }else if(m>0&&n==0) { return akm(m-1,1); }else if(n>0) { return(akm(m-1,akm(m,n-1))); } return n+1; } } 还是Java的基础不牢固,感觉有点问题,有的都忘记了,还是要复习。
1)安装步骤 (1)首先确保 JDK1.8 安装成功 (2)下载对应的 Scala 安装文件 scala-2.12.11.zip (3)解压 scala-2.12.11.zip,我这里解压到 D:\Tools (4)配置 Scala 的环境变量 官网下载scala,选择版本
配置环境变量
测试
(1)在键盘上同时按 win+r 键,并在运行窗口输入 cmd 命令 (2)输入 Scala 并按回车键,启动 Scala 环境。
ctrl+c退出scala环境
如果在Idea上使用scala,还需要安装scala插件,详见:scala插件安装
作用 where函数的主要作用是:根据给定的条件返回相对应的值。
使用方法 import numpy as np np.where(condition, [x, y]) 参数 condition:给定条件;[x, y]:返回值,满足条件,返回x,否则返回y。 实例1–返回满足条件的索引(下标) 在不指定返回值的条件下,默认返回满足条件的索引(下标)。
import numpy as np a = np.arange(1,11) a 输出:
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) np.where(a < 5) 输出:
(array([0, 1, 2, 3], dtype=int64),) 实例2—对满足条件数据进行处理 import numpy as np a = np.arange(1,11) a 输出:
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 对数组a,使用where函数,若是满足小于5的条件返回原值,否则翻10倍。
np.where(a < 5, a, 10*a) 输出:
反射是框架设计的灵魂 框架 = 注解 + 反射 + 设计模式。
一、Java反射机制的基本概念 Java 反射机制是 Java 语言的一个非常重要的特性。
在学习 Java 反射机制前,大家应该先了解两个概念,编译期和运行期。
1.1 编译期和运行期 1.1.1 编译期 编译期是指把源码交给编译器编译成计算机可以执行的文件的过程。在 Java 中也就是把 Java 代码编成 class 文件的过程。编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误。
在编译期,将Java代码翻译为字节码文件的过程经过了四个步骤,词法分析,语法分析,语义分析,代码生成四个步骤。
1、词法分析
词法分析是编译的第一阶段。词法分析器的主要任务是读入源程序的输入字符,将它们组成词素,生成并输出一个词法单元序列,这个词法单元序列被输出到语法分析器进行语法分析。
通俗理解:读取源代码,一个字节一个字节的读取,找出其中我们定义好的关键字(如Java中的if、else、for、while等关键词,识别哪些if是合法的关键词,哪些不是),这就是词法分析器进行词法分析的过程,其结果是从源代码中找出规范化的Token流。
2、语法分析
语法分析程序从扫描程序中获取记号形式的源代码,并完成定义程序结构的语法分析(syntax analysis),这与自然语言中句子的语法分析类似。语法分析定义了程序的结构元素及其关系。通常将语法分析的结果表示为语法树。
通俗理解:通过语法分析器对词法分析后Token流进行语法分析,这一步检查这些关键字组合再一次是否符合Java语言规范(如在if后面是不是紧跟着一个布尔判断表达式),词法分析的结果是形成一个符合Java语言规范的抽象语法树。
3、语义分析
程序的语义就是它的“意思”,它与语法或结构不同。程序的语义确定程序的运行,但是大多数的程序设计语言都具有在执行之前被确定而不易由语法表示和由分析程序分析的特征。这些特征被称作静态语义(static semantic),而语义分析程序的任务就是分析这样的语义,语义具有只有在程序执行时才能确定的特性,由于编译器不能执行程序,所以它不能由编译器来确定)。一般的程序设计语言的典型静态语义包括声明和类型检查。由语义分析程序计算的额外信息,它们通常是作为注释或“装饰”增加到树中(还可将属性添加到符号表中)。
通俗理解:通过语义分析器进行语义分析。语音分析主要是将一些难懂的、复杂的语法转化成更加简单的语法,结果形成最简单的语法(如将foreach转换成for循环,好有注解等),最后形成一个注解过后的抽象语法树,这个语法树更为接近目标语言的语法规则。
4、代码生成
代码生成器得到中间代码,并生成目标代码。
通俗理解:通过字节码生产器生成字节码,根据经过注解的语法抽象树生成字节码,也就是将一个数据结构转化为另一个数据结构,最后生成我们想要的.class文件。
1.1.2 运行期 运行期是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来。
从jvm加载字节码文件,到使用到最后的卸载过程,都是属于运行期的范畴。
1.2 理解反射 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。在 Java 中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。
要想解剖一个类,必须先要获取到该类的字节码文件对象,而解剖使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象。Class类用于表示.class文件(字节码)。
反射就是把Java类中的各种成分映射成一个个的Java对象。例如:一个类有成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述。
以上的总结就是什么是反射!
下图是类的正常加载过程:反射的原理在与class对象。
熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。
1.3 为什么要使用反射 Java中编译类型有两种:
静态编译:在编译时确定类型,绑定对象即通过。
动态编译:运行时确定类型,绑定对象。动态编译最大限度地发挥了Java的灵活性,体现了多态的应用,可以减低类之间的耦合性。
Java Reflection(反射)是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public、static等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Reflection可以在运行时加载、探知、使用编译期间完全未知的classes。即Java程序可以加载一个运行时才得知名称的class,获取其完整构造,并生成其对象实体、或对其fields设值、或唤起其methods。
加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。
一、需求梳理: 1、从FTP服务器上拉取文件(文件名按照固定格式命名)。
2、提取文件名上的一些字符串信息合并到数据流中,入库。
3、替换文件流中的一些字段值。
实现ETL的功能,其流程图如下:
NIFI处理器的选择:
处理器
主要功能
ListFTP
列出服务器文件列表
FetchFTP
根据列表拉取数据
UpdateAttribute
新增流文件属性
UpdateRecord
新增流文件内容或路由逻辑
MergeRecord
文件流纵向合并
MergeContent
文件流横向合并
QueryRecord
从合并流文件中查询结果
InvokeHTTP
结果数据入库
RouteOnAttribute
路由结果数据
HashContent
释放掉结果数据
二、文件流数据替换 选用UpdateRecord处理器、选用Schema Text格式。
{ "type":"record", "name":"nifiRecord", "namespace":"org.apache.nifi", "fields":[ { "name":"test_a", "type":[ "null", "string" ] }, ... {"name":"test_e", "type":["null" ]"string"] }] } 三、从FTP拉取csv文件 监控FTP服务器:ListFTP处理器
拉取FTP服务器两个小时之后的数据:新增路由规则
ListFTP-> UpdateAttribute-> RouteOnAttribute-> FetchFTP
新增自定义属性:UpdateAttribute处理器
fileTime: ${filename:getDelimitedField(5,'-'):trim():toDate('yyyyMMddHHmmss'):toNumber()} timeNow: ${now():toNumber():minus(7200000)}
延时拉取方案实现:
2 hours old ${fileTime:le(${timeNow})}
四、文件实现纵向合并 1、将文件格式转为avro数据格式(avro数据格式在大量数据合并时效率高):updateRecord处理器
2、文件合并:MergeRecord处理器
Android Studio Bumblebee 新建项目模版build.gradle 如何添加 classpath plugins maven 前言添加classpath添加maven完事 前言 升级Android Studio Bumblebee后,发现新建项目时的根目录build.gradle已经和之前的完全不一样了。
旧的build.gradle如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = "1.4.21" repositories { google() jcenter() } dependencies { classpath "com.android.tools.build:gradle:4.0.0" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() maven { url 'https://jitpack.
今天写demo时遇到一个问题,在使用jquery取id为username的文本框的值时,无法取到内容,大致问题如下所示:
从上面可以看出,整个body中只有一个id 为username,最终结果为用户名并没有取到,但密码取到了,最后,将id为username改一下,就取到输入的用户名值。
如果有知道是什么原理的伙伴,烦请告知一下,我只实现了解决,并没找到原因。
remote host
【Mysql索引】二叉树、红黑树、B树、B+树 (1)哈希表(2)二叉树的弊端的演示:(3)红黑树的插入演示:(4)B树的演示(5)B+树的演示(叶子加指针:支持范围查找)(5.1)借着学习B+树的机会,学习为什么会出现索引失效的情况 (7)学习MyISAM引擎的索引的底层原理(8)学习InnoDB引擎(聚集索引)(9)哈希索引和B+树索引(叶子节点指针的作用:支持范围查找) 索引是帮助Mysql高效获取数据的排好序的数据结构
(1)哈希表 Select * from t where t = 5;
上面的语句先到哈希表中找到索引,索引表里存放着对应的地址;然后根据哈希表里的地址,到二叉树里查找,二叉树的查找会快一点。二叉排序树是左小右大,通过比较值大小来往下查找
但是索引基本不用二叉树,为什么不用二叉树呢?
(2)二叉树的弊端的演示: 一个学习算法很好用的网站:算法演示网站
发现问题所在,但我们插入一个有序的数列时,二叉树就会退化为一个链表,这样二叉树的检索优势就不存在了,因此不能使用二叉树,二叉树改进成 红黑树,但是索引也不用红黑树,为什么呢?
(3)红黑树的插入演示: 当一棵子树的高度差超过2的时候,红黑树通过自旋,把中间那个往上提,把第一个往下放,变成左右子树高度差为0,这样就能避免二叉树退化成链表了
但是红黑树还是有点问题,此时用红黑树存放100万个数据,把树放满,这个树的高度会越变越高,这样的话查找的效率也会大大降低,所以红黑树只是在HashMap中使用,而不能用来处理大量的数据。这时候就要考虑在数据增多的时候而不增加树的高度,来看B树
(4)B树的演示 即使是百万数据,想把数据查找的次数控制在3-5之间,也就是说树的高度控制在3-5之间。
那么就把树的每一层变大一点,放的节点多一点,这样树的高度就会控制好,我们设置每一个节点最多放3个数据,
看一下B树存放索引的数据结构:加入搜索20,先从第一层找,把搜索值和15比较,然后往右去跟56比较,然后就能确定在15-56之间的位置,就可以到第二层搜索,找到!
(5)B+树的演示(叶子加指针:支持范围查找) B+树也叫多叉平衡树
一次检索6的过程:
B+树存放索引的情况:
1-非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
2-叶子节点包含所有的索引字段
3-叶子节点用指针连接,提高区间访问的性能
InnoDB引擎下的B+树索引,第一层的节点为16Kb,而第一层的15节点站8b,15-56之间的节点的长度为6b,这个白色节点表示下一层的指针,也就说存储一个索引为14b。所以每一层可以放置1170个索引,那么三层B+树可以放置1170117016=2190万个索引。注意15节点下面没有存放data,这只是一个冗余索引,帮助你到叶子节点中去找具体的data。
注意到B+树还有一个改进,那就是叶子节点加了横向指针,因为B+树的叶子节点是排好序的,横向指针可以更好的实现范围查找。
(5.1)借着学习B+树的机会,学习为什么会出现索引失效的情况 当我们给数据表添加【联合索引】的时候,树的每个节点里会放置多个值,例如(a,b,c),当我们找这些值的大小规律时,会发现每个节点里的a值是从小到大的顺序,而只比较b/c值的时候,其实是无序的。
根据上面的逻辑,当我们要根据索引查找一个值的时候,要使用二分查找法,就要先确定a值的位置(因为a值有序),确定a值以后就能确定一个节点的范围,然后在这个范围内的b值也是从小到大的顺序了,然后继续使用二分查找法确定节点的范围,以此类推…
总结上面的逻辑:只有当a值有序且确定范围的时候,才能保证b值是有序的,接着只有当b值有序且确定范围的时候,才能保证c值是有序的,以此类推。这样就很好理解【最佳左前缀】原则了。如果带头大哥没了,或者中间值断了,那么后面的值就不能保证有序,无序就自然无法使用【二分查找法】,也就出现【索引失效】的情况了。当我们设定索引的时候,索引的树结构也就确定了。
通过上面的例子,就很好理解【索引在使用大于号/小于号时失效】【like模糊查询时索引失效】【使用or或者in之类时索引失效】
失效的原因都是没办法确定一个值,而是只能确定一个范围,导致不能使用二分查找法。例如大于号,不能确定b为某个值,只能确定范围,而这时范围内所有叶子结点里的c值就不是完全有序的,也就不能使用二分查找法,自然b后面的索引都会失效啦!!!
(7)学习MyISAM引擎的索引的底层原理 MyISAM引擎创建的表分为三个文件,分别是:
frm后缀:表定义的一些内容MYD后缀:MyISAM引擎对应的Data,也就是数据文件MYI后缀:MyISAM引擎对应的Index,也就是索引文件 所以说,MyISAM引擎的索引文件和数据文件是分离的,从数据结构看叶子节点里放的不是data,放的是地址,找到地址后再到数据文件里找数据
(8)学习InnoDB引擎(聚集索引) InnoDB引擎创建的表分为两个:
1-frm后缀:表定义的内容
2-ibd后缀:存储索引和数据的文件
1-表数据文件本身就是按B+树组织的一个索引结构文件
2-聚集索引:索引文件和数据文件不分离,都放在叶子节点里
3-为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
InnoDB必须要有主键,并且使整型的自增主键。如果你没有创建主键的话,InnoDB引擎会在表中找一个能唯一标识的数据自动为你创建主键。使用整型是因为整型的数字2<3比较的速度很快,比使用UUID这种字符的比较快很多,字符还需要转换成ACSII码,然后才进行比较;使用自增主键作为索引,而索引放在叶子节点中,叶子节点之间有个指针,叶子指针节点是一个递增的趋势,所以指针可以快速找到下一个节点,这个指针可以有效的支持范围查找,但是如果不是自增的话就不好进行范围查找了。
4-为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)
(9)哈希索引和B+树索引(叶子节点指针的作用:支持范围查找) 哈希索引用的非常少,多数用的就是B+树索引,用哈希索引的速度是比B+树索引要快的,但是它有一个致命的缺点:
select * from table Where col = 6;如果用哈希索引,那就直接到哈希索引表里找就行了,速度很快
但是如果加上检索的范围 select * from table Where 6<col<9;,检索结果集再用哈希索引就不行了,而且工作中肯定离不开范围查找,使用B+树索引进行范围查找的时候,就可以用到叶子节点的指针,先在叶子节点中快速定位到6,然后根据叶子节点的指针往后找到9,那么指针经过的所有叶子节点就是要查找的范围结果集,
思路:
(1)插入: 根节点设置为黑色 插入节点初始为红色,先确定插入位置,当父节点为红色时需要调整。 由于需要保证root指向树的唯一入口,并且调整中的旋转会对root产生影响,所以调整时,需要分为: 1.插入节点的祖父节点是根节点 2.插入节点的祖父节点不是根节点 区别:是否需要回溯(将插入节点的祖父节点看做插入节点进行调整) 旋转调整: (1)兄弟节点是黑色或者为空时:需要旋转(参考AVL的LL型、RR型、LR型、RL型) (2)兄弟节点是红色时:变色不旋转 (2)查询: 根据关键字查询:直接比对数据即可 根据索引查询:利用leftsize计算节点在有序序列中的位置索引 (3)删除: 根据关键字删除,根据索引删除 先根据删除条件找到要删除的节点,删除之后进行调整。 如果删除节点是红色节点,则该节点要么是叶节点,要么度为2。 (原因:根据红黑树的性质:不会出现度为1的情况,因为如果度为1,不能出现连续红, 则唯一子节点一定是黑色,因为黑色路径长度相同的性质,所以不可能出现度为1的情况) 如果是叶节点,直接删除(设置为null即可) 否则寻找前驱节点(左子树中最右边的节点)进行替换 如果前驱节点是红色,直接删除 否则需要回溯 如果删除的是黑色节点,根据度进行调整: 1.度为2:找前驱节点进行替换,思路同上 2.度为1:则只可能有一个红色的子节点,直接替换删除即可 3.度为0,分情况: (1)兄弟节点为红色: 将父节点变红,兄弟节点变黑,旋转,继续回溯 (2)兄弟节点是黑色,远房侄子为红色: 将父节点和兄弟节点交换颜色,将远房侄子变成黑色,删除节点,旋转调整,不用回溯。 (3)兄弟节点是黑色,近邻侄子为红色: 将兄弟节点和近邻侄子节点交换颜色,旋转,调整,删除即可,不用回溯 (4)父节点为红色,兄弟节点为黑色,且兄弟节点是叶节点: 将父节点和兄弟节点交换颜色,直接删除,不用回溯 (5)除以上情况的情况:将兄弟节点变成红色,并回溯到父节点 总结:删除时看颜色的顺序:先看自己(真实删的节点),再看孩子,再看兄弟,再看侄子,最后看父亲 代码实现:
1.节点类和索引红黑树类的声明:
#include<iostream> #include<time.h> #include<queue> using namespace std; template<class k,class t> class note { public: pair<k, t>data; char color = 'r'; int leftsize = 0;//用来标识该节点的左子树的节点数,也是该节点在以其为根节点的子树的索引 note<k, t>* leftchild = NULL; note<k, t>* rightchild = NULL; note<k, t>* parent = NULL;//增加一个父节点,替换搜索父节点的开销 note<k, t>() = default; note<k, t>(pair<k, t>d); }; template<class k,class t> note<k, t>::note(pair<k, t>d) { data = d; } template<class k,class t> class indexedRedBlackTree {/*也是搜索树的性质(和第一题一样),只是每一个节点还有一个leftsize域*/ public: note<k, t>* root = NULL; //函数根据测试顺序排序: void insert(pair<k, t>p);//插入数对p void RR(bool isroot, note<k, t>* n, note<k, t>* temp, note<k, t>* tempfu, note<k, t>* tempfufu); void LL(bool isroot, note<k, t>* n, note<k, t>* temp, note<k, t>* tempfu,note<k, t>* tempfufu);//只负责旋转,不负责着色 void insertadjust(bool isroot, note<k, t>* n, note<k, t>* temp, note<k, t>* tempfu, note<k, t>* tempfufu); void ascend(note<k, t>* p);//按关键字升序输出所有数对 t find(k key);//返回关键字对应的数据 pair<k, t>get(int index);//返回第index个数对 void deleteindex(int index,pair<k,t>&x);//根据给定的索引,删除其数对 void deletekey(k key, t& x);//删除关键字为key的数对 void deletecommon(note<k,t>*temp,note<k,t>*tempfu); note<k, t>* case5(note<k, t>* d); }; 2.
下载安装 最新版本地址
#进入安装目录 cd /opt #下载安装包,300多M wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-linux-x86_64.tar.gz # 解压 tar -zxvf elasticsearch-7.10.1-linux-x86_64.tar.gz # 进入es根目录 cd elasticsearch-7.10.1 配置 修改配置文件 vim config/elasticsearch.yml #集群名词 cluster.name: lizz-application # 本节点名词 node.name: node-1 # 服务ip,0表示所有本地ip network.host: 0.0.0.0 # 服务端口号 http.port: 9200 # es节点列表,集群时配置多个,数组 discovery.seed_hosts: ["127.0.0.1"] # es启动时,参数选主的node列表,集群时配置多个 cluster.initial_master_nodes: ["node-1"] 启动 启动es bin/elasticsearch #启动失败异常 java.lang.RuntimeException: can not run elasticsearch as root 创建esuser用户,参考Linux用户管理添加/删除用户切换用户成功 sudo su esuser [sudo] esuser 的密码: 再次启动异常 bin/elasticsearch [1]: max number of threads [3882] for user [esuser] is too low, increase to at least [4096] [2]: max virtual memory areas vm.
CPU_SOC_MPU和MCU 一、CPU(Central Processing Unit)二、MPU (Micro Processor Unit)三、MCU(Micro Control Unit)四、SOC(System on Chip)五、SOPC(System On a Programmable Chip)六、区别6.1、MCU和MPU的区别6.2、CPU与SoC的区别6.3、SoPC与MCU、MPU、SoC的区别 一、CPU(Central Processing Unit) CPU(Central Processing Unit),是一台计算机的运算核心和控制核心。CPU由运算器、控制器和寄存器及实现它们之间联系的数据、控制及状态的总线构成。差不多所有的CPU的运作原理可分为四个阶段:提取(Fetch)、解码(Decode)、执行(Execute)和写回(Writeback)。 CPU从存储器或高速缓冲存储器中取出指令,放入指令寄存器,并对指令译码,并执行指令。所谓的计算机的可编程性主要是指对CPU的编程。(电脑CPU:处理和运算)
二、MPU (Micro Processor Unit) MPU (Micro Processor Unit),叫微处理器(不是微控制器),通常代表一个功能强大的CPU(暂且理解为增强版的CPU吧),但不是为任何已有的特定计算目的而设计的芯片。这种芯片往往是个人计算机和高端工作站的核心CPU。例如:Intel X86,ARM的一些Cortex-A芯片如飞思卡尔i.MX6、全志A20、TI AM335X等都属于MPU。
在微机中,CPU被集成在一片超大规模集成电路芯片上,称为微处理器(MPU),微处理器插在主板的cpu插槽中。通常所说的16位机、32位机是指该计算机中微处理器内部数据总线的宽度,也就是CPU可同时操作的二进制数的位数。目前常用的CPU都是64位的,即一次可传送64位二进制数。微处理器的功能结构主要包括:运算器、控制器、寄存器三部分:运算器的主要功能就是进行算术运算和逻辑运算。控制器是整个微机系统的指挥中心,其主要作用是控制程序的执行。包括对指令进行译码、寄存,并按指令要求完成所规定的操作,即指令控制、时序控制和操作控制。寄存器用来存放操作数、中间数据及结果数据。
MPU的制造商有:有恩智浦(NXP)、德州仪器(TI)(TEXAS INSTRUMENTS)等
三、MCU(Micro Control Unit) MCU(Micro Control Unit),叫微控制器,其实就是我们平常说的单片机(single-chip Micromputer)。是指随着大规模集成电路的出现及其发展,将计算机的CPU、RAM、ROM、定时计数器和多种I/O接口集成在一片芯片上,形成芯片级的芯片,比如51,STC、AVR、Cortex-M这些芯片,内部除了CPU外还有RAM、ROM,可以直接加简单的外围器件(电阻,电容)等构成最小系统就可以运行代码了。它本质上仍是一个完整的单片机,有处理器,有各种接口,所有的开发都是基于已经存在的系统架构,应用者要做的就是开发软件程序和加外部设备。而如x86、ARM这些MPU就不能直接放代码了,它只不过是增强版的CPU,必须添加相应的RAM,ROM。
现在STM32也几乎成为了MCU的代名词。
MPU的制造商有:意法半导体(ST)、德爱特梅尔(Atmel)等
四、SOC(System on Chip) SOC(System on Chip),整体的一个电路系统,完成一个具体功能的东西,指的是片上系统,MCU只是芯片级的芯片,而SOC是系统级的芯片,它集成了MCU和MPU的优点,它既MCU(51,avr)那样有内置RAM、ROM同时又像MPU那样强大,不单单是放简单的代码,可以放系统级的代码,也就是说可以运行操作系统(将就认为是MCU集成化与MPU强处理力各优点二合一)(以Linux OS为主)。(手机SOC:CPU+通信基带+音/视频编码器、解码器)
SOC目前则以Cortex-A系列为主。
SOC分为两类:基于微处理器构建MPU (Micro Processor Unit),如:路由器、智能音箱等运算处理较多。基于微控制器构建MCU(Micro Control Unit),如:电冰箱管理控制较多,不运算操作系统或者运算小型操作系统。
五、SOPC(System On a Programmable Chip) SOPC是System On a Programmable Chip的缩写,即 可编程片上系统,SOPC与MCU、MPU、SOC最明显的区别在于:可更改硬件配置,也就是说自己构造芯片。
目录
逻辑运算符
连接运算符
错误抑制符
三目运算符
逻辑运算符 &&:逻辑与,左边的条件与右边的条件同时成立(两边的结果都为True);
||:逻辑或,左边的条件或者右边的条件满足一个即可;
!:逻辑非,对已有条件进行取反,本身为true,取反结果就是false;
//逻辑运算符 $a= 'weekend'; $b= 'good'; //逻辑与 var_dump($a == 'weekend' && $b == 'good'); //逻辑或 var_dump($a=='weekend'||$b='goods'); //逻辑非 var_dump(!$a=='weekend'); var_dump($a=='weekend'); 逻辑与和逻辑或又称为短路运算,如果第一个表达式已经满足条件了,那么就不会运行逻辑运算符后面的表达式:所以在书写代码的时候尽量将出现概率最高的表达式放在第一位;
连接运算符 连接运算,是PHP中将多个字符串拼接的一种符号
. :将两个字符串拼接在一起
.= : 复合运算,将左边的内容与右边的内容连接起来,然后重新赋值给左边的变量;
$a= 'hello'; $b= 'aaaaaa'; echo $a.$b; $a.=$b; echo $a; 错误抑制符 在PHP中有一些错误可以提前预知,但这些错误可能无法避免,但是又不希望将这些报错给用户看,可以使用错误抑制符
$a=5; $b=0; //没使用错误抑制符 $a % $b; //使用错误抑制符 @($a % $b); 三目运算符 (表达式1)?(表达式2):(表达式3)
//三元运算符 echo $a>$b?$c:$d; //运算优先 if (($a==$b)&&($c<$d)||$a){ echo $a; }
leetcode之最短路径+记忆化dfs+bfs+动态规划刷题总结 最短路:给定两个顶点,在以这两个顶点为起点和终点的路径中,边的权值和最小的路径。
最短路径中有几种经典的算法,我们主要练习的是Dijkstra算法和Floyd算法,分别用于解决单元最短路径问题和多源最短路径问题。
Dijkstra算法适用于单源最短路径,具体地,找到最短路已经确定的节点,从它出发更新相邻节点的最短距离。
Floyd算法适用于多源最短路径,具体地,通过一系列n阶矩阵来计算一个n节点加权图的最短距离。每轮让第k个节点做中转节点,更新第i个节点到第j个节点的最短路径。
动态规划常常适用于有重叠子问题和最优子结构性质的问题,并且记录所有子问题的结果,因此动态规划方法所耗时间往往远少于朴素解法。
动态规划有自底向上和自顶向下两种解决问题的方式。自顶向下即记忆化递归,自底向上就是递推。
记忆化即记忆化搜索,也叫记忆化递归,其实就是拆分子问题的时候,发现有很多重复子问题,然后再求解它们以后记录下来。以后再遇到要求解同样规模的子问题的时候,直接读取答案。
使用动态规划解决的问题有个明显的特点,一旦一个子问题的求解得到结果,以后的计算过程就不会修改它,这样的特点叫做无后效性,求解问题的过程形成了一张有向无环图。动态规划只解决每个子问题一次,具有天然剪枝的功能,从而减少计算量。
深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.
广度优先搜索算法(Breadth-First Search,缩写为 BFS),又称为宽度优先搜索,是一种图形搜索算法。简单的说,BFS 是从根结点开始,沿着树的宽度遍历树的结点。如果所有结点均被访问,则算法中止。
1-电动车游城市
题目链接:题目链接戳这里!!!
思路:Dijkstra算法
对paths数组建立邻接表,分别存储两个相邻节点以及节点之间的权值,ans数组记录到达当前节点的最少用时,优先队列中存储所用时间,当前位置,剩余电量,并且按照所用时间升序排序,保证每次选择的都是所用时间最少的,如果电量未满可以考虑充电,如如果剩余电量够,可以往相邻的节点走。
class Solution { public int electricCarPlan(int[][] paths, int cnt, int start, int end, int[] charge) { int n = charge.length ; List<int[]> [] g = new List[n] ; for(int i=0; i<n; i++){ g[i] = new ArrayList<int[]>() ; } for(int [] path : paths){ //建立邻接表,后面好操作 int u = path[0], v = path[1], w = path[2] ; g[u].
什么是物理机 物理机是相对于虚拟机而言的对实体计算机的称呼。物理机提供给虚拟机以硬件环境,有时也称为“寄主”或“宿主”。平时我们见到的计算机就是物理机了,物理服务器又叫独立服务器,顾名思义,就是一个躺在机房的实实在在的物理服务器,独立服务器是为满足客户需求而选用的,因为客户端在服务器上是独立的,他们被授予大量磁盘空间,带宽速度取决于客户端管理服务器的方式,重载或升级服务器会很慢,但是由于需要提供高可靠的服务,因此在处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面要求较高。
物理机跟云服务器有什么区别? 随着网络不断的发展,服务器的类型也在更新迭代,现如今云服务器的兴起占据了很大一部分市场,独立服务器的市场份额受到了很大的冲击,物理服务器与云服务器的区别是什么?服务器与云服务器虽然一字之差,但在实际的购买和使用性能中却有不小的差别
物理机:
物理服务器其实就是在网络上为终端客户机提供专业服务的一种高性能,高可用性的计算机。服务器只是一个总称,根据应用领域不同就有不一样的服务器租用
比如,网吧里面的服务器、公司里面的服务器、网站托管的服务器、存储服务器、虚拟机服务器等等
优点:1,有远程操作权限
2,稳定性高、速度快、适合大型网站使用
3.防护能力强,带宽足,配置高。
云服务器:
云服务器是一种简单高效、安全可靠、处理能力可弹性伸缩的计算服务。其管理方式比物理服务器更简单高效,用户无需提前购买硬件,即可迅速创建或释放任意多台云服务器,但是像有些需要防护攻击,和加载带宽有要求的就不太适合。
优点:1.云主机能承受访问量大的网站,拥有独立的远程操作权限,管理方便
2.价格便宜,适合大多数基本要求的人群。
问题描述 azkaban调度脚本执行时报错:java.lang.IllegalStateException: Process has not yet started. 但是单独执行脚本发现运行正常。
问题解决 可能的原因:
如果脚本本身是使用集群执行的,检查是否将所以用到的脚本都分发到集群中。使用azkaban调度,切记先将用到的所有材料分发到集群中。检查azkaban的.flow文件是否书写正确。
从 avue-crud 的官方文档中我们可以知道,操作栏的按钮是否显示是通过 option 中相应的 Boolean 值控制的,比如:
delBtn 对应删除按钮editBtn 对应编辑按钮 但是,这种控制是会对整个表格生效的,那如果我想根据行状态来自定义控制每一行的按钮是否显示呢?该怎么做?
我的做法是根据官网的例子,用自定义插槽实现
<template slot="menu" slot-scope="{ row, index }"> <el-button v-if="这里是自己定义的条件" @click="handleEdit(row, index)" > 编辑 </el-button> </template> 这样一来,界面上按钮是有了,但是点击这个自定义的编辑按钮,不会显示弹窗啊,而且在官方文档中,也没有代码说明了调用什么方法可以弹出弹窗。
到底该怎么调出编辑的弹窗呢?
找了半天,在另一份文档中,找到了相关的代码:
文档地址:
https://www.bookstack.cn/read/avue-2.x/e7156c7f3b035c78.md
// handleEdit 是自己自定义的编辑按钮方法 handleEdit (row, index){ this.$refs.crud.rowEdit(row, index); }, 如此一来,便可以实现根据行状态来控制每一行按钮的显示与否了。