Less和Scss

css预处理器 CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行CSS的编码工作。 为什么要使用CSS预处理器 CSS仅仅是一个标记语言,不可以自定义变量,不可以引用。 CSS有具体以下几个缺点: 1,语法不够强大,比如无法嵌套书写,导致模块化开发中需要书写很多重复的选择器; 2,没有变量和合理的样式复用机制,使得逻辑上相关的属性值必须以字面量的形式重复输出,导致难以维护。 使用预处理器的优点: 1,提供CSS层缺失的样式层复用机制 2,减少冗余代码 3,提高样式代码的可维护性 Less Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。 Less 可以运行在 Node 或浏览器端。一个合法的CSS代码段本身也是一段合法的LESS代码段。 Less 提供了变量、嵌套、混合、操作符、函数等一般编程所需的抽象机制。 变量 变量允许我们在一个地方定义一系列通用的值,然后在整个样式表中调用。 在做全局样式调整的时候,可能只需要修改几行代码就可以了。 @width: 10px; @height: @width + 10px; #header { width: @width; height: @height; } 复制代码 编译为: #header { width: 10px; height: 20px; } 复制代码 混合(Mixins) 混合(Mixin)是一种将一组属性从一个规则集包含(或混入)到另一个规则集的方法。假设我们定义了一个类(class)如下: .bordered { border-top: dotted 1px black; border-bottom: solid 2px black; } 复制代码 如果希望在其它规则集中使用这些属性,只需像下面这样输入所需属性的类(class)名称即可

面试准备1

上海银行 目录 1. java io 字节流 字符流 使用场景 你了解java的流吗?怎么用流打开一个大文件? 2. java序列化 什么时候会用到(必问) 3. java集合类 哪些是线程安全的 为什么它们是线程安全的 4. String a = "a"创建了几个对象 5. mysql存储引擎 隔离级别 6. mybatis缓存 7. 反射以及其意义 8. linux命令 查看进程 查看文件 linux查看一个想知道的进程?linux查看日志文件带有关键字的? linux下如何查看网络状态,如何查看硬盘使用情况 9. spring中resources注解和Autowired的区别 10. spring中bean的构造器注入? 11. spring中的bean默认是单例还是多例 12. java设计模式 工厂方法如何实现14. 银行金额的计算在java中怎么实现比较好 15. 线程如何返回一个值 3.实现多线程的几种方式 4.HashSet有什么特点(唯一性),如何保证唯一性的? 5.进程和线程的区别 6.乐观锁和悲观锁 7.一个表(班级,课程名,姓名)有三条记录,说出具体的MySQL语句实现:A班课程最多的学生的姓名 8.进程间通信方式 9.JDBC过程 10.唯一约束和主键约束的区别 11.final关键字 12.Cookie和Session的区别 3.java一个文件里可以有多个类吗?不让用内部类? 4.ArrayList和LinkedList的区别? 5.java的内存回收机制?具体一点? 3.解释一下线程 4.线程间通信 6.mysql游标 1. java io 字节流 字符流 使用场景 在Java中所有数据都是使用流读写的。流是一组有序的数据序列,将数据从一个地方带到另一个地方。根据数据流向的不同,可以分为输入(Input)流和输出(Output)流两种。

mysql having的用法

一、 having的用法 having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。 二、SQL实例 显示每个地区的总人口数和总面积. SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY region 先以region把返回记录分成多个组,这就是GROUP BY的字面含义。分完组后,然后用聚合函数对每组中的不同字段(一或多条记录)作运算。 显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区。 //在这里,我们不能用where来筛选超过1000000的地区,因为表中不存在这样一条记录。相反,having子句可以让我们筛选成组后的各组数据 SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY region HAVING SUM(area)>1000000 mysql判断某个字段的长度: select home_page from aaa表 where char_length(trim(home_page))<10 and char_length(trim(home_page))>1; 三、mysql中的where和having子句的区别 mysql中的where和having子句都可以实现过滤记录的功能,但他们的用法还是有一些区别的。 用group by和having子句联合来查出不重复的记录,sql如下: select uid,email,count(*) as ct from `edm_user081217` GROUP BY email 然后看这个,就容易理解了 //先用group by 对email进行分组,在用having来过滤大于1的,这样查找出来的就是重复的记录了 select uid,email,count(*) as ct from `edm_user081217` GROUP BY email HAVING ct > 1 以下是having和where的区别: Select city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather); 作用的对象不同。 WHERE 子句作用于表和视图HAVING 子句作用于组。 WHERE 在分组和聚集计算之前选取输入行(因此,它控制哪些行进入聚集计算), 而 HAVING 在分组和聚集之后选取分组的行。因此,WHERE 子句不能包含聚集函数; 因为试图用聚集函数判断那些行输入给聚集运算是没有意义的。 相反,HAVING 子句总是包含聚集函数。(严格说来,你可以写不使用聚集的 HAVING 子句, 但这样做只是白费劲。同样的条件可以更有效地用于 WHERE 阶段。)

设计模式——工厂方法模式

工厂方法 也被称作:抽象构造 目的 工厂方法是一种创建设计模式,它在父类中提供了创建对象的接口但允许子类更改将要创建的对象的类型。 问题 假设您正在创建一个物流管理应用程序。你的应用的第一个版本只能处理卡车运输,所以你的大部分代码都存在于卡车类中。 不久之后,你的应用就变得非常受欢迎。每天你都会收到几十个海运公司的请求,要求将海运物流整合到应用程序中。 但是目前大多数代码都与卡车类耦合在一起。将船类添加到应用中需要对整个代码库进行修改。此外如果之后你决定在应用程序中添加另一种类型的交通工具,你可能需要再次进行所有这些更改。 结果您将得到非常糟糕的代码,其中充满了根据传输对象的类来切换应用程序行为的条件。 解决方案 工厂方法模式建议将直接对象构造调用(使用new操作符)替换为对特殊工厂方法的调用。对象仍然是通过new操作符创建的,但它是从工厂方法内部调用的。工厂方法返回的对象通常称为产品。 乍一看,这种更改可能毫无意义:我们只是将构造函数调用从程序的一个部分移到另一个部分。但是请考虑这一点:现在您可以在子类中重写工厂方法并更改由该方法创建的产品的类。 但是有一个轻微的限制:只有当这些产品具有公共的基类或接口时,子类才能返回不同类型的产品。此外,基类中的工厂方法应该将其返回类型声明为此接口。 例如,Truck和Ship类都应该实现Transport接口,该接口声明了一个名为deliver的方法。每个类都以不同的方式实现这个方法:卡车通过陆地运送货物,轮船通过海上运送货物。RoadLogistics类中的工厂方法返回卡车对象,而SeaLogistics类中的工厂方法返回船舶。 使用工厂方法的代码(通常称为客户端代码)看不到各种子类返回的实际产品之间的差异。客户将所有产品视为抽象运输。客户端知道所有传输对象都应该具有deliver方法,但它的具体工作方式对客户端并不重要。 结构 声明了Product这个接口,它对所有可以由创建者及其子类产生的对象都是通用的。Concrete Product是Product接口的不同实现。Creator类声明了返回新产品对象的工厂方法。这个方法的返回类型必须与产品接口匹配,这一点很重要。您可以将工厂方法声明为抽象的,以强制所有子类实现它们自己的方法版本。作为一种替代方法,基本工厂方法可以返回某种默认产品类型。请注意尽管名称如此,产品创建并不是创建者的主要职责。通常,创建者类已经拥有一些与产品相关的核心业务逻辑。工厂方法有助于将这种逻辑从具体的产品类中分离出来。这里有一个类比:一个大型软件开发公司可以有一个程序员培训部门。然而整个公司的主要职能仍然是编写代码而不是培养程序员。Concrete Creator重写基本工厂方法,因此它返回不同类型的产品。 注意工厂方法不必一直创建新实例。它还可以从缓存、对象池或其他源返回现有对象。 伪码 这个例子演示了如何使用Factory方法来创建跨平台的UI元素而不用将客户端代码耦合到具体的UI类。 基类Dialog使用不同的UI元素来呈现它的窗口。在不同的操作系统下,这些元素可能看起来有些不同但它们仍然应该保持一致的行为。Windows中的按钮在Linux中仍然是按钮。 当工厂方法开始发挥作用时,您不需要为每个操作系统重写Dialog类的逻辑。如果我们在基本的Dialog类中声明一个工厂方法来产生按钮,我们以后可以创建一个子类,从工厂方法返回windows样式的按钮。然后子类继承基类的大部分代码但是由于工厂方法,可以在屏幕上呈现windows外观的按钮。 要使此模式工作,基本Dialog类必须与抽象按钮一起工作:所有具体按钮都遵循的基类或接口。通过这种方式Dialog中的代码保持功能性,无论它处理的是哪种类型的按钮。 当然您也可以将此方法应用于其他UI元素。但是随着您向Dialog中添加的每一个新的工厂方法,您将更接近抽象工厂模式。不要害怕我们稍后会讨论这个模式。 // The creator class declares the factory method that must // return an object of a product class. The creator's subclasses // usually provide the implementation of this method. class Dialog is // The creator may also provide some default implementation // of the factory method.

从旋转向量到欧拉角的六种计算方法

利用SolvePNP解出旋转向量,旋转向量通过罗德里格斯公式解出旋转矩阵,然后通过下面六种公式计算即可,欧拉角有十二种,六种是相对于自身参考系,六种是相对于惯性参考系,这里是相对于惯性参考系的 Point3f RecToEulerXZY(Mat &R){ double Z = asin(-1R.at(1,2)); double X = asin(R.at(3,2) / cos(Z)); double Y = asin(R.at(1,3) / cos(Z)); return Point3f(X/PI180,Y/PI180,Z/PI180); } Point3f RecToEulerXYZ(Mat &R){ double Y = asin(1R.at(1,3)); double X = acos(R.at(3,3) / cos(Y)); double Z = asin(R.at(1,2) / (-1cos(Y))); return Point3f(X/PI180,Y/PI180,Z/PI180); } Point3f RecToEulerYXZ(Mat &R){ double X = asin(-1R.at(2,3)); double Z = acos(R.at(2,2) / cos(X)); double Y = asin(R.at(3,1) / (1cos(X))); return Point3f(X/PI180,Y/PI180,Z/PI180); } Point3f RecToEulerYZX(Mat &R){

互信息(Mutual Information)

Y 已知的情况下, 对 X时间熵(不确定性)降低的程度 : 联合概率分布 : 边缘概率分布 聚类属于无监督学习,数据没有标签,为了比较不同聚类模型的好坏,我们也需要一些定量的指标来进行评估。根式是否提供样本的标签信息,相关的指标可以分为以下两大类 1. 外部方法,外部方法指的是从外部提供数据的标签,比如通过专家认为定义类别,或者是本身就是有标签的数据,将标签拿掉之后做聚类 2. 内部方法,内部方法指的是不需要数据的标签,仅仅从聚类效果本身出发,而制定的一些指标 Normalized Mutual Information (NMI) 标准化互信息 理论上,互信息的值越大越好,可是其取值范围是没有上边界的。为了更好的比较不同聚类结果,提出了标准化互信息的概念,公式如下 将互信息的值归一化到0和1之间,这样就可以在不同数据集之间进行比较了。标准化互信息的值越接近1,聚类效果越好。 应用: 利用互信息比较不同的聚类结果_tyh70537的博客-CSDN博客 聚类模型评估指标之外部方法 - 腾讯云开发者社区-腾讯云 reference: 什么是「互信息」? - 知乎

MySQL4

目录 多表查询练习 事务 事务简介 事务操作 事务四大特性 并发事务问题 事务隔离级别 多表查询练习 -- ---------------------------------------> 多表查询案例 <---------------------------------- create table salgrade( grade int, losal int, hisal int ) comment '薪资等级表'; insert into salgrade values (1,0,3000); insert into salgrade values (2,3001,5000); insert into salgrade values (3,5001,8000); insert into salgrade values (4,8001,10000); insert into salgrade values (5,10001,15000); insert into salgrade values (6,15001,20000); insert into salgrade values (7,20001,25000); insert into salgrade values (8,25001,30000); 1. 查询员工的姓名、年龄、职位、部门信息 (隐式内连接) -- 表: emp , dept -- 连接条件: emp.

vue3.0实现前进刷新后退不刷新

前言 vue2.0实现前进刷新,后退缓存的例子有很多,但是vue3.0版本的没有找到,刚好有一个同学咨询这个问题,所以现在有空了写一篇文章来谈谈,怎么用vue3.0的轮子去实现前进刷新后退缓存。 场景 项目里有三个页面,分别为一级首页、二级列表页和三级详情页,从首页进入列表页刷新,从列表页进入详情页刷新,但是从详情页返回列表页不刷新,所以需要缓存的是二级列表页。 理论 通过keep-alive缓存组件;组件路由里定义一个变量isKeepAlive来控制组件的缓存;通过路由独享守卫根据条件修改缓存变量,选择性缓存组件。 实现 比方说三级页面分别为A、B和C,我们需要对B页面根据路由信息进行条件缓存 1、路由的配置 B组件的路由里定义一个变量isKeepAlive,同时还有一个路由独享守卫方法beforeEnter,当进入B页面时触发beforeEnter,我们判断如果是从C页面进入B页面,修改isKeepAlive为True使B页面缓存起来。 { path: '/a', name: 'A', component: ()=> import('../views/A.vue'), meta: { title: 'A Page' } }, { path: '/b', name: 'B', component: ()=> import('../views/B.vue'), meta: { title: 'B Page', isKeepAlive: false, }, // 路由独享守卫 beforeEnter: (to, from) => { to.meta.isKeepAlive = to.name==='B' && from.name=='C' ? true : false return true }, }, { path: '/c', name: 'C', component: ()=> import('../views/C.vue'), meta: { title: 'C Page' } } (注:路由的初始化略)

1. Python 的 print( )输出函数

1. Python 的 print( )输出函数 文章目录 1. Python 的 print( )输出函数1. 什么是print( )函数2. print( )函数的语法3. 英文输入法4. 敲下你的第一行代码5. print( )函数的4种用法5.1. 没有引号5.2 单引号5.3 双引号5.4 三引号 6. 总结7. 课后练习1. 编写代码用print( )函数输入数字:20222. 编写代码用print( )函数输出今天的日期:2022年7月30日3. 编写代码用print( )函数输出:We're family!4. 编写代码用print( )函数原样输出下面的内容,注意有换行:5. 下面那个选项可以输出结果`7`?6. 用单引号或双引号输出你的姓名: 1. 什么是print( )函数 print[prɪnt]:打印。 print的中文意思是打印、印刷,即将文字打印到纸张上。 print( )函数在Python中的作用是将print( )函数括号里的内容输出到屏幕上。 print( )函数:Python中的输出函数。 【功能】将print( )函数括号中的内容打印或输出到屏幕上。 2. print( )函数的语法 print( )函数由4部分组成: 1.函数名:print 2.英文小括号:( ) 3.英文引号(有4种情形) 4.要输出的内容 【示例】 【温馨提示1】print( )函数后必须紧跟( )小括号,( )小括号是这里的必要符号。 【温馨提示2】( ) 括号,引号等符号必须在英文输入法状态下输入。 【温馨提示3】引号根据要输出的内容决定是否使用。 3. 英文输入法 默认情况下,切换中英文输入法的快捷键是【shift】。

SQL后计算的利器

现代应用开发中,通常只用SQL实现简单的数据存取动作,而主要的计算过程和业务逻辑直接在应用程序中实现,主要原因在于: 过于复杂的SQL很难调试、编写、阅读、修改。SQL有方言特征,大量使用SQL后,会导致程序很难移植。架构方面要求业务逻辑在应用中实现,而不能依赖于数据库,否则耦合性过高。有些计算SQL不擅长,包括复杂的集合计算、有序计算、关联计算、多步骤计算,经常也需要移到数据库外实现。实现流程控制时,因为更难移植、耦合性更高、影响数据安全,不方便使用存储过程。 此外,还有涉及多数据库和非数据库的场景,也无法使用SQL完成计算任务,只能在外部完成。 这样,就要在应用程序中实现SQL后计算任务。 SQL返回的数据一般都是结构化数据,那么好的SQL后计算技术也要有方便的结构化数据对象,能够进一步计算和处理返回的数据;提供丰富的库函数,拥有不亚于SQL的计算能力;最好还能支持循环和判断语法以实现流程控制。特别地,SQL后计算技术要用在应用程序中,要易于被集成。 Java是重要的开发语言,但JDK提供的方法过于基础,虽然能实现SQL后计算,但开发效率很低。 ORM是Java中用来实现SQL后计算的常见方案。但几种较流行的ORM都缺乏专业的结构化数据对象,不支持动态数据结构。虽然可以利用Java实现流程控制,但难以进行灵活的计算。这些ORM技术的计算能力还远不如SQL,提供的计算函数非常有限,用Java硬写的现象仍然非常普遍。 Stream的链式编程比ORM的HQL更加面向对象,且有Lambda语法的加成,也常被用于SQL后计算,有些ORM还能直接生成Stream对象。但Stream同样没有专业的结构化数据对象,不支持动态数据结构。此外,Stream的计算能力也较差,甚至不如ORM,即使排序、分组汇总、关联这样的基础计算,也要辅以大量编码。 Kotlin基于JVM,且在链式编程和Lambda语法上对Stream进行了一系列改进,也可以用于SQL后计算。但因为编译型语言的底层,Kotlin只能对Stream小幅微调,重大缺点一个没少。 Python Pandas有较强大的结构化数据处理能力,有时也可以用于SQL后计算,但因为缺乏易用的接口,很难被Java集成,很少出现在正式项目中。 esProc SPL是更好的SQL后计算技术。 专业的结构化数据对象 SPL是JVM下的开源结构化数据计算引擎,内置专业的结构化数据对象序表,可以和数据库表/记录方便地互转,支持动态数据结构,提供了灵活易用的访问方法、维护方法、计算函数。序表专业性强,为数据计算和流程控制提供了有力的底层支撑,可以方便地实现SQL后计算中的各类业务逻辑。 直接的数据库交换方法,可以在数据库表(SQL结果集)和SPL序表之间进行互转。 比如,使用query函数执行SQL,生成单条记录序表: AB1=connect("orcl")//连接数据库2.query("select * from sales where orderid=?",201)=r=A1//查询单条记录3=db.close()//关闭数据库连接 如果SQL返回多条记录,则自动生成多条记录序表: =T=A1.query(“select * from salesR where SellerID=?”,10) 反过来也简单,用update函数就可以将序表记录批量地持久化到数据库。比如,原序表为T,经过多条件记录的增删改之后的序表为NT,将两者的变更结果统一写入数据库: =A1.update(NT:T,sales;ORDERID) 灵活的序表访问方法,可以按字段名或记录号自由地访问序表。 取序表的第3条记录:T(3) 取后3条记录:T.m([-1,-2,-3]) 取记录的字段值:T(3).Amount*0.05 取一列,返回集合:T.(Amount) 取几列,返回集合的集合:T.([CLIENT,AMOUNT]) 先按字段名取再按记录序号取:T.(AMOUNT)(3) 先按记录序号取再按字段名取:T(3).AMOUNT 易用的序表维护方法,可以对单条或多条记录记录进行统一的增删改操作。 追加记录:T.insert(200,“APPL”,10,2400.4,date(“2010-10-10”)) 修改记录:T(3).Amount = T(3). Amount*1.05 删除记录:T.delete(T.select(ORDERID==209 || ORDERID==208)) 丰富的序表计算函数,可进行完整的SQL式计算。 过滤:T.select(Amount>1000 && Amount<=3000 && like(Client,“bro”)) 排序:T.sort(-Client,Amount) 去重:T.id(Client) 汇总:T.max(Amount) 分组汇总后过滤: T.groups(year(OrderDate),Client; avg(Amount):amt).select(amt>2000) 关联:join(Orders:o,SellerId ; Employees:e,EId).groups(e.Dept; sum(o.Amount)) 交集:T1.id(Client) ^ T2.id(Client) TopN:T.top(-3;Amount)

使用 Haproxy + Nginx 实现高可用配置

使用 Haproxy + Nginx 实现高可用配置 一、基本介绍二、使用 Haproxy + Nginx 实现高可用配置1.安装 Nginx2.安装 Haproxy3.修改 Haproxy 配置文件4.启动 Haproxy 服务5.验证 一、基本介绍 Haproxy 是目前比较流行的一种集群调度工具,同类集群调度器工具有很多,如 LVS 和 Nginx。相比较而言,LVS 性能最好,但是搭建相对复杂;Nginx 的 upstream 模块虽然支持集群功能,但是对集群节点健康检查功能不强,性能没有 Haproxy 好。 Haproxy 可以提供高可用性、负载均衡以及基于 TCP 和 HTTP 应用的代理,并且支持虚拟主机配置。官方介绍 常见调度模式: 调度模式作用Round Robin(轮询)根据轮询分配访问请求,来实现负载均衡的效果(可以配置权重,以此增加调度概率)Least Connections(最小连接数)根据后端节点的连接数大小,来动态的分配前端请求(将请求优先分配到连接数小的节点上)Source Hashing(基于来源访问调度)用于一些有 Session 会话记录在服务器端的场景,可以基于来源 IP、Cookie 等进行集群调度。 二、使用 Haproxy + Nginx 实现高可用配置 准备工作: 主机名操作系统IP地址软件包Nginx-1CentOS7.4192.168.1.1nginx-1.21.0.tar.gzNginx-2CentOS7.4192.168.1.2nginx-1.21.0.tar.gzHaproxyCentOS7.4192.168.1.3haproxy-2.6.0.tar.gz 1.安装 Nginx 1)安装并启动 Nginx 服务 [root@Nginx-1 ~]# yum -y install pcre-devel zlib-devel popt-devel openssl-devel openssl [root@Nginx-1 ~]# wget http://www.nginx.org/download/nginx-1.21.0.tar.gz [root@Nginx-1 ~]# ls anaconda-ks.

基础复习——项目练习——计算器

布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#eeeeee" android:orientation="vertical" android:padding="5dp"> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="400dp" android:layout_height="wrap_content" android:gravity="center" android:text="简单计算器" android:textColor="#000000" android:textSize="20sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_result" android:layout_width="400dp" android:layout_height="wrap_content" android:background="#ffffff" android:gravity="right|bottom" android:lines="3" android:maxLines="3" android:scrollbars="vertical" android:text="0" android:textColor="#000000" android:textSize="25sp" /> </LinearLayout> <GridLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:columnCount="4"> <Button android:id="@+id/btn_cancel" android:layout_width="100dp" android:layout_height="75dp" android:gravity="center" android:text="CE" android:textColor="@color/black" android:textSize="30sp" /> <Button android:id="@+id/btn_divide" android:layout_width="100dp" android:layout_height="75dp" android:gravity="center" android:text="÷" android:textColor="@color/black" android:textSize="30sp" /> <Button android:id="@+id/btn_multiply" android:layout_width="100dp" android:layout_height="75dp" android:gravity="center" android:text="×" android:textColor="

MavSDK&Mavros学习笔记

MavSDK&Mavros学习笔记 Introduction · MAVSDK Guide (mavlink.io) GitHub - mavlink/MAVSDK源码 C++ · MAVSDK API reference paper) GitHub - mavlink/MAVSDK-docs单独给doc做了个仓库而且还得编译才能看的docs,使用gitbook建立 GitHub - JonasVautherin/px4-gazebo-headless: An unofficial Ubuntu-based container building and running PX4 SITL (Software In The Loop) through gazebo. MavSDK Mavlink是Pixhawk的通讯协议,mavlink很简单。而MavSDK可以发送Mavlink信号到飞控然后控制飞控的工具包,就不再需要自己写mavlink了。MAVSDK 是跨平台的:Linux、macOS、Windows、Android 和 iOS。多语言的c++,swift,python,java,Go,JavaScript,CSharp,Rust。在使用时可以通过串口或者tcp或者udp建立连接然后就可以控制Pixhawk飞控。在此之前可以在Ubuntu下建立Pix的源码然后并创建模拟器,然后蓝mavsdk控制模拟器里的飞机进行控制。 安装 realease版本安装(再下载一份源码看看) wget https://github.com/mavlink/MAVSDK/releases/download/v0.37.0/mavsdk_0.37.0_ubuntu20.04_amd64.deb sudo dpkg -i mavsdk_0.37.0_ubuntu20.04_amd64.deb 示例程序的使用 Build and Try Example git clone https://github.com/mavlink/MAVSDK.git --recursive cd MAVSDK cd examples cd takeoff_and_land/ cmake -Bbuild -H. cmake --build build -j4 Running an Example build/takeoff_and_land udp://:14540 模拟器安装 Setting up a Developer Environment (Toolchain) | PX4 User Guide

【ROS基础】map、odom、base_link、laser 的理解 及其 tf 树的理解

一、题目各个坐标系的含义 背景: 本文以 gmapping 为例,其中 map、odom、base_link、laser 均来自 gmapping 中的坐标系。这里的 gmapping 是指使用laser_scan_matcher包,在仅使用激光雷达、无需里程计的情况下跑 gmapping。 下图是执行rosrun rqt_tf_tree rqt_tf_tree的结果: map:可以理解为世界坐标系odom:机器人以为的世界坐标系base_link:机器人本体坐标系laser:激光雷达坐标系 二、对坐标系的理解 map:地图坐标系,顾名思义,一般设该坐标系为固定坐标系(fixed frame,rviz中的设置项),一般与机器人所在的世界坐标系一致。base_link:机器人本体坐标系,与机器人中心重合,原点一般为机器人的旋转中心。当然有些机器人(PR 2)是 base_footprint,其实意思差不多,base_footprint 坐标系原点为 base_link 原点在地面的投影,有些许区别(z值不同)。odom:里程计坐标系,这里要区分开odom topic,这是两个概念,一个是坐标系(本文),一个是根据编码器或者视觉等计算的里程计。但是两者也有关系,odom topic 转化的位姿矩阵是odom–>base_link的tf关系。这时可能会有疑问,odom 和 map 坐标系是不是重合的?可以很肯定地说,机器人起始运动位置这两者是重合的。但是,随着时间的推移是不重合的,而出现的偏差就是里程计的累积误差。那 map–>odom 的 tf 怎么得到?就是在一些校正传感器合作校正的 package 比如 amcl 会给出一个位置估计(localization),这可以得到 map–>base_link 的 tf,所以估计位置和里程计位置的偏差也就是 odom 与 map 的坐标系偏差。所以,如果你的 odom 计算没有错误,那么 map–>odom 的 tf 就是 0。laser:激光雷达的坐标系,与激光雷达的安装点有关,其与 base_link 的 tf 为固定的。 三、对于 map --> odom 举个例子 首先,我们制定机器人路径时,使用的必然是绝对坐标系。要完成这件事,机器人需要先知道自己在哪。它没有GPS,所以只能倒推——通过里程计。这也是为什么“没有偏移的话 odam 应该与 map 重合”,因为 odam 本来就是用来倒推 map 的。假设机器人终点定在了(8,5),初始时刻,map 的(8,5)和 odom 的(8,5)是重合的。odom 坐标系视角看运动过程:假设里程计告诉它,自原点启动起,它在 X 方向移动 2 ,Y 方向移动 5 ,运动描述为(+2,+5)。于是它就认为自己在 odom 坐标系下的(2,5)。反馈给 base_link,则 base_link 坐标系下,机器人需要运动(8,5) - (2,5) = (+6,+0)才能到达目标点(8,5)。而此时如果机器人按(+6,+0)运动完后,确实能到达odom下的终点(8,5),并开始以完成任务为由而沾沾自喜,殊不知,它并没有运动到真正的终点终点:map 坐标系下的(8,5)。map 坐标系看运动过程:然而实际上,因为里程计累计误差,它其实第一次运动到了(3,4)。但在 odom 中它在(2,5)。它理应运动(8,5)-(3,4) = (+5,+1)到达目标点,但它会运动(+6,+0),因为 odam 反馈给 base_link 后,目标在 base_link 坐标系下的(6,0)。其实到达的是 map 坐标系下的(9,4),并不能达到运动到 map 坐标系下目标点(8,5)的目的。机器人只能自以为是地认为自己运动到了odom 坐标系下的(8,5)就算万事大吉了。而这时,校正传感器又告诉它了,“我觉得你的里程计刚才 X 漏算了 0.

基于Python实现的五子棋游戏设计

一、设计目的: 1.1 课程设计教学目的 本课程设计是本专业的一门重要实践性教学环节。在学习了专业基础课和《Python程序设计》课程的基础上,本课程设计旨在加深对Python程序设计的认识,对Python语言及其语言生态有一个进一步的掌握和应用,学会运用Python标准库及外接相关库来解决实际问题的基本能力,培养和提高学生分析问题、解决问题的能力,尤其是提高学生使用Python为开发语言来进行问题描述、交流与思考的能力,为毕业设计和以后的工程实践打下良好的基础。 1.2 本课程设计具体目的 经过小组讨论分析,我们最终选择了“五子棋”作为本次课设主题。 五子棋起源于中国上古时期的传统黑白棋种之一。主要流行于华人和汉字文化圈的国家以及欧美一些地区,是世界上最古老的棋。古代五子棋棋盘与围棋棋盘是通用的,直到1931年,才出现所谓五子棋专用棋盘,为十五路(15×15)棋盘。现在人们压力日益增大,需要劳逸结合才能获得更高的工作效率,工作之余的娱乐对于每一个人来说必不可少。五子棋这种娱乐方式容易上手,老少皆宜,而且趣味横生,引人入胜;不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。 二、课程设计任务和要求 2.1 课程设计教学任务和要求 本次课程设计的主要任务是以Python为开发语言完成一个100~300行左右规模的程序项目开发。 课程设计的基本要求是:在课程设计的各个阶段严格、规范地完成相关的文档,例如在初期按时完成设计目的、设计要求、总体设计,在后期完成详细设计、调试与测试、设计总结等。要求能完成所选题目的主要功能,程序运行健壮、正确,代码要有详细注释,可读性好;所写文档结构合理、内容完整、叙述清晰。更高要求是:有创意、系统界面美观。 由于课程设计项目具有一定的综合性,鼓励具有不同特长和不同能力的学生互相组队。项目小组自己推荐一名组长,实行“组长负责制”。组长组织组员进行项目选题、任务分配、方案确定、方案设计、系统调试测试,组员分工协作。小组成员开展项目讨论,互相支持,形成协作意识。 2.2 本课程设计具体任务和要求 有图形界面,能够用鼠标进行操作。 能够进行五子棋游戏的基本操作,即玩家轮流落子。 能够对游戏结果进行正确的判定。 能够实现悔棋及认输等附加功能。 各项功能的展示与应用直观明了。 输出必要的提示信息让玩家更好地进行游戏。 三、总体设计: 基于Python的标准GUI库tkinter快速创建GUI应用程序。 运行程序提示可开始游戏。人人对战,二人轮流落子。界面显示提示信息当点轮到哪一方落子。先有五子“—”或“|”或“/”或“\”连成一线的玩家获胜。若棋盘中棋子已满,玩家均为完成五子相连则判定为平局。当黑方获胜或白方获胜或平局时及时作出判定,并弹出提示框,告知玩家当前对局结束。 3.1 小组成员及任务分配情况 组员:吴佳丽余叶钰刘璐瑶 任务分配: :负责玩家操作模块设计,包括落子、悔棋及认输。 :负责游戏的可视化设计,包括游戏界面设计及棋盘设计。 棋盘设计部分包括运行程序开始游戏及重新开局时初始化棋盘。 :负责判定游戏结果即玩家胜负或平局判定 3.2 程序功能图 3.3 整体流程图 四、设计实现 4.1 最终实验结果 游戏主界面 启动程序运行游戏,弹出提示框,提示玩家游戏开始,黑方先进行落子。玩家可点击棋盘无棋子处进行落子。或点击“开局”、“悔棋”、“认输”按钮可重新开局或悔棋或认输。当点击“开局/重新开局”按钮时,清空棋盘中的棋子,展示处与启动程序相同的游戏界面。界面中间“黑方”与“落子”二处文字为游戏进行中的提示信息,表示当前轮到黑方进行棋子放置。轮到白方落子时会“黑方”将自动更改为“白方”,“白方”二字以白色显示。如图4-1所示。 玩家获胜后界面 如图4-2所示,若有一方玩家存在“—”或“|”或“/”或“\”五子相连,该玩家取得该局游戏胜利。以图中所示情况——黑方“/”五子相连为例,说明玩家取胜结果。通过黄色线条将黑方连成一线的五颗棋子相连接,此时界面中间提示信息改为“黑方获胜”,“获胜”二字以红色显示。并弹出消息提示框,提示玩家游戏结束黑方完成五子相连,取得胜利。若此时点击悔棋按钮,将提示玩家此时不能悔棋。如图4-3所示;点击认输按钮,将提示玩家点击开局开始游戏,如图4-4所示。 平局情况 当玩家双方都没有完成五子连线,且棋盘中所有棋格都有棋子放置即无处置放棋子时,判定为平局。 为更方便展示,将棋盘改为5*5大小。如图4-5所示,中间提示文字变更为绿色字样“平局??!”,同时弹出消息提示框,提示玩家当前对局结束,双方达成平局。此时游戏结束,玩家不可再悔棋或认输,若玩家点击悔棋或认输按钮,效果与有一方玩家获胜时相同。即游戏界面不做改变,弹出消息提示框,该消息提示框与图4-3、图4-4中消息提示框相同,不再重复展示。 玩家认输 在一局游戏过程中,若玩家首次点击认输按钮。棋盘不做改变,游戏界面中间文字“落子”变为“认输”如图4-6所示。此时游戏结束,玩家不可再悔棋或认输,若玩家点击悔棋或认输按钮,效果与有一方玩家获胜时相同。即游戏界面不做改变,弹出消息提示框,该消息提示框与图4-3、图4-4中消息提示框相同,不再重复展示。 玩家悔棋 游戏过程中,若一个回合内该玩家首次进行悔棋,取回该玩家刚放置到棋盘上的棋子,并将中间的提示信息“某方落子”改回到该玩家。以黑方悔棋为例,悔棋前及悔棋后游戏部分界面分别如图4-7、图4-8所示。若该玩家在一个回合内已经进行过悔棋操作,再次点击悔棋按钮,则不改变游戏界面及棋盘,但回弹出提示框此时不能悔棋,该消息提示框及提示信息与获胜时点击悔棋按钮,即图4-4中的提示框相同。 4.2 实验结果评价 窗体界面直观明了,游戏过程中有适当的提示信息有助于玩家更好的进行游戏。同时窗体的颜色搭配即窗体大小设置合适。玩家不会因游戏界面颜色冲击或棋盘、文字信息等过大过小产生疲劳。程序能对游戏结果进行正确的判定,悔棋及认输这两个附加功能也能够实现。课程设计最初定下的功能和要求均能实现。在此基础上,玩家完成五子相连时用黄色线条标记,让玩家能有更好的体验。还加上了一个回合内只允许玩家各悔棋一次,增加挑战,让游戏更加有趣。 小组超额完成了最初想要实现的功能和要求,所以我们给自己评价为优秀! 当然这个小程序也很多不足之处。例如没有标记出最后放置的棋子,玩家悔棋后也没有标记出悔棋前的棋子等等。我们往后也应努力学习,做的更好。 五、详细设计 5.1 模块设计 所负责部分大致可分为三大模块。首先,判断游戏胜负的四种情况,即横、竖、斜方向五子一线;其次,判断棋盘是否可以继续下棋,即是否平局;最后,判断玩家输赢,并弹出提示框。 5.2 程序流程图 5.3 具体算法分析 引用tkinter库 from tkinter import* from tkinter import messagebox Tkinter库:

Qt Mac下局域网文件夹共享

1、共享MacOS系统相应的文件夹; 2、查看MacOS的IP:192.168.3 *1.1*4; 3、在Windows下通过网上邻居的方式://192.168.3 *1.1*4/文件夹目录(pwd获取),直接访问苹果系统共享文件夹; 4、映射“网络驱动器”,对共享文件夹映射成网络驱动器(Z); 5、在windows下,通过网络盘符访问MacOS下的工程; 6、进入Linux,使用mout命令访问macOS下的共享文件夹;打开项目,将对应项目设置成“活动项目”。 mount -t cifs //192.168.31.14/qt -o username=Kenny,password=mypassword,nounix,sec=ntlmssp 切换系统如果发现代码没有同步,reload一下。

【ROS】Ros官方文档学习笔记

Ros学习笔记 官方学习网址https://wiki.ros.org/ROS/Tutorials 如何阅读ROSwiki的网页https://wiki.ros.org/ROS/Tutorials/NavigatingTheWiki 环境搭建 printenv | grep ROS # 查看环境中ros有关的变量 source /opt/ros/melodic/setup.bash # 利用source bash建立环境,需要在打开的每个新 shell 上运行此命令才能访问 ROS 命令,除非将此行添加到 .bashrc或者zshrc。 echo $ROS_PACKAGE_PATH# 应得到/home/youruser/catkin_ws/src:/opt/ros/kinetic/share 工作区搭建 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/ catkin_make # 在“src”文件夹中创建一个 CMakeLists.txt 链接。当前目录应该有一个“build构建”和“devel开发”文件夹。在“devel”文件夹在有几个 setup.*sh source devel/setup.bash # source devel里的bash文件可以覆盖当前的黄静。 创建包 包(package):包是ROS代码的软件组织单元。每个包都可以包含库、可执行文件、脚本或其他工件。 清单 (package.xml):清单是对包的描述。它用于定义包之间的依赖关系并捕获有关包的元信息,如版本、维护者、许可证等… ros的文件系统管理工具 rospack rospack find [package_name] #find命令返回package地址 rospack depends1 [package_name] #查看package的一级依赖包,在xml里也会显示 rospack depends [package_name] #查看package的所有级依赖包,在xml里不会显示 roscd roscd [package_name]/subdir # 跳转到package所在的地址或者下面的subdir echo $ROS_PACKAGE_PATH # 所有的package都在这里,找不到就没有 roscd log #ROS 存储日志文件的文件夹。如果还没有运行任何 ROS 程序,这将roscd log指出它尚不存在 roscd roscpp_tut >> 摁一下TAB >> roscd roscpp_tutorials/#Tab Completion包名补全 rosls rosls [package_name]/subdir#返回package地址下目录 ros包的建立和安装 ros包的文件架构 workspace_folder/ #WORKSPACE src/ #SOURCE SPACE。package在src里 CMakeLists.

【python】print函数的用法示例与讲解

python学习 本文以python3为核心 文章目录 python学习一、有用的知识点1、print 输出不换行2、f"{}"的用法 二、格式规范1.字符串输出格式2.浮点数输出格式3.整数类型输出格式 一、有用的知识点 1、print 输出不换行 代码示例: a = "早晨" b = "下午" print(a) print(b) print(">>>不换行操作<<<") print(a,end="") print(b) 输出如下: 早晨 下午 >>>不换行操作<<< 早晨下午 若想使我们print后的输出不自动补充换行符,那么应该在结尾加上end=“” 例如:print(a,end=“”) 则输出 a 并且不换行 (还有其他的格式写法,但本人常用的方法就是这种,故此列出) 2、f"{}"的用法 该方法很快捷地放入我们想要的内容,很符合python语言的风格 代码示例: a = "早晨" b = "下午" c = 2 print(f"从{a}起床到{b},我一共只吃了{c}个苹果") 输出如下: 从早晨起床到下午,我一共只吃了2个苹果 注意点:不要忘记加上 f ,否侧输出的是单纯的字符串,不会进行变量替换 二、格式规范 1.字符串输出格式 代码示例: a = "早晨" b = "下午" print('早晨') print("早晨") print(a) print("%s,我起床" % a) print("直到第二天%s,我才睡觉,而到了那天%s,我才起床" %(a,b)) print(f"{a}和{b}") 输出如下:

AI 自动写代码插件 Copilot(副驾驶员)

AI 自动写代码插件 Copilot 提示:Copilot单词直译过来就是副驾驶员的意思。 介绍:本质上就是基于GitHub开源的亿级别的代码,训练AI模型,自动生成代码。 就是数据量(GitHub的数据量就很大!)能够决定你AI模型精度的上线。 安装 copilot官网:https://copilot.github.com/ 需要给自己的GitHub账号申请。 支持VS Code 和 JetBains全家桶,去setting里面下载对应的插件就可以。 插件名字就叫做 GitHub Copilot 。 功能介绍 自动补全代码。根据注释自动生成代码。自动推断,生成类似的代码。自动生成测试。自动生成代码建议,提供选择。 Copilot生成代码的时候会检索上下文的代码,帮你自动生成一些相关测试数据等等。 注释 输入单例模式。enter =》 tab 进而生成代码,如下的一种双检索的模式。 单例模式 懒汉式 双检索: 但是输入其他设计模式,也仅仅会生成一些相关代码,并不是真正自己要使用的代码。 一些常用逻辑还是可以精确声明,像用户名校验,省份证校验,密码校验等。并且会牵扯到上下文代码的一些逻辑,使用这个打打下手感觉还可以。 如果作为一个Java程序员的话,使用Copilot写代码,确实能省不少时间。 像正常MVC模式中,可以根据注释快速生成代码,并且可以根据一些逻辑帮住我们自动补全其他逻辑。 当然不仅仅MVC模式,像SSM,SpringBoot项目代码也是可以生成补全的,这一点还是很不错啊。 不过,如果在公司,最好还是慎用,大多数公司都是禁用代码生成器的,而且GitHub AI生成的代码,很多情况是不准确的。不过,平时学习,写一些自己的项目还是挺好用的。 可以把它当作工具类使用还是不错的,像日期转换,对象转换等等,生成出来的代码还是很准确的。 总结来说,平时学习,写写项目,可以用用,节约节约时间。但是,工作中慎用!

编程语言:类型系统的本质

0. 引子 我一直对编写更好的代码有浓厚的兴趣。如果你能真正理解什么是抽象,什么是具象,就能理解为什么现代编程语言中,接口和函数类型为什么那么普遍存在了。在使用函数式语言进行编程后,就能够很清晰地理解为什么随着时间的推移,更主流的语言开始采用函数式语言中的一些被认为理所当然的特性。 我将多年间学习类型系统和编程语言开发的经验汇聚起来,加以提炼,并辅以现实世界的应用,撰写了这篇文章。本文脉络如下: 概述:什么是类型?为什么要引入类型的概念? 编程语言中的基本类型 类型组合 OOP与接口类型 函数类型 函子(Functor)和单子(Monad) 1. 概述:什么是类型?为什么要引入类型的概念? 类型系统设计的理论与日常生产软件之间存在直接的联系。这并不是一个革命性的发现:复杂的类型系统特性之所以存在,就是为了解决现实世界的问题。 本节介绍类型和类型系统,讨论它们为什么存在以及为什么有用。我们将讨论类型系统的类型,并解释类型强度、静态类型和动态类型。 两个术语:类型、类型系统 类型 类型是对数据做的一种分类,定义了能够对数据执行的操作、数据的意义,以及允许数据接受的值的集合。编译器和运行时会检查类型,以确保数据的完整性,实施访问限制,以及按照开发人员的意图来解释数据。 类型系统 类型系统是一组规则,为编程语言的元素分配和实施类型。这些元素可以是变量、函数和其他高级结构。类型系统通过两种方式分配类型:程序员在代码中指定类型,或者类型系统根据上下文,隐式推断出某个元素的类型。类型系统允许在类型之间进行某些转换,而阻止其他类型的转换。 从复杂系统的约束开始 “系统”一词由来已久,在古希腊是指复杂事物的总体。到近代,一些科学家和哲学家常用系统一词来表示复杂的具有一定结构的整体。在宏观世界和微观世界,从基本粒子到宇宙,从细胞到人类社会,从动植物到社会组织,无一不是系统的存在方式。 控制论(维纳,1948,《控制论(或关于在动物和机器中控制和通讯的科学)》)告诉我们,负反馈就是系统稳定的机制,一个组织系统之所以能够受到干扰后能迅速排除偏差恢复恒定的能力,关键在于存在着“负反馈调节”机制:系统必须有一种装置,来测量受干扰的变量和维持有机体生存所必需的恒值之间的差别。例如,一个实时系统复杂性任务的约束,包括时间约束、资源约束、执行顺序约束和性能约束。 类型检查:类型检查确保程序遵守类型系统的规则。编译器在转换代码时进行类型检查,而运行时在执行代码时进行类型检查。编译器中负责实施类型规则的组件叫作类型检查器。如果类型检查失败,则意味着程序没有遵守类型系统的规则,此时程序将会编译失败,或者发生运行时错误。“遵守类型系统规则的程序相当于一个逻辑证明。” 类型系统,就是复杂软件系统的“负反馈调节器”。通过一套类型规范,加上编译监控和测试机制,来实现软件系统的数据抽象和运行时数据处理的安全。 随着软件变得越来越复杂,我们越来越需要保证软件能够正确运行。通过监控和测试,能够说明在给定特定输入时,软件在特定时刻的行为是符合规定的。但类型为我们提供了更加一般性的证明,说明无论给定什么输入,代码都将按照规定运行。 例如,将一个值标记为 const,或者将一个成员变量标记为 private,类型检查将强制限制实施其他许多安全属性。 从 01 到现实世界对象模型 类型为数据赋予了意义。类型还限制了一个变量可以接受的有效值的集合。 在低层的硬件和机器代码级别,程序逻辑(代码)及其操作的数据是用位来表示的。在这个级别,代码和数据没有区别,所以当系统误将代码当成数据,或者将数据当成代码时,就很容易发生错误。这些错误可能导致系统崩溃,也可能导致严重的安全漏洞,攻击者利用这些漏洞,让系统把他们的输入数据作为代码执行。 通过对编程语言的研究,人们正在设计出越来越强大的类型系统(例如,Elm或Idris语言的类型系统)。Haskell正变得越来越受欢迎。同时,在动态类型语言中添加编译时类型检查的工作也在推进中:Python添加了对类型提示的支持,而TypeScript这种语言纯粹是为了在JavaScript中添加编译时类型检查而创建的。 显然,为代码添加类型是很有价值的,利用编程语言提供的类型系统的特性,可以编写出更好、更安全的代码。 编程语言中的数据类型 类型系统是每个编程语言都会有的基本概念。 Lisp 数据类型可分类为: 标量类型 - 例如,数字类型,字符,符号等。 -数据结构 - 例如,列表,向量,比特向量和字符串。 C 语言的类型系统分为:基本类型和复合类型。基本类型又可以细分为:整型数值类型和浮点数数值类型,不同类型所占用的内存长度不相同: 整型数值基本类型 char 占用一个字节 short 占用两个字节 int 目前基本都是4字节 long int (可以简写为 long) (32位系统是4字节,64位系统是8字节) long long int ( 可以简写为long long) 占用8节字 浮点数数值基本类型 float 占用4字节 (单精度)

11、Redis实现关注、取消关注以及关注和粉丝列表

实现关注、取消关注 value的数据类型时zset,有序集合,按照关注的时间排序 followee:userId:entityType -> zset(entityId,now) 某个用户关注的实体(实体包括帖子、评论、用户),按照实体分别存 follower:entityType:entityId -> zset(userId,now) 某个实体拥有的粉丝(实体包括帖子、评论、用户) 这个功能时异步请求 1、RedisKeyUtil private static final String PREFIX_FOLLOWEE = "followee"; private static final String PREFIX_FOLLOWER = "follower"; // 某个用户关注的实体(实体包括帖子、用户) // followee:userId:entityType -> zset(entityId,now) public static String getFolloweeKey(int userId, int entityType) { return PREFIX_FOLLOWEE + SPLIT + userId + SPLIT + entityType; } // 某个实体拥有的粉丝(实体包括帖子、用户) // follower:entityType:entityId -> zset(userId,now) public static String getFollowerKey(int entityType, int entityId) { return PREFIX_FOLLOWER + SPLIT + entityType + SPLIT + entityId; } 2、FollowService @Service public class FollowService { @Autowired private RedisTemplate redisTemplate; public void follow(int userId, int entityType, int entityId) { redisTemplate.

C语言之加法程序

笔者将介绍以下两种C语言编程的初级加法代码 1. #define_CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { int num1=0; int num2=0; int sum=0; scanf("%d%d",&num1,&num2); sum=num1+num2; printf("sum=%d\n",sum); return 0; } 这种写法是我个人比较喜欢的一种写法,相较于下一种,该写法更加灵活,在输出界面可以自己输入数值进行加法,互动性更强 2. #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> add(int x,int y) {int z=x+y; return z; } int main() { int num1=500; int num2=20; int sum=0; sum=add(num1,num2); printf("sum=%d\n",sum); return 0; } 该函数的特点在于需要自己去定义一个add函数,逻辑性较强,运行后可直接输出结果520,但缺乏互动性。 我将会在下一篇文章中对两种代码进行详细的分析,期待你们的学习和指误。 欢迎大家在评论区留下你们喜欢的加法代码!

vscode 工作区配置插件 配置不同工作环境

背景: 公司中老项目都是用的vue2,新项目用的vue3,在vscode中,vue2用的插件是Vetur,vue3用的插件是Vue Language Features (Volar),这就导致打开vue2的时候需要禁用Volar,打开vue3的时候需要禁用Vetur。而vscode提供了工作区的概念,可以给每个工作区配置不用的插件,形成不同的工作环境。 使用: 1. 打开文件夹 2. 左上角【文件】-【将工作区另存为】-选择合适位置-【保存】 3. 左上角【文件】-【首选项】-【设置】可以看到工作区是否创建成功 4. 找到想要配置的插件,禁用/启用到对应工作区即可 建好工作区后,以后同配置的文件夹,可以直接拖到对应的工作区,即可享受相同的配置。

STM32CubeMX配置生成FreeRTOS项目

文章目录 1. 安装STM32CubeMX软件1.1 下载安装1.2 安装要用到的芯片软件包 2. 配置FreeRTOS项目2.1 创建工程2.2 配置SYS2.3 配置RCC2.4 配置系统运行时钟2.5 配置UART1串口作为调试代码2.6 配置一个LED引脚的GPIO2.7 使能FreeRTOS组件 3. 生成代码4. 测试生成的工程代码 1. 安装STM32CubeMX软件 ST公司现在出了一套封装更好的HAL库,并且搭配STM32CubeMX软件自动生成初始化外设相关的代码,再也不用自己去写初始化相关得代码了,非常方便。 1.1 下载安装 STM32CubeMX是ST公司的免费软件,我们去ST的官网: https://www.st.com/en/development-tools/stm32cubemx.html 找到下面获取软件的界面,下载相应版本即可 注意:STM32CubeMX是JAVA写的,所以需要安装JAVA的运行环境,怎么安装JAVA运行环境自己网上找一下。 1.2 安装要用到的芯片软件包 安装完CubeMX后,打开界面如下,然后点击Install/Remove,如下: 我们先安装要用到的一些芯片软件包,因为我使用的事STM32F407ZGT6芯片,所以我选择的是F4软件包。如下: 2. 配置FreeRTOS项目 2.1 创建工程 然后进入到选择芯片型号,这里我用的是STM32F407ZGT6芯片。 2.2 配置SYS 2.3 配置RCC 我们使能外部晶振。注意:如果是没有使用到外部低速晶振的话,就不要使能外部低速晶振了,否则程序上电会死在时钟设置相关得代码那里。 2.4 配置系统运行时钟 我们配置玩RCC外设之后,就可以去配置系统的各个外设运行的时钟了。如下图,外部晶振我的的开发板是8MHz,所以输入晶振要选中8。其他的配置其实按照软件的提示进行设置即可,如果配置的运行频率超过了芯片的最大运行频率,软件会高亮提示的。 2.5 配置UART1串口作为调试代码 在右侧Connectivity栏,然后选中USART1,然后配置如下界面: 因为我们使用中断方式接收串口数据,所以还需要使能USATR1的中断,和配置中断优先级: 2.6 配置一个LED引脚的GPIO 我们配置一个控制LED亮灭的GPIO引脚,用于测试程序。我的开发板上的LED引脚是PE3,所以我配置这个引脚。 2.7 使能FreeRTOS组件 CubeMX可以直接使能FreeRTOS组件,这里我选择V1版本,V1、V2具体有什么区别我也不是很了解。 然后其他的FreeRTOS相关的配置参数,就全部默认配置就行,后面需要的时候再改。 3. 生成代码 生成代码前,先配置下相关的 Project Manager 选项。 配置代码的文件组织结构,把下面的选项勾上,这样生成的每一个外设的代码都会有对应的 .c/.h 文件,不勾上会把所有代码都添加到main文件上。然后就点击右上角生成代码即可。 说明:CubeMX生成的FreeRTOS代码,他把FreeRTOS的所有操作又封装了一遍,在文件cmsis_os.c文件中。我们使用了ST封装的FreeRTOS接口的话,就算我们以后的代码使用了不同版本的FreeRTOS,那么用户代码也不用修改。 4. 测试生成的工程代码 生成代码后,在freertos.c文件中,CubeMX会生成一个默认的任务,我们去该任务的任务函数添加串口打印和LED亮灭的代码,如下: void StartDefaultTask(void const * argument) { /* USER CODE BEGIN StartDefaultTask */ uint8_t str[] = "

电脑蓝屏按哪三个键恢复?怎么修复蓝屏问题

最近有人在咨询小编,说电脑蓝屏按哪三个键恢复?我一脸懵逼,还有这操作么?其实如果发你的电脑一开机就蓝屏,一开机就蓝屏,没办法进入系统的话,那么你就需要用另外的方法进去系统了,而不是按三个键恢复,下面我们一起来看看。 有硬件故障,也有软件故障 首先我们要先解决掉无法进入系统,一直蓝屏的处境。 步骤1、如果发现开机蓝屏时,可能以通过开机第一屏时迅速不停按动F8键,记住哈,就是按f8,而不是三个键!在屏幕出来的界面选择[安全模式]并按[Enter]进入安全模式。 步骤2、如果能进安全模式,说明软件有冲突或系统故障。这时只需重装个系统就行了。 当然,如果你不想重装系统,那么就直接去电脑修复精灵下载个蓝屏修复工具,利用这个蓝屏工具来修复相关的蓝屏错误。 步骤3、如果进安全模式也蓝屏,可能是硬件有问题,这时就要打开机箱检查硬件了。 步骤4、打开机箱如果有很多灰尘,有时蓝屏就是因为灰尘引起的,所以我们就先对机 步骤5、如果清过灰尘开机还蓝屏的话,下一步再取出内存,用橡皮擦擦一下内存的金手机。 如果以上方法还不能解决电脑一开机就蓝屏的问题,有可能内存本身或都硬盘有问题,建议拿到更专业的电脑维修机构去检修。

Java面试复习大纲2.0(持续更新)

Java面试复习大纲2.0(持续更新) 2018-02-26奋斗蒙 Java帮帮 面试复习大纲(Java帮帮总结) 【人事】31道,不准备就掉坑的问题 【简历】1年简历模板一 【简历】2年简历模板一 【简历】3年简历模板一 【面试】面试练习题大集合(持续更新中…欢迎问题投稿) 更多整理的问题点击公众号中间的“简历/面试”菜单即可 面试+简历+沟通+工作流程+谈判_汇总 想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在面试之前到底需要准备哪些东西呢?本文陈列的这些内容既可以作为个人简历中的内容,也可以作为面试的时候跟面试官聊的东西,你可以把这些内容写到你的简历中,当然更需要的是你在面试的时候向面试官展示这些专业技能。相信此文对正在寻觅Java程序员(Java工程师)职位的freshman以及希望成为中高级Java开发者的junior都会有所帮助。 专业技能 1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型] 2.熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。 3.对Spring的IoC容器和AOP原理有深入了解,熟练的运用Spring框架管理各种Web组件及其依赖关系,熟练的使用Spring进行事务、日志、安全性等的管理,有使用Spring MVC作为表示层技术以及使用Spring提供的持久化支持进行Web项目开发的经验,熟悉Spring对其他框架的整合。 4.熟练的使用Hibernate、MyBatis等ORM框架,熟悉Hibernate和MyBatis的核心API,对Hibernate的关联映射、继承映射、组件映射、缓存机制、事务管理以及性能调优等有深入的理解。 5.熟练的使用HTML、CSS和JavaScript进行Web前端开发,熟悉jQuery和Bootstrap,对Ajax技术在Web项目中的应用有深入理解,有使用前端MVC框架(AngularJS)和JavaScript模板引擎(HandleBars)进行项目开发的经验。 6.熟悉常用的关系型数据库产品(MySQL、Oracle),熟练的使用SQL和PL/SQL进行数据库编程。 7.熟悉面向对象的设计原则,对GoF设计模式和企业应用架构模式有深入的了解和实际开发的相关经验,熟练的使用UML进行面向对象的分析和设计,有TDD(测试驱动开发)和DDD(领域驱动设计)的经验。 8.熟悉Apache、NginX、Tomcat、WildFly、Weblogic等Web服务器和应用服务器的使用,熟悉多种服务器整合、集群和负载均衡的配置。 9.熟练的使用产品原型工具Axure,熟练的使用设计建模工具PowerDesigner和Enterprise Architect,熟练的使用Java开发环境Eclipse和IntelliJ,熟练的使用前端开发环境WebStorm,熟练的使用软件版本控制工具SVN和Git,熟练的使用项目构建和管理工具Maven和Gradle。 说明:上面罗列的这些东西并不是每一项你都要烂熟于心,根据企业招聘的具体要求可以做相应的有针对性的准备。我个人觉得前6项应该是最低要求,是作为一个Java开发者必须要具备的专业技能。 项目经验 实际情况为主,适自己能力而定。 项目介绍 本系统是X委托Y开发的用于Z的系统,系统包括A、B、C、D等模块。系统使用了Java企业级开发的开源框架E以及前端技术F。表示层运用了G架构,使用H作为视图I作为控制器并实现了REST风格的请求;业务逻辑层运用了J模式,并通过K实现事务、日志和安全性等功能,通过L实现缓存服务;持久层使用了M封装CRUD操作,底层使用N实现数据存取。整个项目采用了P开发模型。 说明:上面的描述中,E通常指Spring(Java企业级开发的一站式选择);F最有可能是jQuery库及其插件或者是Bootstrap框架,当然如果要构建单页应用(SPA)最佳的方案是前端MVC框架(如AngularJS)和JavaScript模板引擎(如HandleBars);G显然是MVC(模型-视图-控制),最有可能的实现框架是Spring MVC,除此之外还有Struts 2、JSF以及Apache为JSF提供的MyFaces实现,可以使用JSP作为MVC中的V,也可使用模板引擎(如Freemarker和Velocity)来生成视图,还可以是各种文档或报表(如Excel和PDF等),而Servlet和自定义的控制器是MVC中的C,当然Spring MVC中提供了作为前端控制器的DispatcherServlet;J通常是事务脚本,K应该是AOP(面向切面编程)技术,L目前广泛使用的有memcached和Redis;M的选择方案很多,最有可能的是Hibernate和MyBatis,也可以两种技术同时运用,但通常是将增删改交给Hibernate来处理,而复杂的查询则由MyBatis完成,此外TopLink、jOOQ也是优秀的持久层解决方案;底层的数据存取传统上是使用关系型数据库,可以是MySQL、Oracle、SQLServer、DB2等,随着大数据时代的来临,也可以采用NoSQL(如MongoDB、MemBase、BigTable等)和其他大数据存取方案(如GFS、HDFS等);项目的开发模型P可以是瀑布模型、快速原型模型、增量模型、螺旋模型、喷泉模型、RAD模型等。 项目开发流程 1.可行性分析>>>可行性分析报告/项目开发计划书 2.需求分析>>>需求规格说明书 oOOAD(用例图、时序图、活动图) o界面原型:帮助理解需求、业务层设计时推导事务脚本 3.设计>>>概要设计说明书/详细设计说明书 o抽取业务实体(领域对象):类图、E-R图(概念设计阶段) o分层架构:确定各层的技术实现方案(具体到使用的框架、数据库服务器、应用服务器等)。 o业务层设计:事务脚本模式(事务:用户发送一次请求就是一个事务;脚本:一个方法或一个函数;事务脚本:把一次请求封装为一个方法或一个函数;事务脚本模式:一个事务开始于脚本的打开,终止于脚本的关闭)。 o业务层涉及的对象有三种类型:事务脚本类(封装了业务的流程)、数据访问对象(DAO,封装了持久化操作)、数据传输对象(DTO,封装了失血/贫血领域对象),三者之间的关系是事务脚本类组合(聚合)数据访问对象,这二者都依赖了数据传输对象 o正向工程(UML类图生成Java代码)和逆向工程(Java代码生成UML类图) o数据库物理设计(ER图转换成表间关系图、建库和建表、使用工具插入测试数据) 4.编码 5.测试>>>测试报告/缺陷报告 o单元测试:对软件中的最小可测试单元进行检查和验证,在Java中是对类中的方法进行测试,可以使用JUnit工具来实施。 o集成测试:集成测试也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求组装成为子系统进行测试。 o系统测试:将已经确认的软件、硬件、外设、网络等元素结合在一起,进行信息系统的各种组装测试和确认测试,系统测试是针对整个产品系统进行的测试,目的是验证系统是否满足了需求规格的定义,找出与需求规格不符或与之矛盾的地方,从而提出更加完善的方案。 o验收测试:在软件产品完成了单元测试、集成测试和系统测试之后,产品发布之前所进行的软件测试活动。它是技术测试的最后一个阶段,也称为交付测试。验收测试的目的是确保软件准备就绪,并且可以让最终用户将其用于执行软件的既定功能和任务。 6.交付和维护>>>用户手册/操作手册 项目管理 ·版本控制:CVS/SVN/Git ·自动构建:Ant/Maven/Ivy/Gradle ·持续集成:Hudson/Jenkins 系统架构 ·负载均衡服务器:F5、A10 ·应用服务器: §HTTP服务器:Apache、NginX(HTTP、反向代理、邮件代理服务器) §Servlet容器:Tomcat、Resin §EJB容器:WildFly(JBoss Application Server)、GlassFish、Weblogic、Websphere ·数据库服务器:MySQL、Oracle 第三方工具(插件)应用

Ubuntu安装spconv1.2.1

主要参考ubuntu18.04安装OpenPCDet这篇文章安装成功 . 但是编译的时候遇到的下面这个问题, 需要修改spconv/include/spconv/nms.h的加上 #include <iostream> 重新编译后在dist目录下可以找到编译好的安装包,直接pip install这个安装包即可.

如何选择合适的自动化测试工具?

自动化测试是高质量软件交付领域中最重要的实践之一。在今天的敏捷开发方法中,几乎任一软件开发过程都需要在开发阶段的某个时候进行自动化测试,以加速回归测试的工作。自动化测试工具可以帮助测试人员以及整个团队专注于自动化工具无法处理的各自任务,但困难的部分就是选择自动化工具。事实上,测试人员最常见的问题就是,如何选择适宜的自动化测试工具? 在本文中,我们将详细讨论在选择自动化测试工具时如何进行选择。但在继续之前,让我们强调一下自动化测试工具的重要性。 选择最佳自动化测试工具的重要性 如果想对项目进行成功的自动化测试,识别正确的自动化工具至关重要。为项目自动化测试选择合适的工具是获得项目所需结果的最佳方法之一。让我们以web应用程序开发为例,更好地了解自动化测试工具的重要性。 假设您正在为业务开发一个网站。现在,在一开始,如果你是在低水平上创业,你不需要任何自动化测试。所有测试都可以用手动方法完成。但是,当您的业务开始增长并开始获得广泛受众的认可时,您可能需要自动化一些流程,如web应用的跨浏览器测试,以确保它为所有用户提供类似的体验。 假设正开发一个网站。如果初期是处在较低水平,那不需要任何自动化测试,所有的测试都可以用手工方法完成。但是当业务开始增长,并广泛获得用户的认可时,就可能需要自动化一些流程,如跨浏览器测试这个web应用,以确保它为所有用户提供类似的体验。 此外,如果需要回归测试,那么也需要执行自动化测试。这就是为何选择一个能够提供所有这些功能的自动化工具是必要的。 自动化测试工具的种类 通常有三种类型的自动化测试工具可供选择。以下是每种类型的简要说明: 开源自动化测试工具 开源工具基本上是免费的平台,允许您访问和使用源代码,也可以修改其原始设计。使用开源工具没有任何成本或费用。 此外,开源工具可以用于测试过程的任何阶段,如测试用例管理、bug跟踪、调试等。当然,一般来说,与商业测试工具相比,开源自动化工具的功能更少。 商业自动化测试工具 商业测试工具是专门为商业目的而设计和生产的。诸多大型企业会选择使用商业自动化测试工具,因为它们具有可扩展特性和来自技术团队的支持。 定制工具或自研工具 对于小众测试项目,测试环境和测试过程有一些特殊的特征,这是开源或商业自动化测试工具无法实现的。因此,测试主管需要考虑定制工具的开发。这些类型的工具很少被少数组织使用,因为它们需要明确地开发。 选择自动化测试工具时要考虑的因素 选择正确的自动化测试设置取决于多个因素。每一个测试设置在开始时独一无二,随着项目的发展可能演变成完全新颖的东西。选择将随着项目规模而扩大的正确设置与选择用于开发应用程序的正确技术堆栈同等重要。以下是影响决策的几个因素: 该工具是否支持您的测试活动,以及是否在市场上可用。哪个自动化测试工具最适合您的项目需求和预算。团队是否具备使用该工具所需的技能,如果没有,那么在您购买测试工具后,谁将使用该工具。自动化工具对于您正在使用的项目环境和技术是否准确。该工具是否有免费试用版,以便购买前分析其性能。随着项目的增长,扩展测试平台所涉及的成本和开发工作是什么。维护和管理旧的测试以在项目中使用更新有多困难。 尽管在选择自动化工具时包含许多因素,但我们相信这些是您在寻找自动化测试工具之前需要考虑的基本因素。让我们更深入地探讨选择最佳自动化测试工具的概念。 自动化测试工具的选择标准 无论您的项目对自动化测试工具有什么要求,总是有一种简单而有效的方法来为您的项目选择最佳的自动化测试工具。 1.全面分析项目需求 通过提供无缺陷的产品来保持项目的质量对于项目的成功至关重要。自动化测试是提高任何项目质量以及增加测试深度和范围的最佳方法。但是,在实施自动化测试之前,请清楚地了解您的项目需求,例如: 项目类型是什么?它是web/桌面/移动应用程序还是其他类型项目?项目发布后的范围是什么?在流程开始之前,分析测试团队在代码语言方面的实力。 一般来说,没有完全好或坏的自动化工具,但是如果希望该工具具有良好的ROI,这完全取决于项目需要,例如实际需要自动化什么以及有多少测试用例需要自动化测试。 对于大多数项目,普遍认为手动和自动化测试对于web、移动和桌面应用程序的测试都是必不可少的。因此,可以选择能够与项目规划和测试管理工具无缝集成,而且学习速度快、使用方便的工具。 2.将现有的自动化工具作为基准进行比较 如果您正在使用像Selenium测试自动化这样的开源自动化工具,那么可以将其作为评估和确定项目最佳自动化测试工具的基准。为此,就需要了解Selenium自动化工具的优点和缺点。 例如,Selenium是一种开源的免费工具,允许用户测试其web应用程序和网站。它还为自动化测试提供了独特的功能,如记录回放以创建记录回放测试脚本,以及对多种语言的语言支持。但是,Selenium WebDriver并不能提供良好的客户支持。 Selenium是熟悉编码技术并通过用户界面测试其网站的测试人员的首选。此外,Selenium套件的维护并不容易,尤其是对于经常监督手动和自动化测试的测试人员来说。使用Selenium可能面临的另一个挑战是web应用的浏览器兼容性测试,因为不可能跨浏览器、操作系统和设备的多种组合自动进行跨浏览器测试。 因此,选择当前的测试工具作为基准并将其与决定购买用于自动化测试的工具进行比较是至关重要的。 3.验证适合项目的关键标准 在确定项目的最佳自动化工具之前,需要考虑以下要点: 对于任何项目成员来说,测试执行都必须简单,以便成员都能够在需要时高效地运行测试。此外,对于技术知识很少的非技术用户来说,这也应该是容易的。该工具生成的测试报告对于管理团队来说必须直观、简单,以便他们能够理解测试过程。自动化测试工具必须支持所有三种平台,包括web、桌面和移动应用程序。测试脚本的开发和维护必须减少人力和时间资源管理。当涉及到web应用程序的跨浏览器测试时,自动化工具必须支持多种浏览器和平台。支持关键字驱动测试,因为它充当了数据驱动测试框架的扩展。自动化工具必须支持项目所需的语言,以便测试人员可以轻松地编写代码。在选择自动化测试工具时,技术支持和协助是首要任务,请确保该工具可以获得持续的技术支持。如果包含其他功能是加分项,如屏幕截图测试、视觉外观测试、实时测试等。 比较不同自动化工具的这些关键因素,然后从中选择最佳因素。 4.在购买工具前考虑预算 在根据上述标准比较了不同的自动化工具之后,最后要确认预算。预算是关键的问题之一,这个最好理解,不管根据上述选的工具如何满意,超过组织预算的话都无法实现。 如果组织已最终确定购买该工具,则建议下载并使用该工具的试用版,以分析其性能,以及是否值得投入这么多资金。在试用之后,如果发现该工具有任何问题,那么不要花太多时间在它上面,而是寻找另一个自动化测试工具。只有确定工具的功能和性能时,才购买该工具。 陈哥卖瓜,自卖自夸,遵循以上各种标准,免去挑选自动化测试工具的烦恼,直接为您推荐禅道自动化测试解决方案。该方案由禅道项目管理软件+ZTF自动化测试框架+ZenData通用数据生成器构成,从测试框架、测试数据和测试环境方面解决测试管理问题。

Centos8.x yum 源配置 解决 yum 不可用

镜像下载、域名解析、时间同步请点击 阿里云开源镜像站 备份 [root@iZ2ze1e3u7m7oe426pyndaa ~]# cd /etc/yum.repos.d/ [root@iZ2ze1e3u7m7oe426pyndaa yum.repos.d]# ll total 48 -rw-r--r-- 1 root root 635 Nov 20 2020 CentOS-AppStream.repo -rw-r--r-- 1 root root 619 Nov 20 2020 CentOS-Base.repo -rw-r--r-- 1 root root 701 Nov 20 2020 CentOS-centosplus.repo -rw-r--r-- 1 root root 1329 Nov 20 2020 CentOS-CR.repo -rw-r--r-- 1 root root 668 Nov 20 2020 CentOS-Debuginfo.repo -rw-r--r-- 1 root root 227 Nov 20 2020 CentOS-epel.repo -rw-r--r-- 1 root root 663 Nov 20 2020 CentOS-Extras.

第10章 Spark

10.1 Spark概述 10.1.1 Spark简介 Spark具有如下几个主要特点: •运行速度快:使用DAG执行引擎以支持循环数据流与内存计算 •容易使用:支持使用Scala、Java、Python和R语言进行编程,可以通过 Spark Shell进行交互式编程 •通用性:Spark提供了完整而强大的技术栈,包括SQL查询、流式计算 、机器学习和图算法组件 •运行模式多样:可运行于独立的集群模式中,可运行于Hadoop中,也 可运行于Amazon EC2等云环境中,并且可以访问HDFS、Cassandra、 HBase、Hive等多种数据源 10.1.2 Scala简介 Scala是一门现代的多范式编程语言,运行于Java平台(JVM, Java 虚拟机),并兼容现有的Java程序 Scala的特性: •Scala具备强大的并发性,支持函数式编程,可以更好地支持分布式系统 •Scala语法简洁,能提供优雅的API Scala兼容Java,运行速度快,且能融合到Hadoop生态圈中 •Scala是Spark的主要编程语言,但Spark还支持Java、Python、R作为编程语言 •Scala的优势是提供了REPL(Read-Eval-Print Loop,交互式解释器),提高程序开发效率 10.1.3 Spark与Hadoop的对比 Hadoop存在如下一些缺点: •表达能力有限 •磁盘IO开销大 •延迟高 相比于Hadoop MapReduce,Spark主要具有如下优点: •Spark的计算模式也属于MapReduce,但不局限于Map和Reduce操作,还提供了多种数据集操作类型,编程模型比Hadoop MapReduce更灵活 •Spark提供了内存计算,可将中间结果放到内存中,对于迭代运算效率更高 •Spark基于DAG的任务调度执行机制,要优于Hadoop MapReduce的迭代 执行机制 使用Hadoop进行迭代计算非常耗资源 Spark将数据载入内存后,之后的迭代计算都可以直接使用内存中的中间 结果作运算,避免从磁盘中频繁读取数据 10.2 Spark生态系统 在实际应用中,大数据处理主要包括以下三个类型: •复杂的批量数据处理:通常时间跨度在数十分钟到数小时之间 •基于历史数据的交互式查询:通常时间跨度在数十秒到数分钟之间 •基于实时数据流的数据处理:通常时间跨度在数百毫秒到数秒之间 •Spark的设计遵循“一个软件栈满足不同应用场景”的理念,逐渐形成了一套完整的生态系统 •既能够提供内存计算框架,也可以支持SQL即席查询、实时流式计算、机器学习和图计算等 •Spark可以部署在资源管理器YARN之上,提供一站式的大数据解决方案 •因此,Spark所提供的生态系统足以应对上述三种场景,即同时支持批处理、交互式查询和流数据处理 Spark的生态系统主要包含了Spark Core、Spark SQL、Spark Streaming、 MLLib和GraphX 等组件。 10.3 Spark运行架构 10.3.1 基本概念 •RDD:是Resillient Distributed Dataset(弹性分布式数据集)的简称,是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型 •DAG:是Directed Acyclic Graph(有向无环图)的简称,反映RDD之间的依赖关系

第6章 云数据库

6.1 云数据库概述 6.1.1 云数据库概念 云数据库是部署和虚拟化在云计算环境中的数据库。云数据库是在云计算的大背景 下发展起来的一种新兴的共享基础架构的方法,它极大地增强了数据库的存储能力 ,消除了人员、硬件、软件的重复配置,让软、硬件升级变得更加容易。云数据库 具有高可扩展性、高可用性、采用多租形式和支持资源有效分发等特点。 6.1.2 云数据库特性 1.动态可扩展 2.高可用性 3.较低的使用代价 4.易用性 5.高性能 6.免维护 7.安全 6.2 云数据库系统架构 以UMP为例。 6.2.1 UMP系统概述 UMP(Unified MySQL Platform)是由阿里集团核心系统数据库团队设计与实现的,提供低成本和高性能的MySQL云数据服务。 总的来说,UMP系统架构设计遵循了以下原则。 •保持单一的系统对外入口,并且为系统内部维护单一的资源池 •消除单点故障,保证服务的高可用性 •保证系统具有良好的可伸缩,能够动态地增加、删减计算与存储节点 •保证分配给用户的资源也是弹性可伸缩的,资源之间相互隔离,确保 应用和数据安全 6.2.2 UMP系统架构 UMP系统中的角色包括: •Controller服务器 :为UMP集群提供各种管理服务(成员管理、元数据存储、MySQL实例管理、故障恢复、备份、迁移、扩容等) •Proxy服务器 :完全实现了MySQL服务,向用户提供访问MySQL数据库的服务 •Agent服务器 :它部署在运行MySQL进程的机器上,用来管理每台物理机上的MySQL实例 •Web控制台 :向用户提供系统管理界面 •日志分析服务器:存储和分析Proxy服务器传入的用户访问日志,支持实时查询一段时间内的慢日志和统计报表 •信息统计服务器 :定期将采集到的用户连接数、QPS(每秒查询次数)数值及MySQL实例的进程状态等信息进行统计展示在Web界面上,或将结果作为以后资源分配等的依据。 •愚公系统:用于做数据迁移,可在不停机的情况下动态扩容、缩容和迁移。 依赖的开源组件包括: •Mnesia :分布式数据库管理系统 •LVS:Linux虚拟服务器 •RabbitMQ :工业级的消息队列产品 •ZooKeeper :协同工作系统 6.2.3 UMP系统功能 •容灾 •读写分离 •分库分表 •资源管理 •资源调度 •资源隔离 •数据安全

Matlab APP Designer 如何实时更新代码调试信息(drawnow的使用)、Matlab APP Designer如何自动输出程序中的变量值

Matlab APP Designer drawnow如何实现自动更新日志、如何自动输出程序中的变量值 eg:如下图所示,实现代码调试信息刷新 1.编写信息刷新函数:点击函数,添加私有函数,将以下代码输入,后点击参数,添加私有参数,即可实现。 function logRefresh_func(app,StrArrayNew) %刷调试信息 if length(app.StrArray)>=5 app.StrArray={};%信息初始化 end app.StrArray=[app.StrArray,StrArrayNew];%合并信息 app.TextArea.Value=app.StrArray;%将值赋予TextArea app.TextArea_2.Value=app.StrArray;%将值赋予TextArea end 2.回调时在功能函数中需要输出信息的位置,输入以下代码即可实时刷新消息框信息 StrArrayNew={'msg:正在读取排产计划......'};%输入自己想要输出的信息 logRefresh_func(app,StrArrayNew);%调用显示信息的函数 drawnow%必须加上这个,不然不能实时更新,只能运行完整个程序后全部显示 3.实现自动输出程序中的变量值,需要提前将变量变成字符或者字符数组,例如要输出当前月份,见以下代码 shuchu=month(today); shuchu_2='月份'; shuchu_sum=[shuchu,shuchu_2]; StrArrayNew={shuchu_sum}; logRefresh_func(app,StrArrayNew); drawnow appdesigner信息调试框内会出现:8月份 4.drawnow更新图窗并处理任何挂起的回调。如果修改图形对象并且需要在屏幕上立即查看这次更新,请使用该命令。(千万别忘了加上这个语句,否则只能运行完整个程序后显示)

TCP/IP协议之客户端——华清远见

书接上回 自打上次学习了服务器端之后 又认真研究了一番 客户端与服务器之间存在三次握手!! 客户端与服务器之间存在三次握手!! 客户端与服务器之间存在三次握手!! 那么问题来了,什么是三次握手呢??? 一、三次握手是什么? 第一次握手:客户端发起,发送SYN请求报文,序列化:X;服务器收到SYN请求报文。 第二次握手:服务器端发起,发送ACK确认报文,确认号:X+1;发送SYN请求报文,序列号Y,客户端收到SYN/ACK请求确认报文。 第三次握手:客户端发送ACK确认报文,确认号Y+1,服务器端收到ACK确认报文。 咱们就是说,谁能拒绝简单明了的图解呢~ 简单来说,就有些像正常聊天一样 一边发送信息,另一边接收信息之后进行回复 接下来一起看看怎么具体实现叭~ 二、具体步骤 1.引入库 代码如下(示例): import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Scanner; 2.具体实现 代码如下(示例): public static void main(String[] args) { // TODO Auto-generated method stub Socket socket = null; OutputStream os = null; InputStream is = null; Scanner scan = new Scanner(System.in); try { socket = new Socket("192.168.60.33", 6666); os = socket.getOutputStream(); String request = scan.

mongo进入报错

问题:在cmd中,输入命令mongo就报错 couldn’t connect to server 127.0.0.1:27017 应该是没有启动服务的原因,打开服务,并没有发现MongoDB这个服务 解决方法 还是在cmd中,输入下面两个命令 (1)删除服务 sc delete MongoDB (2)创建服务,注意创建的位置 sc create MongoDB binPath= “C:\Program Files\MongoDB\Server\4.0\bin\mongod.exe --service --config=D:\mongodb\mongo.config” 最后打开服务,启动服务 再次进入mongo,成功了

docker镜像与容器基本的基本操作(三)

目录 一、docker基本命令 1.1、查看镜像——docker images 1.2、查看所有状态容器——docker ps -a 1.3、docker —— run 指令 工作流程简单解释: 1.4、查看docker版本命令(docker -v) 1.5 、查看docker信息(docker info) 1.6、docker帮助命令文档(docker --help) 二、docker镜像操作 2.1、搜索镜像(公共仓库)(docker search) 2.2、下载镜像(docker pull) 2.3、查看镜像列表(docker images) 2.4、获取镜像信息(docker inspect) 2.5、添加镜像标签(docker tag 定位) 2.6、导出镜像(docker save) 2.7、删除镜像(docker rmi) 2.8、批量删除镜像 ​编辑 2.9、导入镜像——docker load 2.10、批量打包镜像 三、容器操作 3.1、查询所有容器运行状态(docker ps -a) 3.2、创建容器(基于镜像)docker create 3.3、启动/停止容器(docker start/stop) 3.4、启动容器(一次性执行)—docker run 3.5、日志 端口 重命名 3.5.1查看容器运行日志 3.5.2查看容器端口信息 3.5.3 容器重命名 3.6、查看容器ip地址—docker inspect 3.7、进入容器—docker exec 扩展:生产方式进入容器 3.8、容器导出/导入—docker export/import 3.9、删除容器—docker rm -f 3.10、容器打包为镜像 查看docker消耗的资源状态

隐马尔可夫模型基础介绍

应用场景 隐含马尔可夫模型(Hidden Markov Model, 简称HMM)可以被应用到语音,人脸识别,动作识别等领域。语音具有时序性质。HMM被应用到语音当中,可以有效的反映出语音的时序变化。人脸图像在水平方向和垂直方向上都表现出了像素级的顺序性,因此HMM可以被用来人脸识别,对周围环境的变化也具有很好的鲁棒性。除此以外,人的行为动作等,也表现出序列性。 模型定义 隐含马尔克夫模型中的变量可以被分为状态变量和观测变量。状态变量是不可观测,也叫做隐藏的,被称为隐藏变量。我们将状态变量表示为: y 1 , y 2 , ⋯ , y i , ⋯ , y n { {y_1},{y_2}, \cdots ,{y_i}, \cdots ,{y_n}} y1​,y2​,⋯,yi​,⋯,yn​ 其中 y i ∈ Y {y_i} \in {\mathcal Y} yi​∈Y表示第 i i i时刻的状态值,表示状态空间 Y \mathcal{Y} Y。一般情况下,存在多个状态值,并且状态之间具有转换,我们将所有的状态表示为: { s 1 , s 2 , ⋯ , s i , ⋯ , s N } \{ {s_1},{s_2}, \cdots ,{s_i}, \cdots ,{s_N}\} {s1​,s2​,⋯,si​,⋯,sN​}

ViLT: Vision-and-Language Transformer Without Convolution or Region Supervision内容理解

ViLT: Vision-and-Language Transformer Without Convolution or Region Supervision内容理解 一、Abstract二、引言三、背景介绍1、目前VLP模型框架介绍2、多模态交互框架3、Visual Embedding 框架 四、VILT模型1、模型总览2、预训练计划3、Whole Word Masking4、Image Augmentation5、模型结构图 五、实验1、总览:2、实施细节3、VLP模型的复杂度分析4、分类任务5、检索任务6、Ablation Study7. 常规的Visualization操作 六、结论及展望 写在前面 这篇文章作为一系列多模态理解的第一篇,从这里记录本人研究内容相关话题,期待后来者共同学习,共同进步,也顺便作为笔记备份。 文章链接:ViLT: Vision-and-Language Transformer Without Convolution or Region Supervision代码:https://github.com/dandelin/vilt 发表于ICML2021, v2版本更精彩一些。本人看的是第一版,且第一版代码未放出。第二版多了代码部分+region feature提取部分,推荐看一下~ 2022年7月29日 更新: 今天沐神和搭档朱老师在 B 站上面讲解了这篇论文, 链接:https://www.bilibili.com/video/BV14r4y1j74y 一、Abstract 摘要部分首先指出:当前大多数模型极度依赖于目标检测模型提取出的Feature进行VLP建模(不得不说,类似Faster-rcnn这种框架提取出的特征确实用起来精度高了很多),同时点明 缺点一:效率/速度;当然,肯定会慢很多,毋庸置疑,因为这种方法是将提取出的特征缓存到磁盘里面,再进行VLP训练。 缺点二:由于类似RPN这种候选区域生成器,也就是文中所说的visual enconde的出现+监督训练过程中label 词汇的有限,就导致了其上界问题。 后面就是作者对自己模型ViLT的介绍了:完全去除掉conv操作,加速加速再加速。同时提及精度和某些模型相当或超过一些模型。 评语:点名缺点很正常,速度慢,但是精度高呀,你没法打败; 上界问题哪个模型都离不开image+text呀 作者提出的这个模型,咋说,速度快,确实;但这个accuracy着实拉胯,和19年的MCAN比较额。 二、引言 引言部分描述了当前VLP模型的结构以及预训练的方法:MLM,ITM; 借势引出了Visual enocde的方法,基于region(传统)或者grid(2020年整活了),这些需要conv,而作者提出conv-free的方法,在速度上更快。 最后作者提出文章的三点贡献: 1、运行速度快,参数少; 2、第一个不使用卷积就能达到相当不错的精度; 3、首次用实验表明了whole word masking and image augmentations针对下游任务的有效性。 三、背景介绍 1、目前VLP模型框架介绍 喏,就是下面这张图了点出了目前VLP的框架结构: a图是19年及之前的方法,后来多模态交互部分都改成transformer了; b图暂时还没认真看到过,因为大多数的Text Embed都是直接调用nn.embedding模块实现; c图是目前自transformer出来之后的主流方法,精度贼高,但速度慢; d图是目前作者提出的方法。速度快,但精度差。

视觉学习笔记4——ORB-SLAM3的地图保存与使用

ORB系列文章目录 前言:视觉学习笔记4——学习研究ORB-SLAM3 文章目录 ORB系列文章目录前言一、地图保存方法1(使用自带OSA保存):方法2(保存为PCD文件): 二、地图调用1.修改PCD文件2.安装使用meshlab 未完待续··· 前言 ORB-SLAM3基本搭建完成,具体可以看开头的系列文章目录,接下来需要研究如何自定义自己的地图,也就是实时地图的保存与运用。 一、地图保存 方法1(使用自带OSA保存): 按照开源说明来看,地图保存与加载在V1.0已经实现了,需要修改相应的yaml文件即可,也就是相机yaml文件,例如单目测试就需要修改ORB_SLAM3/Examples_old/ROS/ORB_SLAM3/Asus.yaml文件。 1、修改yaml文件 在该文件中的末尾添加以下代码: System.SaveAtlasToFile: "map.osa" 2、ORB-SLAM3编译运行: 重新编译后再运行单目实例,这时就会自动保存点云了,点云信息保存在.osa文件中。 sudo ./build.sh sudo ./build_ros.sh 3、加载 按道理此时地图已经保存成功,也确实有.osa文件出现在主目录里,可是我却没有很好办法来查看和调用这个文件,所以就修改为pcd文件来使用。 方法2(保存为PCD文件): 经过查询找到这位博主的文章 1、安装PCL库 sudo apt-get install libpcl-dev pcl-tools 2、修改MapDrawer.cc 文件 第一步,先加入 pcl 保存点云所需的头文件: #include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <pcl/io/pcd_io.h> 第二步,找到 DrawMapPoints 函数中的如下代码: for(set<MapPoint*>::iterator sit=spRefMPs.begin(), send=spRefMPs.end(); sit!=send; sit++) { if((*sit)->isBad()) continue; Eigen::Matrix<float,3,1> pos = (*sit)->GetWorldPos(); glVertex3f(pos(0),pos(1),pos(2)); } 并将其修改为如下代码: pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_saved(new pcl::PointCloud<pcl::PointXYZ>()); for(set<MapPoint*>::iterator sit=spRefMPs.begin(), send=spRefMPs.end(); sit!=send; sit++) { if((*sit)->isBad()) continue; Eigen::Matrix<float,3,1> pos = (*sit)->GetWorldPos(); glVertex3f(pos(0),pos(1),pos(2)); //modified by Awei pcl::PointXYZ p; p.

微信发红包测试用例

目录 一、功能 二、性能 三、兼容 四、界面 五、安全 六、易用性(有点重复) (难免有所遗漏,仅供参考) 一、功能 1.在红包钱数和红包个数的输入框中只能输入数字 2.红包里最多和最少可以输入的钱数 3.拼手气红包最多可以发多少个红包 超过最大拼手气红包的个数是否有提醒 红包个数超过群里总人数 拼手气红包,每个人抢的钱数不一样 4.当红包数超过最大范围是不是有对应的提示 5.当发送红包个数超过最大范围是不是有对应提示 一对一 群发 6.当余额不足时,红包发送失败 银行卡 零钱 零钱通 6.1塞钱进红包,扣钱顺序 主动设置优先级 默认顺序,看哪一种方式付钱比较充足 确认时候,自己选择付款方式 7.在红包描述里是否可以输入汉字,英文,符号,表情,纯数字等 是否可以输入自己下载的表情,并且抢红包的人是否可以看到 是否可以选择红包封面 描述最多能有多少个字符 8.红包描述,金额,个数是否支持复制粘贴操作 9.发送出去的红包是否是否可以撤回 10.发送的红包别人是否可以领取 发的红包自己可不可以领 发红包的人是否还可以抢红包 11.超过24小时没有领取的红包是否可以退到原来的账户 12.用户是否可以多次抢一个红包 13.红包的金额里的小数位是否有限制 14.是否可以按取消键取消发红包 15.断网时,无法抢红包 16.红包界面能否看到以前的收发红包记录 17.红包记录里的信息是否与实际收发红包记录相匹配 18.支付时可以密码或指纹支付,免密支付或刷脸支付 19.支付成功后,退出到聊天界面 20.发红包金额和收红包金额相匹配 21.是否可以连续多次发红包 22.输入钱数为0时,”塞钱进红包“置灰 23.退款到账时间 24.电脑端是否可以抢微信红包 二、性能 1.不同网速时抢红包,发红包的时间 2.发红包和收红包成功后的跳转时间 3.收发红包的耗电量 三、兼容 1.苹果,安卓是否都可以发送红包,抢红包 四、界面 1.发红包界面没有错别字 2.抢完红包里面没有错别字 3.发红包和收红包界面排版是否合理 4.发红包和收红包界面颜色搭配是否合理 五、安全 1.对方微信异地登录,是否会有提醒 2.红包被领取后,发送红包人的金额会减少,收红包人的金额会增加 3.发送红包失败,余额和银行卡里的钱不会减少 4.红包发送成功,是否会收到微信支付的通知 六、易用性(有点重复) 1.红包描述,可以通过语音输入 2.可以指纹、免密、刷脸等支付

python选择语句

python的选择语句: if if…else if...elif...else if...else用于二选一,可以用条件表达式简化 多重选择只能用if...elif...else 缩进很重要! elif,else不可以单独使用,必须和if一起使用 if,elif都要判断表达式的真假,else不用判断 例: your_age=int(input("请输入恁现在的年龄:")) if your_age<=18: print("你太小了,好好学习吧!") elif 18<your_age<=30: print("你现在正是黄金时期,奋斗呀!") elif 30<your_age<=50: print("一切皆有可能!") else: print("最美不过夕阳红~")

EventBus 事件机制详解(Google Guava)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 概念1. 事件本身2. 发布事件的对象3. 接收事件的对象4. 验证结果 概念 使用EventBus(Guava提供的)可以实现事件的发布和监听,概念、效果和Spring的事件(可点击参看另一篇文章)很类似。 EventBus的事件机制是A调用一个发布事件的方法,就能自动调用B监听这个事件的方法,这个过程有3个对象: 事件本身,其实就是一个对象,这是一个普通的java类;发布事件的对象,使用 EventBus 的 post 方法来发布,参数就是事件;接收(或者叫监听)事件的对象,使用@Subscribe注解的方法来处理接收的事件,这里需要注意提前将这个监听者注册到EventBus中; 1. 事件本身 对应3个对象中的第一个,如上所述,是一个普通的java类,如下: package test.eventbus; public class EventBusMessage { private int age; public EventBusMessage(int age) { this.age = age; } public int getAge() { return age; } } 2. 发布事件的对象 对应3个对象的第二个,使用 EventBus 的 post 方法来发布,参数就是事件 EventBusMessage ,如下: package test.eventbus; import com.google.common.eventbus.EventBus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/test") public class EventBusTestController { @Autowired private EventBus eventBus; // 注意这里的EventBus是spring默认的单例 @GetMapping("

安装Ubuntu双系统(Win10双硬盘)2021新版教程

本机配置 电脑:战神Z7-TA5NA 系统:Win10 BIOS模式:UEFI 双硬盘:512SSD+1T机械硬盘 Ubantu系统:20.04LTS ubuntu安装anaconda unbuntu安装pycharm ubuntu安装pytorch 准备事项 1.准备重装启动盘 一个,包含Ubuntu系统,个人建议淘宝上买一个,一键安装(WIN7、8、10、11、Ubuntu)它不香嘛?性价比技术溢价都很高(淘宝搜索:重装盘 Ubuntu)又快,镜像又全,自动化集成度高! 2.电脑一台,提前关闭快速启动、Secure Boot(为了进入BIOS) 快捷启动项参考 开始安装 1.WIN10此电脑右键管理, 选择磁盘管理: 【一个硬盘的话在最后一个盘,点击右键删除卷】 【二个硬盘的话在没有装win10的盘,点击右键删除卷,我机械硬盘是磁盘0,你的可能是磁盘1,所以我在磁盘1点击右键删除卷】 2.分配Ubantu系统需要的空间 右键删除卷后如图所示 【输入压缩空间量,我给的是200000MB即200G的空间】 【出现】黑色的未分配空间 3.关闭快速启动,为了等下插入启动盘进入BIOS,不然键盘 按烂 都进不去 = = 4.插入启动盘,进入BIOS,我的电脑是开机启动后一直按F2选择安装Ubuntu系统(启动盘做好后,将Ubuntu写入U盘后会有Ubuntu的安装选项,此时选择这个选项进入安装Ubuntu的界面) 5.进入安装界面,选择中文简体(左边一直下滑,在最后面),然后点击【安装Ubuntu】 6.选择键盘布局,都选择Chinese 7.无线,【选择不联网】因为网络不佳的话可能会卡住呢,所以直接不联网 8.更新和其他软件,选择【正常安装】【最小安装】都可以,我选择的正常安装,其他选项记得选为图像或无线…这个 9. 关键步骤 不要花里胡哨 直接选择第一个与Win10共存,它会把你的Ubuntu自动安装在你【删除卷】预留的200G空间中。 优点:方便快捷,一键安装简单且不需要任何分区操作缺点:他会给你Swap分区默认分配仅2G空间,不能自主设置其他分区,将EFI启动项默认装到预留的空间中,当你安装系统在机械硬盘中的时候,这样可能会导致启动Ubuntu时,搜索启动项,花费额外时间 EFI及Swap说明(可跳过) Swap分区及交换分区,简单来讲就是当你物理内存不足的时候,会调用Swap分区来充当虚拟内存,突破物理内存的限制! 所以一般是内存的1.5-2倍,默认一键安装的2G不会影响你个人使用,一般是为解决服务器上多人访问内存不足的问题(但装好Ubuntu之后可手动扩充swap空间,详情介绍见文末参考文献) 总结:一键安装的时候,不能手动分配swap空间,以及设置EFI启动项位置默认安装是在预留的机械硬盘分区中(如在win10的固态硬盘上预留EFI启动项空间,且在手动分区时设置EFI并且放到预留固态硬盘中,会减少搜索时间加快启动速度) 【特此说明】:本文的教程全都没有去主动调整EFI启动项的位置,无论在一键安装还是自主分区都是将他安装在机械硬盘中,因此我在这儿说明一下,为防止有特殊需求的同学,请看清楚! 不需要自主进行分区的同学,就可以不看如果后面的字了!!! 如果 你想自己分区,那么你就点其它选项:说明一点,分区的话,如果你不是很了解每个分区的作用那么就简单的分成2个区就好: ①找到空闲预留的空间,看大小,然后双击它,或者左下角有个加号 ②Swap,大小为内存两倍,逻辑分区,起始位置 ③其余空间全部分配给【/】,文件格式ext4,主分区,起始位置 ④点击安装 简明的视频教程:【双系统】在Windows上安装Ubuntu系统(零基础保姆级教学) 分析:网上看教程的时候,别人都说要怎么怎么分区,要什么efi引导,需要怎么怎么安装或者预留系统引导的空间,但是我想这些教程都过时了,虽然有很多是可以借鉴的,但是我想随着Ubuntu的进步,它也会帮你简化很多不必要的过程,所以引导可能已经在安装的时候自动帮你设置好了,你尽管去分区,不要怕,我Ubuntu就是有这个稳定性!(我自己瞎猜的 哈哈) 10.直接点安装Ubuntu与Win10共存的,那么现在就点继续进行下一步 11.您在什么地方?直接点击【继续】下一步 12.设置个人信息 13.点击【继续】后会自动安装Ubuntu 等待几分钟… 14.安装完成点击【重启】 点击enter继续重启并拔掉启动盘 15.完成安装,手动选择Ubuntu系统,进入Ubantu 16.输入密码并进入Ubuntu 17.点点点点点 18.安装完成-Bngo 19.我们没有手动去进行分区,现在回到Win10上看看是不是Ubuntu自动占用了前面我们预留的200G空间,并自动进行引导 20.看看我们的Win10是否能正常运行 英雄联盟,启动!!! 补充:如果不是新的BIOS:UEFI的话,那么重装电脑的时候选择GUID即可

Spring Boot 3 新特性及快速使用示例

Spring Boot 3 截止2022年7月28日发版4个里程碑版本 v3.0.0-M4v3.0.0-M3v3.0.0-M2v3.0.0-M1 新特性 1、最低要求 要求说明JDKJDK 17兼容JDK 18SpringSpring Framework 6.0.0或更高版本Maven3.5+servlet5.0+Tomcat10.0IntelliJ IDEA2021.2.1 2、删除的支持 Apache ActiveMQAtomikosEhCache 2Hazelcast 3 3、Spring boot 2.x中丢弃的 在 Spring Boot 2.x 中不推荐使用的类、方法和属性已在此版本中删除。请确保在升级之前您没有调用过时的方法。 4、依赖包的升级 很多相关的包,就不一一列出来了 示例演示 准备 同时存在2个版本JDK 因为大部分人自己电脑上使用的是JDK 1.8,想要试用Spring Boot 3必须JDK 17,那边就要配置一下2个JDK版本共存来试用。 1、下载 https://www.oracle.com/java 下载JDK 17安装 2、配置环境 新建2个系统环境变量 环境变量操作类型值jdk1.8新增jdk17新增JAVA_HOME修改%jdk17% 要使用其他JDK版本时,修改JAVA_HOME的值%%中的值即可。 不同版本说明 M 表示里程碑版本,RC 表示候选发布版本,SNAPSHOT 表示构建 GA:General Availability,正式发布的版本,官方推荐使用此版本SNAPSHOT:快照版,可以稳定使用,且仍在继续改进版本PRE:预览版,内部测试版,主要是给开发人员和测试人员测试和找BUG用的,不建议使用M:里程碑版本,可能不完整,但可能仍然有问题 示例 IDEA 配置JDK 17 新建Spring Boot 3工程 如图选择点击完成就自动生成相关代码。 其中pom.xml文件中的如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.

卷积神经网络(CNN)之卷积操作、池化操作、激活函数

前言:卷积神经网络是深度学习算法中一个重要组成部分,在深度学习图像识别技术的应用中起到了关键作用。卷积神经网络和循环神经网络(RNN)都是类似于传统的全连接神经网络(也叫深度神经网络,简称DNN),CNN属于编码了空间相关性的DNN,RNN属于编码了时间相关性的DNN。由于图像任务的不同,CNN的网络层也会有些许变动,但是基本上都会使用到卷积层、池化层以及非线性层。为了加深这方面理论知识的理解,本文将从多方面深入讲解CNN中的卷积操作、池化操作以及激活函数。 目录 1、卷积层 1.1 卷积计算 1.2 卷积层的特点 1.3 常用的卷积操作 2、池化层 2.1 池化的作用 2.2 常用的池化操作 3、非线性层 3.1 激活函数的作用 3.2 常用的激活函数 1、卷积层 卷积层的作用是提取输入图片中的信息,这些信息被称为图像特征,这些特征是由图像中的每个像素通过组合或者独立的方式所体现,比如图片的纹理特征,颜色特征。 1.1 卷积计算 在讲解具体的卷积计算之前,我们先通过几张动图直观地感受一下不同维度的卷积操作。 一维卷积操作如下图所示: 二维卷积操作如下图所示: 三位卷积操作如下图所示: 卷积核做的是线性运算,核上的每个值与它滑动到的对应位置上的值相乘,然后把这些值相加。以二维卷积为例讲解Conv2d如何进行卷积计算,在讲解卷积计算之前,我们需要明白几点重要的概念,这对理解卷积运算有很大的帮助: ①二维卷积中的二维并不是指卷积核是二维的,它与卷积核的维度无关,而是指卷积核只在两个维度上滑动。同理,一维卷积和三维卷积分别指卷积核在一个维度或者三个维度上滑动,正如上面3个图所示; ②卷积核通道数(或者叫卷积核个数,一组卷积核中有通道数个卷积核)=输入层通道数; ③输出层通道数(即特征图通道数或特征图个数)=卷积核组数,也就是说1组卷积核对输入进行卷积计算后只能得到1个特征图,特征图有n个通道则说明需要用n组卷积核对输入进行卷积计算。 理解了上面几点概念后,现在我们来通过一个实例来具体感受一下二维卷积是如何计算的。 如上图所示,假设输入是RGB3个通道的二维图像,那么一组卷积核中包含3个二维卷积核,即卷积核也必须是3个通道的。这3个卷积核分别在输入图像的3个通道上滑动,比如R通道上,每滑动一次,对应元素相乘再相加就可以得到一个数,3个卷积核滑动一次就会得到3个数,将这3个数相加并且加上一个偏置即可得到特征图上的一个值,该组卷积核在输入图像上全部滑动结束,那么就可以得到一个完整的特征图,这个特征图代表从输入图像中提取出来的一种特征。而一般在输入图像上只提取一种特征是完全不够的,往往需要在输入图像上获取更多的特征信息,即要获得多个特征图,那么就需要多组卷积核在图像上进行卷积计算。下图中使用了两组卷积核计算得到了2个特征图。 二维卷积操作在Pytorch中通过下面函数实现: #二维卷积 torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros', device=None, dtype=None) #参数介绍: #in_channels:输入的通道数 #out_channels:输出的通道数 #kernel_size:卷积核的大小 #stride:卷积核滑动的步长,默认是1 #padding:怎么填充输入图像,此参数的类型可以是int , tuple或str , optional 。默认padding=0,即不填充。 #dilation:设置膨胀率,即核内元素间距,默认是1。即如果kernel_size=3,dilation=1,那么卷积核大小就是3×3;如果kernel_size=3,dilation=2,那么卷积核大小为5×5 #groups:通过设置这个参数来决定分几组进行卷积,默认是1,即默认是普通卷积,此时卷积核通道数=输入通道数 #bias:是否添加偏差,默认true #padding_mode:填充时,此参数决定用什么值来填充,默认是'zeros',即用0填充,可选参数有'zeros', 'reflect', 'replicate'或'circular' 假设输入的尺寸是,卷积后输出的尺寸是,那么: 1.2 卷积层的特点 ①权值共享 用同一组参数去遍历整张图像,用于提取整张图像中具有某种共性的特征信息,比如纹理特征等,不同卷积核用于提取图像在不同方面具有共性的特征信息,即卷积操作后得到的一个特征图代表提取的一种图像特征。权值共享是深度学习的一个重要思想,它在减少网络参数的同时依然可以保持很好的网络容量。卷积神经网络在空间上权值共享,而循环神经网络在时间上权值共享。 ②局部连接

JS中的reduce()函数介绍

定义 reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。 reduce() 可以作为一个高阶函数,用于函数的 compose。 注意: reduce() 对于空数组是不会执行回调函数的。 语法 array.reduce(function(total, currentValue, currentIndex, arr), initialValue) 上面的语法参考 菜鸟联盟 通常情况下,第一个参数 使用 prev (如下) arr.reduce(function(prev,cur,index,arr){ ... }, init); prev:上一次调用 callbackFn 时的返回值。在第一次调用时,若指定了初始值 init,其值则为 init,否则为数组索引为 0 的元素 arr[0]。 cur:数组中正在处理的元素。在第一次调用时,若指定了初始值 init,其值则为数组索引为 0 的元素 arr[0],否则为 arr[1]。 index:数组中正在处理的元素的索引。若指定了初始值 init,则起始索引号为 0,否则从索引 1 起始。 arr:用于遍历的数组。 看到这么多参数是不是感觉 reduce 很复杂,一开始我也是这么认为的,然后反复理解上面那些参数的含义,知道了通常情况下,常用的参数只有前面必选的两个参数 prev,cur ,下面我们来看案例 案例 1.数组求和 通常情况下,对数组求和我们常使用 for 循环 或者 forEach ,这里使用 reduc 也会比较简洁,如下 var arr = [1,5,8,10,15,66,65,25,48,55] // forEach var eachSum = 0; arr.

Numpy 常见函数及使用

Numpy常见函数及使用 本文后续边补充,边更新! 参考: 1. Numpy基本使用 2. numpy的文件存储.npy .npz 文件详解 3. np.hstack 用法 4. 图解 5. 菜鸟教程 6. python之np.argmax()及对axis=0或者1的理解 1. np.delete() 删除指定行 np.delete(x, i, axis=0) #删除x矩阵 第i行 2. np.where() 返回输入数组中满足给定条件的元素的索引,返回值为元组类型。 import numpy as np x = np.arange(9.).reshape(3, 3) print ('我们的数组是:') print (x) print ( '大于 3 的元素的索引:') y = np.where(x > 3) print (y) print ('使用这些索引来获取满足条件的元素:') print (x[y]) 结果: 我们的数组是: [[0. 1. 2.] [3. 4. 5.] [6. 7. 8.]] 大于 3 的元素的索引(元组): (array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2])) 使用这些索引来获取满足条件的元素: [4.

AUTOSAR学习笔记1——基础了解

AUTOSAR学习笔记1——基础了解 一、AUTOSAR是什么?二、AUTOSAR架构1.架构图2.各层的基础介绍 总结 一、AUTOSAR是什么? 全称Automotive Open System Architecture(汽车开放系统架构);是全球汽车巨头共同合作建立的一个开放的汽车控制器标准软件架构。 主要是利用标准化的接口实现软硬件的隔离。 二、AUTOSAR架构 1.架构图 中文翻译 AUTOSAR架构最高抽象级别总共分为三大软件层: Application Layer:应用软件层 RTE:实时运行环境层 BSW:基础软件层;又分为:服务层、ECU(电子控制单元)抽象层、微控制器抽象层、复杂的驱动程序(CDD)。 2.各层的基础介绍 1、应用软件层(Application Software Layer) 独立于硬件,软件组件之间的通信以及通过 RTE 访问 BSW。 由一个个的软件组件SWC(Software Component)组成,软件组件间通过端口(Port)进行交互。每个软件组件可以包含一个或者多个运行实体(Runnable Enity),运行实体里是一些实现的算法。 2、RTE层:为应用层和基础软件层提供标准化的接口通信服务。 3、BSW层:提供基础软件服务,包括标准化的系统功能以及功能接口,并且由一系列的基础服务软件组件构成。分为四层:服务层,ECU抽象层,微控制器抽象层和复杂驱动 1)微控制器抽象层:就是把各种外设看成一体,向上提供接口,使上层软件与ECU硬件设计无关 2)ECU抽象层:就是把整块板子看成一体,主要是根据微控制器抽象层提供的接口再封装成脱离硬件设计方面的标准接口,以供给上层使用。 3)服务层:将各种基础软件功能以服务的形式封装起来,服务层为应用层提供的接口就与硬件几乎都不相干了。 4)复杂驱动型:主要是一些autosar中没有定义的一些东西。 总结 AUTOSAR是汽车电子的主流趋势,在开发上提供了模块化开发的方便,减少了开发的成本,软件质量也有明显的提升。

docker安装部署及优化详解(二)

目录 一:、docker安装 1.1、关闭防火墙 1.2、安装依赖包 1.3、设置阿里云镜像源 1.4、安装 Docker-CE(社区版)并设置为开机自动启动 1.5、查看 docker 版本信息 二、设置镜像加速 三、网络优化 为什么要开启路由转发功能? 四、docker-server端配置文件建议配置 五、总结 一:、docker安装 docker初期版本是1.13(同一版本,开源)——》分类型 1.15 - 1.17 过程中分成两种。 ①开源社区 docker-ce ②企业版 docker-ee 目前 Docker 只能支持 64 位系统。 1.#关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service setenforce 0 2.#安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm2 -------------------------------------------------------------------------------- #yum-utils:提供了 yum-config-manager 工具。 #device mapper: 是Linux内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构。 #device mapper存储驱动程序需要 device-mapper-persistent-data 和 lvm2。 -------------------------------------------------------------------------------- 3.#设置阿里云镜像源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 4.#安装 Docker-CE 社区版并设置为开机自动启动 yum install -y docker-ce systemctl start docker.

Android四大组件之——Service

文章目录 程序、进程、线程概念线程的生命周期线程的创建 初识serviceService概念Service生命周期Service种类Service中重要的方法Service 的声明Service的启动StartService启动ServiceBindService启动ServiceStartService启动Service后bindService绑定 Service 进阶IntentService的使用Activity与Service通信前台服务的实现定时后台线程的实现 Service 再进阶Binder机制IBinder和BinderBinder机制和工作流程为何Android使用Binder机制来实现进程间的通信 AIDL(重要)AIDL定义AIDL实现两个进程间的简单通信传递复杂数据的AIDL Service通过Binder的onTransact完成跨进程通信 记录一个高版本的使用AIDL大坑 程序、进程、线程 在了解service相关知识之前,先了解一下多线程的知识。在实际开发中,Service很多时候会和多线程相关进行结合。 概念 程序:为了完成特定任务,用某种语言编写的一组指令集合(一组静态代码)进程:运行中的程序,系统调度与资源分配的一个独立单位,操作系统会 为每个进程分配一段内存空间!程序的依次动态执行,经历代码的加载,执行, 执行完毕的完整过程!线程:比进程更小的执行单元,每个进程可能有多条线程,线程需要放在一个 进程中才能执行,线程由程序负责管理,而进程则由系统进行调度!多线程的理解:并行执行多个条指令,将CPU时间片按照调度算法分配给各个 线程,实际上是分时执行的,只是这个切换的时间很短,用户感觉到"同时"而已 唠叨两句,有很多同学会把进程和线程的概念混淆分不清,这里教大家一个办法,把进程看作一列火车;而把线程看作组成火车的一节节车厢,然后我们再来看线程和进程的概念是不是很符合这个概念呢? 进程是最小的资源分配单位;线程是最小的程序执行单元 线程的生命周期 一共五个阶段 新建、就绪、运行、阻塞、死亡 线程的创建 继承Thread类实现Runnable接口 //创建并启动 new Thread(myThread).start(); //使用匿名内部类 new Thread(new Runnable(){ public void run(); }).start(); 实现Callable接口 初识service Service概念 什么是Servie? Service (服务)是能够在后台执行长时间运行操作并且不提供用户界面的应用程序组件。其他应用程序组件能启动服务,并且即便用户切换到另一个应用程序,服务还可以在后台运行。此外,组件能够绑定到服务并与之交互,甚至执行进程间通信(IPC) 。例如,服务能在后台处理网络事务、播放音乐、执行文件IO或者与ContentProvider通信。 Service生命周期 Service种类 由上图可知,Service主要分为两种 Started:当应用程序组件(如Activity )通过调用startService()方法启动服务时,服务处于started状态。 一旦启动,服务能在后台无限期运行,即使启动它的组件已经被销毁。通常,启动服务执行单个操作并且不会向调用者返回结果。例如,它可能通过网络下载或者上传文件。如果操作完成,服务需要停止自身。Bound :当应用程序组件通过调用bindService()方法绑定到服务时,服务处于bound状态。绑定服务提供客户端-服务器接口,以允许组件与服务交互、发送请求、获得结果,甚至使用进程间通信(IPC) 跨进程完成这些操作。仅当其他应用程序组件与之绑定时,绑定服务才运行。多个组件可以一次绑定到 一个服务上,当它们都解绑定时,服务被销毁。 其实还有一种就是启动Service后,绑定Service,也就是两种兼有的 不管应用程序是否为启动状态、绑定状态或者两者兼有,都能通过Intent使用服务,就像使用Activity那样。然而,开发人员可以在配置文件中将服务声明为私有的,从而阻止其他应用程序访问。 服务运行于管理它的进程的主线程,服务不会创建自己的线程,也不会运行于独立的进程(除非开发人员定义)。这意味着,如果服务要完成CPU密集工作或者阻塞操作(如MP3回放或者联网),开发人员需要在服务中创建新线程来完成这些工作。通过使用独立的线程,能减少应用程序不响应(ANR)错误的风险,并且应用程序主线程仍然能用于用户与Activity的交互。 Service中重要的方法 为了创建服务,开发人员需要创建Service类(或其子类)的子类。在实现类中,需要重写一些处理服务生命周期重要方面的回调方法,并根据需要提供组件绑定到服务的机制。 回调描述onCreate()当服务通过onStartCommand()和onBind()被第一次创建的时候,系统调用该方法。该方法在整个生命周期 中只会调用一次,如果服务已经运行,该方法不被调用onDestory()当服务不再有用或者被销毁时,系统调用该方法。你的服务需要实现该方法来清理任何资源,如线程,已注册的监听器,接收器等。该方法只会回调一次!onStartCommand()其他组件(如活动)通过调用startService()来请求启动服务时,系统调用该方法。如果你实现该方法,你有责任在工作完成时通过stopSelf()或者stopService()方法来停止服务。当客户端调用startService(Intent)方法时会回调,可多次调用StartService方法, 但不会再创建新的Service对象,而是继续复用前面产生的Service对象,但会继续回调 onStartCommand()方法IBinder onOnbind()该方法是Service都必须实现的方法,当其他组件想要通过bindService()来绑定服务时,系统调用该方法。如果你实现该方法,你需要返回IBinder对象来提供一个接口,以便客户来与服务通信。你必须实现该方法,如果你不允许绑定,则直接返回null。onUnbind()当该Service上绑定的所有客户端都断开时会回调该方法onRebind()当新的客户端与服务连接,且此前它已经通过onUnbind(Intent)通知断开连接时,系统调用该方法。 需要重写的重要回调方法有onStartCommand()、onBind()、onCreate()、onDestroy() Service 的声明 <service android: enabled= ["

JIT VS AOT

一、AOT,JIT是什么 JIT,即Just-in-time,动态(即时)编译,边运行边编译;AOT,Ahead Of Time,指运行前编译,是两种程序的编译方式 理解 jit、aot 程序主要有两种运行方式:静态编译与动态解释。静态编译的程序在执行前全部被翻译为机器码,通常将这种类型称为AOT (Ahead of time)即 “提前编译”;而解释执行的则是一句一句边翻译边运行,通常将这种类型称为JIT(Just-in-time)即“即时编译”。AOT程序的典型代表是用C/C++开发的应用,它们必须在执行前编译成机器码,而JIT的代表则非常多,如JavaScript、Python等,事实上,所有脚本语言都支持JIT模式。但需要注意的是JIT和AOT指的是程序运行方式,和编程语言并非强关联的,有些语言既可以以JIT方式运行也可以以AOT方式运行,如Java、Python,它们可以在第一次执行时编译成中间字节码、然后在之后执行时可以直接执行字节码,也许有人会说,中间字节码并非机器码,在程序执行时仍然需要动态将字节码转为机器码,是的,这没有错,不过通常我们区分是否为AOT的标准就是看代码在执行之前是否需要编译,只要需要编译,无论其编译产物是字节码还是机器码,都属于AOT。 2. 区别 这两种编译方式的主要区别在于是否在“运行时”进行编译 优劣 JIT优点: 可以根据当前硬件情况实时编译生成最优机器指令(ps. AOT也可以做到,在用户使用是使用字节码根据机器情况在做一次编译)可以根据当前程序的运行情况生成最优的机器指令序列当程序需要支持动态链接时,只能使用JIT可以根据进程中内存的实际情况调整代码,使内存能够更充分的利用 - JIT缺点: 编译需要占用运行时资源,会导致进程卡顿由于编译时间需要占用运行时间,对于某些代码的编译优化不能完全支持,需要在程序流畅和编译时间之间做权衡在编译准备和识别频繁使用的方法需要占用时间,使得初始编译不能达到最高性能 - AOT优点: 在程序运行前编译,可以避免在运行时的编译性能消耗和内存消耗可以在程序运行初期就达到最高性能可以显著的加快程序的启动 - AOT缺点: 在程序运行前编译会使程序安装的时间增加牺牲Java的一致性将提前编译的内容保存会占用更多的外存 二、JIT深度解析 在从事Java开始的一段时间,那时候经常可以听到什么C++的瞧不起写Java的,在一些群里也经常看到二个派的人经常互怼。Java能够这么流行与它的跨平台,语言无关性是分不开的,不管你是用Java,python还是Go,只要变成对应的标准字节码文件,那么JVM都是可以识别并执行的,但是那时候的Java之所以被C++吐槽主要还是因为Java 慢,为什么这么说呢。我们写的程序虽然能被JVM识别,但是不能被机器识别,程序要运行起来,还是得让机器能够识别你的程序,所以JVM还需要一个 解释器,这个解释器就是将你的程序转换成机器能识别的指令,然后执行,如下图 对于一个长期运行的Java进程来说,每次执行都要经过 解释器 将程序翻译成机器指令去执行,那么这个效率就不是很好,这也是为什么Java被吐槽慢的缘故,所以为了解决这个问题,才出现了 JIT。对于一些热点代码(经常被执行的,for循环)的一些代码,在运行时,JVM会将这些代码编译成机器可以执行的机器码,并缓存起来,这样下次执行这些代码的时候,就不需要再经过 解释器去编译了,机器可以直接运行这段程序,提高性能,这个就被称为 即时编译器,简称 JIT编译器。 JIT种类 在JDK1.8中HotSpot虚拟机中,内置了二个JIT,分别为C1编译器和C2编译器C1编译器:是一个简单快速的编译器,主要关注点在于局部性的优化,适用于执行时间较短或者对启动性能有要求的程序,C1编译器几乎不会对代码进行优化。C2编译器:是为长期运行的服务器端应用程序做性能调优的编译器,适用于执行时间较长或对峰值性能有要求的程序,根据各自的适配性,这种即时编译也被称为Server Compiler,但是由于C2代码超级复杂,无人维护,所以才会开发Java编写的Graal编译器代替C2。 热点代码 JIT会将一些热点代码编译成机器能够识别的机器码然后缓存起来,比如一些经常被调用的代码,还有for循环中的代码,那么JIT如何识别出哪些是热点代码呢??为什么说是一些热点代码缓存起来,而不是全部呢?因为缓存是需要空间存储的。JVM提供了一个参数 -XX:ReservedCodeCacheSize 来限制该缓存的大小,如果空间满了,JIT就无法继续编译,编译执行就会变成解释执行,程序也就会通过解释器去执行。 java -XX:+PrintFlagsFinal -version | grep ReservedCodeCacheSize 热点探测 热点探测也就是检查出那些热点代码,然后进行编译,热点探测是基于计数器的热点探测,也就是会统计每个方法被调用的次数,当次数达到一个阈值的时候,就会被认为是热点代码虚拟机为每个方法准备了俩种计数器,方法调用计数器 和 回边计数器,在确定JVM的运行参数之后,这二个计数器都会有各自的一个阈值,达到阈值就会出发JIT编译。 方法调用计数器:用于统计方法被调用的次数,客户端模式下默认是1500次,在服务端模式下默认是10000次(默认我们都是用服务端模式),我们可以使用以下命令查看 java -XX:+PrintFlagsFinal -version|grep CompileThreshold 回边计数器:用于统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为 回边,该值在服务端模式下默认是10700次 在JVM内存结构中是有一个程序计数器的,它表示的是字节码需要你执行的下一行指令的行号,当我们执行 第一次循环之后,程序又回调到for循环的第一行执行,这个就叫回边 for(int i = 0; i < 10000; i ++) { int a = i; int b = a + i; } JIT是如何优化Java性能的 方法内联 方法内联的优化是指将被调用方法的代码复制到发起调用方法中,避免发生真实的方法调用,举个例子