JVM对象创建、内存分配以及回收机制深度刨析 1、对象的创建(new)2、对象的内存分配3、判断进入老年代的方法3.1、发生gc回收3.2、大对象直接进入老年代3.3、长期存活的对象进入老年代3.4、动态年龄判断机制3.5、老年代空间分配担保机制 4、对象的回收机制4.1、判断是否是垃圾对象的算法4.1.1、引用计数法4.1.2、可达性分析算法 4.2、常见的引用类型4.3、finalize()的自救 5、辅助知识5.1、对象分配内存时并发问题的解决5.2、使用jol‐core查看对象头信息5.3、为什么要有指针压缩5.4、如何判断一个类是无用的类 1、对象的创建(new) 由上图我们可以看出,对象的创建分为以下几个步骤:
1、类加载检查:当虚拟机遇到一条new命令时,首先会检查这个符号是否能引用到具体的堆中的对象,或者说这个符号所代表的对象是否有被加载、初始化过,如果没有,则执行类的加载过程,new,对象克隆、对象序列化。
2、分配内存:在类加载完成之后,一个类的大小就已经被确定出来了,这时候就需要从堆里面划分一块内存给对象,划分内存有以下两个方法。
2.1、指针碰撞:在内存的已分配和未分配空间的中间有一个指针,指针的一边是都已经存放完整,另一边全是空闲内存,当我们需要给一个对象分配堆内存时,仅仅是将指针向后挪一个对象大小的空间而已,详情如下图所示:
2.2、空闲列表:这种的堆内存空闲空间是不规整的,所有的空闲空间会有一个空闲列表所记录,那一块有空闲,空闲多大,当需要为一个对象分配堆内存时,会根据空闲列表找到一块合适的区域,为新对象分配内存区域,并更新空闲列表,详情如下图所示:
3、初始化:给程序的静态变量赋初始值。
4、设置对象头:java对象由三大部分组成,对象头、实例数据,对齐填充字节,而对象头又分为Mark Word(一个标记)、Klass Pointer(类型指针)、数组长度(只有数组对象才有),图解关系如下图:
4.1、对象头:下图是一副对象头的详细数据,这里我们着重说一下无锁态的对象头。
4.1.1、Mark Word:在32位操作系统下占32bit,在64位操作系统占64bit,这里面存储的就是下图中的对象运行中的hashcode值,分代年龄、线程ID、偏向锁标志位等等。
4.1.2、Klass Pointer:我们在运行程序的时候,栈中存放的变量指针会指向堆,而堆中的这个对象就会有我们对象的这三大组成部分,它的这个Klass Pointer(类型指针)将会指向我们元空间里面存放的我们的代码二进制文件的类元信息,详情请看下图
//代码示例 Object1 object1 = new Object1(); Class<? extends Object1> object1Class = object1.getClass(); 4.1.3、数组长度:只有当对象是数组时,才会有这个标志位。
4.2、实例数据:我们类中存放的一些静态变量所占的空间。
4.3、对齐填充字节:我们的操作系统目前应用最多的应该就是32bit和64bit了吧,32bit是4字节,64bit是8字节,所以,当一个东西是4字节或者8字节的整数倍的时候,计算机的寻址效率是最高的,所以在每一个对象在生成自己的所有信息之后,如果不是4或者8的倍数的时候,我们就会产生一个对齐填充字节,将不足的字节部分补上。(我这里说的4或者8要根据计算机的操作位数来看)
5、执行init:设置完对象头之后,JVM底层会调用init方法,这个方法有两大作用,细节如下:
5.1、赋值:根据程序中写的初始值给对象的属性赋上真正的初始值。
5.2、执行构造方法:执行对象的构造方法,生成对象的实例。
2、对象的内存分配 对象在内存分配的时候,首先会做一个操作,叫做对象逃逸分析(前提是对象逃逸分析参数开启,JDK7之后默认开启逃逸分析),如果对象没有逃逸,将会进行一系列的判断,是否分配在栈内存,如果逃逸或者逃逸分析参数位开启,对象将直接分配到堆内存。
对象逃逸分析:可根据下面的代码分析
public Person function1() { Person person = new person(); person.setId(1); person.setName("XiaoLeLe"); return person; } public void function2() { Person person = new person(); person.setId(2); person.setName("XiaoLeLe"); } 根据上面这段代码,在function1中有一个Person的实例化对象,它被返回出了方法外,所以说明方法外还有变量引用着它,所以这个对象就逃逸出了方法,而在function2中实例化的Person的实例只在方法内部有效,方法结束后,person将销毁掉,所以,对于这种未逃逸出方法的对象,Java在为其分配内存的时候,会有一系列的判断,(开启逃逸分析参数-XX:-DoEscapeAnalysis,JDK7之后默认开启)如下图所示:
mysql 查看当前连接数
命令: show processlist; 如果是root帐号,你能看到所有用户的当前连接。如果是其它普通帐号,只能看到自己占用的连接。 show processlist;只列出前100条,如果想全列出请使用show full processlist; 1
mysql> show processlist;
这个命令中最关键的就是state列,mysql列出的状态主要有以下几种:
Checking table
正在检查数据表(这是自动的)。
Closing tables
正在将表中修改的数据刷新到磁盘中,同时正在关闭已经用完的表。这是一个很快的操作,如果不是这样的话,就应该确认磁盘空间是否已经满了或者磁盘是否正处于重负中。
Connect Out
复制从服务器正在连接主服务器。
Copying to tmp table on disk
由于临时结果集大于tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。
Creating tmp table
正在创建临时表以存放部分查询结果。
deleting from main table
服务器正在执行多表删除中的第一部分,刚删除第一个表。
deleting from reference tables
服务器正在执行多表删除中的第二部分,正在删除其他表的记录。
Flushing tables
正在执行FLUSH TABLES,等待其他线程关闭数据表。
Killed
发送了一个kill请求给某线程,那么这个线程将会检查kill标志位,同时会放弃下一个kill请求。MySQL会在每次的主循环中检查kill标志位,不过有些情况下该线程可能会过一小段才能死掉。如果该线程程被其他线程锁住了,那么kill请求会在锁释放时马上生效。
Locked
被其他查询锁住了。
Sending data
正在处理SELECT查询的记录,同时正在把结果发送给客户端。
Sorting for group
正在为GROUP BY做排序。
Sorting for order
正在为ORDER BY做排序。
Opening tables
这个过程应该会很快,除非受到其他因素的干扰。例如,在执ALTER TABLE或LOCK TABLE语句行完以前,数据表无法被其他线程打开。正尝试打开一个表。
文章目录 浅克隆与深克隆一.引用赋值二、浅克隆/深克隆2.1 浅克隆2.2 深克隆2.2.1 克隆(clone)2.2.2 序列化(Serialization) 三、实践使用3.1 浅克隆3.1.1 工具类BeanUtils和PropertyUtils进行对象复制3.1.2 指定对象实现克隆3.1.3 数组克隆 3.2 深克隆3.2.1 所有对象都实现克隆3.2.2 序列化3.2.3 Apache Commons工具包3.2.4 通过 JSON 工具类实现深克隆3.2.5 通过构造方法实现深克隆 四、参考 浅克隆与深克隆 一.引用赋值 Student stu1 = new Student(); Student stu2 = stu1; 改变stu1或stu2,对方都会跟着改变,因为是引用同个对象。
二、浅克隆/深克隆 浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制。
2.1 浅克隆 在Java语言中,通过覆盖Object类的clone()方法可以实现浅克隆。
一般步骤:
被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常), 该接口为标记接口(不含任何方法)覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。(native为本地方法) 在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址,要变一起变。
简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
2.2 深克隆 2.2.1 克隆(clone) 如果要用clone()方法实现深克隆,那么对于原型对象的引用类型成员变量,都要实现Clonenable接口。
简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
2.2.2 序列化(Serialization) 如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。
具体操作是先使对象实现Serializable接口,然后把对象写到一个流里,再从流里读出来,便可以重建对象。
三、实践使用 3.1 浅克隆 3.1.1 工具类BeanUtils和PropertyUtils进行对象复制 除BeanUtils外还有一个名为PropertyUtils的工具类,它也提供copyProperties()方法,作用与BeanUtils的同名方法十分相似,主要的区别在于BeanUtils提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而PropertyUtils不支持这个功能,但是速度会更快一些。在实际开发中,BeanUtils使用更普遍一点,犯错的风险更低一点。
BeanUtils.copyProperties(a, b); // BeanUtils.copyProperties("转换前的类", "转换后类"); 是浅拷贝
b中的存在的属性,a中一定要有,但是a中可以有多余的属性;a中与b中相同的属性都会被替换,不管是否有值;a、 b中的属性要名字相同,才能被赋值,不然的话需要手动赋值;Spring的BeanUtils的CopyProperties方法需要对应的属性有getter和setter方法;只是调用对象的set方法,并没有将所有属性拷贝。如果存在属性完全相同的内部类,但是不是同一个内部类,即分别属于各自的内部类,则spring会认为属性不同,不会copy;spring和apache的copy属性的方法源和目的参数的位置正好相反,所以导包和调用的时候都要注意一下。 注意:
场景: mounted(){ // this指向改变 setTimeout(function () { // setInterval同理 console.log(this);// 此时this指向Window对象 },1000); } 解决方法:使用箭头函数 // 箭头函数访问this实例 // 因为箭头函数本身没有绑定this 继承上一个不是箭头函数的函数的this setTimeout(() => { console.log(this); }, 500); // 使用变量保存this指向 通过变量访问this实例 let self = this; setTimeout(function() { console.log(self); // 使用self变量访问this实例 }, 1000);
如果你真的觉得很难,坚持不了了,那就放弃,既然放弃了就不要抱怨没有得到。
选择你热爱的,坚持你选择的,不抱怨放弃的。
前言 Flutter越来越火,学习Flutter的人越来越多,对于刚接触Flutter的人来说最重要的是如何学习Flutter,重点学习Flutter的哪些内容。下面是Flutter的学习路线图,学会这些你就入门了,当然这仅仅是初学者的学习路线图,前路漫漫。
了解Flutter 这是一个非常虚的概念,也不必花费非常多的时间去专门了解,只需在搜索引擎上搜索大概浏览下相关内容即可,这可以让你对Flutter有一个全面的、站在顶层的了解,了解的内容如下:
Flutter是什么、历史发展、有哪些优点。Flutter对比其他跨平台技术有哪些优势。Flutter整体框架。Flutter实现原理。Flutter响应式编程实现原理。Flutter与Dart的关系及Dart特点。 不要一看上面“原理”就感觉好高深,对于初学者要了解仅仅是思想,知道实现的思路,而不需要深入学习。
环境搭建 其实学习每一项技术首先都需要搭建环境,这并不属于学习路线的一部分,拿到这里单独说,也并不是告诉大家如何搭建环境,而是给大家推荐环境的选择,因为Flutter的开发并没有专门的IDE,可以使用vscode、android studio等,这里推荐使用android studio,系统建议Mac OS,因为Flutter目前主要用于Android和IOS的开发。
UI控件 UI控件的学习是进入Flutter的钥匙,因此第一个要学习的就是相关UI控件,Flutter系统提供的组件非常多(估计300+),难道要都要学习一遍吗?就算一天学3个控件,那也需要好几个月,这明显是不科学的,只需要学习常用的组件即可,哪些是常用组件?已经为大家整理好了常用组件及相关用法,地址:http://laomengit.com ,不仅有常用组件,还有整理了150多个组件的相关用法,不常用组件只需浏览一下,知道Flutter提供了类似的组件,用到的时候在来查阅。
Dart基础 Flutter是用Dart语言开发的,所以我们需要Dart语言的基础知识,如果你有其他高级语言的基础,这一部分基本可以略过,只需了解如下内容:
如何导入包。 异步编程(Future、async、await)。注释。命名规范如何定义变量作用域(private、public)因为这些方面和其他高级语言有些区别,至于其他的方法差别不大。 对于没有其他语言基础,甚至没有编程基础,这时候你需要找一本Dart基础的书学习其中的知识。
手势事件及事件传递机制 Flutter中有点击、长按、双击等各种手势事件,学习如何给控件绑定手势事件及事件的处理,最后需要对事件的传递机制有一定的了解。
动画 Flutter提供了大量的动画组件,但我们不仅仅是会使用这些组件,还要了解动画组件的实现原理,自定义动画组件。
网络请求 任何一个App基本都离不开请求网络,学会网络请求数据,强烈建议先了解下Dart自带网络请求,然后使用dio第三方库获取网络请求。
本地数据存储 本地数据的存储有如下几种方式:
文件读取、写入。shared_preferences:通过key-value的方式存放数据,适合存储简单的数据,比如配置数据等。sqflite:数据库的形式存储数据,适合存储大量数据。 路由管理 什么是路由?简单的理解就是页面的跳转,从一个页面跳转到另一个页面。路由管理就是对这些页面跳转到管理。
国际化 如果你的App需要国际化,那么你需要学习国际化相关的内容,如何设置不同国家的文案等。当然这并不是必须的。
混合开发 混合开发是一个非常重要的内容,即使你完全使用Flutter开发一个全新的App,也可能涉及到原生开发。这部分你需要了解如下内容:
在原生项目中增加Flutter模块。Flutter与原生通信。Flutter与原生通信更为重要,因为一些涉及硬件功能Flutter必须通过原生实现,比如相机、蓝牙等。 学习 Flutter 的理由 在我接触在大多 Flutter 萌新里,有很大一部分其实是“被迫”使用 Flutter,因为领导或者老板要求用 Flutter ,所以不得不“欲拒还迎”地开始学习 Flutter,这就是最“有力的”理由之一 :“老板(领导)要”,除非你选择“跳槽”飞出三界。
虽然 Flutter 是全新的跨平台技术,但其背后的框架原理和底层设计思想,无论是底层渲染机制与事件处理方式,还是组件化解耦思路,亦或是工程化整体方法等,与原生 Android / iOS 开发并没有本质区别,甚至还从 React Native 那里吸收了不少优秀的设计理念。就连 Flutter所采用的 Dart 语言,关于信息表达和处理的方式,也有诸多其他优秀编程语言的影子。
因此,从本质上看,Flutter 并没有开创新的概念。这也就意味着,如果我们在学习 Flutter时,能够深入进去搞懂它的原理、设计思路和通用理念,并与过往的开发经验相结合,建立起属于自己的知识体系抽象层次,而不是仅停留在应用层 API 的使用上,就摆脱了经验与平台的强绑定。
Flutter 到底该怎么学? 这份谷歌开源的《Flutter完整开发实战详解》,希望可以帮助大家用最短时间学习Flutter。教程通俗易懂,实例丰富,既有基础知识,也有进阶技能,能够帮助读门者快速入进阶,快收藏起来!!!
执行命令composer update报错:
先把抛出报错的代码跳过:
然后在页面运行时发现在D盘下少了storage,framework,sessions文件夹,
file_put_contents(D:\storage\framework/sessions/sT26yYBdbbIEprKmGkyc7CikgTkdSDGiUixJ25rG): failed to open stream: No such file or directory
重新在D盘创建,然后重新运行就好了。
点击“终码一生”,关注,置顶公众号
每日技术干货,第一时间送达!
1、前言 索引策略是指创建使用索引所要遵循的规则,换句话说,违背了这些规则会导致索引失效或者查询效率降低。
策略1:尽量考虑覆盖索引
策略2:遵循最左前缀匹配
策略3:范围查询字段放最后
策略4:不对索引字段进行逻辑操作
策略5:尽量全值匹配
策略6:Like查询,左侧尽量不要加%
策略7:注意null/not null 可能对索引有影响
策略8:尽量减少使用不等于
策略9:字符类型务必加上引号
策略10:OR关键字左右尽量都为索引列
2、介绍 测试数据表:
show index from employees; 策略1:尽量考虑覆盖索引
覆盖索引:SQL只需要通过遍历索引树就可以返回所需要查询的数据,而不必通过辅助索引查到主键值之后再去查询数据(回表操作)。回表操作的详细介绍可以参考本人《MySQL慢查询优化》系列博文之索引。
EG:
EXPLAIN SELECT emp_no,birth_date,gender FROM employees WHERE gender ='M' ; Using index:表示已经使用了覆盖索引。
策略2:遵循最左前缀匹配
联合索引命中必须遵循“最左前缀法则”。即SQL查询Where条件字段必须从索引的最左前列开始匹配,不能跳过索引中的列。联合索引又称复合索引,类似于书籍的目录,多级的目录结构中子目录依赖于父级目录存在,也是遵循“最左前缀法则”。
联合索引结构分析,示例:
EXPLAIN SELECT * FROM employees WHERE birth_date = '1963-06-01' AND gender ='F'; 注:表存在多个索引时,即使Where条件满足最左前缀规则,SQL执行时也未必一定会命中联合索引,根据性能可能直接使用了主键索引。
EG:
EXPLAIN SELECT * FROM employees WHERE emp_no = 10010 AND birth_date = '1963-06-01' AND gender ='F'; PRIMARY KEY (`emp_no`)
.el-icon-plus{ font-size:30px; //改变图标大小 line-height: 110px; //通过设置行高让图标垂直居中 color: #409EFF; //设置图标颜色 }
1.使用jquery中带的getJSON方法来传递我们的接口地址以及我们的方法
$.getJSON('http://localhost:5000/api/userid/list',function(json){ console.log(json); }); 2.用ajax的方法来进行编写这里我们通过success后面的函数来进行方法的调用
$.ajax({ url: 'http://localhost:5000/api/userid/list',//请求的地址 type: 'get',//请求的方式 data: '',//携带到后端的参数 dataType: 'json',//期望后端返回的数据类型 success: function (res) { console.log(res); },//成功的回调函数 res就是后端响应回来的数据 })
你了解业务运作方式吗?你了解为什么即使失业人数达到两位数,软件工程师也可以要求如此疯狂的薪水吗?为什么编程是如此宝贵的技能?为什么客户愿意为某些超级基本的Web表单向你的公司每年支付50,000美元?你是否觉得他们被骗了?
领导可以放心地让你去负责面试候选人吗?你是否擅长通过有限的信息来对人员进行分类,并可视化他们和团队的适合程度?你能识别出在什么情况下,在工程方面优秀的候选人却不能很好地融入公司文化吗?这种候选人你会建议录取吗?同样,即使你和候选人在Zoom里聊了5分钟就知道他不可能被录取,你是否还可以确保他仍然可以从你们的聊天中学到东西?毕竟,语言在网络上的传播速度是很快的。
假如今天是12月28日,你被困在办公室。你今年有点疯狂,在9月中旬就把今年所有的带薪休假糟蹋完了。此时此刻,同事们都休假出去high了。你还能按时上班吗?领导不在身边惩罚你,你是否打算半途而废?这种情形下,是否需要领导强迫你你才能尽全力工作?
机会成本是一件必须考虑的事。你在平衡技术债务和推动业务发展方面做得如何?你是否会重构发现的每个微小的编码样式问题?毕竟大家都很难承认“这段代码很烦人,但它确实有效,需要花费四个小时的清理时间,这段时间可以花在构建其他功能上,而这是很多客户都在请求的”。
你知道如何向你的下属反馈他们的绩效吗?你和他们有良好的工作关系吗?你是否将他们视为敌人?你是否正在积极尝试减轻他们的压力,使他们的生活更轻松?你是否曾经说过“你们那边有什么烦人的任务我可以帮忙削减吗”?公司雇人都是有原因的,你的下属可能比你想象的更有经验和资格。
你有能力扑灭生产大火吗?你是否会在遇到大麻烦时惊慌、不知所措(比如AWS中断使网站瘫痪、不小心搞丢了customer_invoices表单、某些错误导致了不同用户帐户之间的数据泄漏等)?你是会在压力之下崩溃,还是会在解决问题的同时保持镇静,并与其他部门进行有效的沟通?
虽然我说的话不能代表所有的初级工程师,但我确实知道自己八年前开始在该领域工作时,在情绪方面的处理是非常糟糕的。
那时的我极度自信,与人沟通很糟糕,不能毫不犹豫地处理建设性批评,为无关的小事与我的老板激烈争论,浪费无数宝贵时间来解决根本不重要的问题,总是觉得自己应该得到大幅度的加薪(却不付出额外的努力来赚钱)并为之苦恼和抱怨,天天花 45 分钟打乒乓球、玩游戏(在慢悠悠吃了一个小时午餐后)……
我为我的老板带来价值了吗?
是有的。
你能把当时的我放心地关 30 分钟,让我在此期间独立工作、不出幺蛾子、不拿头撞墙吗?
绝对不可能。
而高级开发者,就会在工作中解决问题,而非制造问题。
他们减少压力。他们按时完成任务。他们知道如何编写经得起时间考验、可维护的代码。他们值得更高的工资。他们对项目的方向可以有准确的把控。他们可以发现当前流程中的缺陷,并使每个人都接受他们的想法以进行改进。他们可以指导应届毕业生。他们处事冷静,不会在周二与你的最大客户的电话会议上情绪崩溃、破口大骂。
很多人想踏实当个技术人员,并不想一直向上升去当领导当主管,我认为这种想法没什么问题。编程是目前最令人鼓舞的职业之一,许多企业愿意给经验丰富的“老兵”开很多很多工资,来保证业务进行顺利。
话虽这么说,总会有少数工程师最终决定有一天挂断 IDE,并开始过渡到管理层。
挺恶心的。
太长不看版:反正现在就我来说,转管理层这条路是可选的,但绝对不是适合所有人的。
如果你具有扎实的沟通技巧,并且确实愿意开会开一整天(这样你可以消除干扰、帮助队友争取更多时间来高效完成工作),那么你进入管理层就是非常有意义的。
如果你由于其他任何原因转行管理层(即使刚读了我的博客文章,也因为受到雇主的压力、较高的薪水、害怕技术技能过时的焦虑等等),那你的日子可能就难过了。
回顾我的旅程,能从初级开发者过渡到高级开发者,归功于我每周(在繁重的编码任务之间)都试着花几个小时专注于以下事件:
改进我们进行技术面试的方式,保证我们与候选人之间的沟通信噪比更高(如改善我们的面试问题、重新考虑我们的电子邮件模板、考虑是否要给面试者布置线下笔试题、反思我们对工作的描述是否准确、我们向哪里投放招聘广告、换位思考如果我正在寻找工作会如何回复该招聘信息、如何在候选人做出决定之前使其更深入地了解我们的公司文化和发展历程等等)。
与产品团队合作,以更细致的方式对即将开展的工作进行分类,从而使产品团队和最终要去接收JIRA tickets的工程师之间的沟通更加顺畅,而不需要磨叽好几个来回。
组织团建活动和团队聚餐。
当CEO/CTO为即将到来的季度制定的目标听起来有点过于乐观时,向他们提出提醒和意见,以免团队其他成员受不了过分辛苦的工作而逃离你们公司。
最好能每周与所有大的客户进行一次确认电话(亲自回答他们所有的技术问题,并确保双方之间的关系保持健康)。
用6个月的时间进行积极的安全审核,不断提醒客户我们会认真对待他们的隐私,并在公司发展的每个检查点努力完善我们的流程。
找出其他开发人员在知识上的不足之处,然后让他们查缺补漏(使用能激发他们学习兴趣的方式):如使用vim宏处理CSV文件、Linux终端中实用的短命令、高级SQL命令、如何使PR描述更具描述性、解释负载平衡器如何工作、讨论合并和重新定基之间的区别等。
帮助设计团队在花数小时将线框转换为高保真模型之前,先弄清楚哪些功能易于开发。
改进我们的流程,让其他部门知道何时会增加新功能(编写更好的发行说明、在每周的内部产品演示中回答他们的问题、帮助他们编写客户能理解的外部文档),因为没人知道的功能不会解决任何实际问题。
上面的列表还可以一直一直往下写,而其中大部分条目不需要用到 Visual Studio。
几年后,许多高级工程师走的路都是类似的。你可能在不知不觉中就变成了小领导,每天有 6 个人向你汇报工作。
但要做到这种程度,与自身的努力也是离不开的,只有不断地学习不断地进步,我们才能跟上时代的进步!
最后
==============================================================
在这里我分享一份由多位大佬亲自收录整理的Android学习PDF+架构视频
+面试文档+源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料
这些都是我现在闲暇时还会反复翻阅的精品资料。里面对近几年的大厂面试高频知识点都有详细的讲解。相信可以有效地帮助大家掌握知识、理解原理,帮助大家在未来取得一份不错的答卷。
当然,你也可以拿去查漏补缺,提升自身的竞争力。
真心希望可以帮助到大家,Android路漫漫,共勉!
如果你有需要的话,只需 点击这里快速免费获取
识、理解原理,帮助大家在未来取得一份不错的答卷。
当然,你也可以拿去查漏补缺,提升自身的竞争力。
真心希望可以帮助到大家,Android路漫漫,共勉!
如果你有需要的话,只需 点击这里快速免费获取
前置:
文章中用到的数据
链接:https://pan.baidu.com/s/1rKLM45dq_xIKxcI54Nq0qg 提取码:c298
公式:
样本标准差公式
年化收益波动率公式
年化收益波动率公式可以转换为【标准差的平方*250,再取平方根】
计算过程(jupyter notebook):
import pandas as pd import math df = pd.read_csv('temptemp.csv',encoding='utf-8') df['o_date'] = df['date'] df['o_date'] = pd.to_datetime(df['o_date']) df.dropna(inplace=True) df.sort_values(by='o_date', ascending=True, inplace=True) # value值为净值,收益率为后一天减去前一天再除以前一天 df['change'] = (df['value']-df['value'].shift(1))/df['value'].shift(1) df.head() # 日收益率的标准差 day_std = df['change'].std() annual_std = math.sqrt(day_std**2*250) annual_std
在无线蓝牙耳机成为刚需的时代,从形形色色的耳机中,想要寻找一款在价格和功能乃至外观上都满意的耳机产品是十分不易的。众多耳机厂商也意识到了用户的需求,便在产品类别上做了不少文章。于是半入耳式、挂耳式耳机相继出现了,甚至有了骨传导耳机。但这并不是用户真正想要的东西,要想吸引用户买单,除了产品种类还得从产品品质入手。
在我看来哈氪品牌在耳机领域的发展和定位有着自己的特色。哈氪的每一款产品都有一个设计理念,这种理念不仅体现在它的每个产品的广告视频里,更是融入到了整个产品的设计中,可以说到目前为止它的每个作品都是主题鲜明的。
哈氪游侠、哈氪Time、哈氪觉醒、哈氪拾光,每个产品的定位都很明确,设计也都很有辨识度。今天要跟大家重点介绍的这款哈氪新品是哈氪零度,是不是有一种清爽的感觉?
没错,哈氪零度的设计理念就是“一酷到底”,给你零度冰爽的感觉,这一点从它的外观上就可以清晰地看出来。
充电仓采用冰元素流线型设计,外部采用了透明材质双色注塑壳,标志性流线型纹理像是隐现于高透“冰面”之下,相当有立体感。与同款纹理小冰棍耳机交相辉映,观感清爽舒适,彰显运动时尚的格调,美感和质感十足。
这得益于哈氪创新性应用高透&耐高温双色复合材料,增加了两道抛光打磨工序,突破产业传统单材质工艺限制,专门打造了透明冰晶的冰封外观,颜值在耳机界简直是绝绝子!这一产品的设计是由2022北京冬奥会吉祥物总设计师曹雪教授担任美学指导,充电仓从概念设计到量产历经10个月,足见哈氪对这款产品的重视,也说明了哈氪的研发态度。
哈氪零度产品不仅颜值高,音效质量也是杠杠滴,不然不成了中看不中用的花瓶了!
这款产品是半入耳式的类型,为了让用户佩戴舒适,特意优化了半入耳的人体工学设计,单耳重量仅4g,设计上也减轻了压力感,佩戴起来还是比较轻盈舒适的。因为耳机曲面与耳朵的贴合设计得很轻缓,也不容易掉落,可以放心地运动。
操作起来也很方便,支持极简一键式操作,播放、切换、接听电话等操作触控起来很简单。同时IPX4级防水设计也不用太担心汗水问题。
哈氪零度搭载了5.2真无线蓝牙芯片,信号传输稳定,性能全面升级。13mm直径高性能动圈工艺,使得音色和谐动听,同时也使得音色不失真。搭配充电仓使用,续航时间可以达到24小时,可以说很能打了。
哈氪零度还注重降噪功能,支持应用麦克风阵列波束成形技术+全新升级智能神经网络DNN通话降噪算法,有很好的通话降噪能力。
这绝对称得上是一款颜值与品质兼具的精致耳机,不同于其他耳机产品,它的外观设计个性十足,以往的产品也很抢手,相信这款产品也会受到更多人的喜欢。
前几天,移植一个Qt项目到银河麒麟系统上,项目中包含了opencv,因此安装编译了相同版本的opencv和zlib,但是结果在qtcreator上编译都没过去,报错 collect2:error:ld return 1 exit status,因为之前遇到多这个,一般是include和lib不全的问题(本质上是.h头文件中定义了某个函数声明,但是对应的cpp中没有实现),网上搜这个问题,也大多说的是这个问题。
但是找了好久,并且在原系统没有这个问题,于是排除了这个原因。
然后又查看了两个系统上编译环境的配置,发现也是一样的,用的都是系统自带的g++编译器,版本也一致,这就让人想不通了,究竟是哪里错了呢。
然后我就想从qtcreator中找报错信息,不至于除了collect2:error:ld return 1 exit status,什么也没有了吧,于是,我发现了,就在底部应用程序输出旁边,有编译输出:libopencv_imgcodecs.so:对’inflateValidate@ZLIB_1.2.9’未定义的引用,哎,是自己对编译器不熟悉,原来是有报错信息的。
于是开始百度这个错误,发现大多是说zlib库的版本问题,但是我已经下载了这个库啊,并且我在项目的pro配置文件中,引入了编译安装后的libz.so文件(默认安装路径)。
LIBS+=/usr/local/lib/libz.so 又然后,我尝试把这个库的引入去掉,发现还是这个报错,我感觉发现了问题所在,于是我看到了在LIBS的最后,我加了一个
LIBS+=-lz 这是当时为了解决ffmpeg的库添加的一个库,当时没理解,原来这就是zlib库,也就是报错中的ZLIB,于是我就想找到系统这个-lz究竟引用的是哪里的库,百度无果,用whereis也没有找到,我就直接在整个电脑上搜索,果然,被我找到了。在 /lib/aarch64-linux-gnu/ 下,我看到了libz.so.1和libz.so.1.2.8,libz.so.1是指向libz.so.1.2.8的软链接,实质上就是libz.so.1.2.8,从名字上看已经发现了报错的原因:libz的版本不对
于是我抱着尝试的心态,用自己编译后的libz.so.1.2.9,替换了/lib/aarch64-linux-gnu/libz.so.1.2.8,并且把libz.so.1指向了libz.so.1.2.9,然后再进行编译,编译通过了!
虽然解决了问题,但是我没明白为什么在之前的系统上没有问题,因为之前的系统也是银河麒麟,并且我同样找到了/lib/aarch64-linux-gnu/下,zlib版本也是1.2.8,但是就没有这个报错,同样的代码,同样的环境,但是编译结果都不同。
解决这个问题花了整整1天,本来都打算放弃了,但是多亏了发现编译输出以及后边系统libz版本的问题,这次的debug也算是给以后一个解决问题的思路,相信报错信息,因为错了就是错了,操作系统不同这种玄学问题,也不是我们能解释的。
记录一下,今年遇到的第一个头疼的bug。
cout<<vis[1]<<endl;
}
return 0;
}
第三题
===
/*
给了n个数字,然后q次查询,每次查询给了若干个数组,求这些数组合并后的第k小
范围都是1e5
* @Author: 7QQQQQQQ
* @IDE: vscode
* @Date: 2021-03-21 20:14:53
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+50;
vector<``int``> e[N];
int cnt[N];
int main(){
int
n;cin>>n;
for``(``int i=1;i<=n;i++){
cin>>cnt[i];
for``(``int j=1;j<=cnt[i];j++){
int x;cin>>x;
e[i].push_back(x);
}
sort(e[i].begin(),e[i].end());
}
int Q;cin>>Q;
while``(Q--){
int num;cin>>num;
vector<``int``> query;
for``(``int i=0;i<num;i++){
int x;cin>>x;
query.push_back(x);
}
int K;cin>>K;
int L=0,R=1e9;
while``(L+1<R){
Top Programming Languages - IEEE Spectrumhttps://spectrum.ieee.org/top-programming-languages/#/index/2021/1/1/1/1/1/50/1/50/1/50/1/30/1/30/1/20/1/20/1/5/1/50/1/100/1/50/ 官网链接在上面,可以点进去瞅瞅。python依旧排第一,我关心的C排第三。用纯C的除了底层开发(驱动、嵌入式、网络等等),其他领域用的很少了。
1、基本算法
# 十进制数转换为 N 进制 # num -- 十进制整数 base -- 转换的进制 def binchange(num: int, base: int) -> str: s = '' while num: i = num % base s += str(i) num = int(num / base) return s[::-1] print(binchange(100, 16)) # 40 print(binchange(25,8)) # 32 2、内置函数
# 二进制转换成十进制:int()函数 将一个字符串或数字转换为整型 (x, base) x:字符串或数字 base:进制数,默认十进制。 v = "0b111111" a = int(v, 2) print(a) # 63 # 十进制转换成二进制:bin()函数 返回一个整数 int 或者长整数 long int 的二进制表示 v2 = 17 print(bin(v2)) # 0b10001 # 八进制转换成十进制 # Python2.
不小心格式化了硬盘怎么恢复数据?在我们使用电脑的时候,会使用硬盘保存一些重要的资料。
也许你会经历一下情况导致硬盘里面的资料丢失:
格式化磁盘重装系统清理病毒等等 如果是非常重要的内容,想必很多用户是需要找回这些资料的。不过大多数的用户都认为对硬盘进行格式化就是彻底地清空了数据,再没有办法可以进行恢复,其实并不是无法恢复。很多的格式化仅仅只是表面的进行了清理数据,如果使用专业数据恢复工具还是可以恢复成功的。
下载Windows版本https://www.easeus.com.cn/download/trial/yiwo_recovery.exe 下载Mac版本https://www.easeus.com.cn/download/trial/yiwo_recovery_mac.dmg 找回硬盘丢失后的数据,最简单并且恢复成功率最高的方法就是通过文件备份进行恢复,但是大部分用户都没有文件备份的习惯,所以在硬盘被格式化之后无法利用备份还原。
如果无法使用备份进行还原,可以使用易我数据恢复软件来针对格式化的硬盘进行扫描然后去恢复。易我数据恢复软件可用于因删除、误操作、系统问题和硬盘问题等导致的数据丢失,支持从存储硬盘、U盘、SD卡和记忆卡等存储设备中找回丢失的文档、邮件、图片、视频等。效果好,而且操作起来也非常的简单!
步骤 1.
安装后启动易我数据恢复格式化恢复软件。
选择不小心被格式化的硬盘,点击「扫描」。
步骤 2.
开始扫描查找硬盘上丢失的文件。
在扫描的过程中,查找到的文件会逐一显示在扫描结果中。
步骤 3.
扫描结束后,浏览查找到的文件。可以优先在「丢失文件」中搜索因为格式化而丢失的文件。
勾选想要恢复的文件,点击「恢复」。
提醒
选择不曾丢失数据的位置保存还原回来的文件,请勿保存在原来的位置!
动态盘转换成基本盘是很多人都会遇到的一个难题,一个操作不当,就会导致硬盘上的所有数据丢失。那么如何在确保数据完全保留而不会丢失的情况下,将动态盘转换成基本盘呢?有些人已经知道了答案,那就是使用专业的分区软件来解决这个问题,安全地将动态盘转换成基本盘。紧接着另一个问题又来了,分区软件如何将动态盘转换成基本盘呢?下面小编就给大家详述一下具体过程。
首先,下载安装分区软件——易我分区大师。然后,运行易我分区大师,按照以下步骤操作:
步骤1:在Windows计算机上安装并打开 易我分区大师 。 步骤2:选择要转换为基本磁盘的动态磁盘。右键点击,选择「转换到基本盘」。
步骤3:点击弹出窗口上的「确定」,将此转换添加到待执行操作。
步骤4:点击左上角的「执行1个操作」按钮,点击「应用」按钮,开始将动态磁盘转换为基本磁盘。然后,您还可以使用磁盘分区管理软件来调整/移动、克隆、合并、格式化和删除分区。 易我分区大师作为一款多合一磁盘管理工具,可以创建、格式化、隐藏、删除、擦除分区,并且能够轻松调整分区大小、合并分区、合理分配空间,从而确保用户充分利用Windows PC & Server磁盘空间;不仅支持基本/动态磁盘互转,MBR/GPT盘互转,还支持FAT/NTFS文件系统格式互转;附加克隆功能,可克隆分区或磁盘,将操作系统迁移至更大更新的磁盘,优化系统运行;还可扫描并恢复磁盘上的丢失分区,解决分区意外删除导致数据丢失的问题;创建启动盘,即使系统无法正常启动,也可以通过启动盘启动并管理磁盘!
以上就是易我分区大师这款分区软件如何将动态盘转换成基本盘的基本过程介绍,相信大家已经学会了,那就赶紧试试吧!
免费下载支持 Windowshttps://www.easeus.com.cn/download/trial/yiwo_partition.exe
转换 —— transform
目录
2D转换
移动 —— translate
旋转 —— rotate
缩放 —— scale
2D转换综合写法
设置转换中心点
3D转换
3D移动 —— translate3d
2D转换 —— rotate3d
透视 —— perspective
3D呈现 —— transform-style
练习
使盒子居中
旋转出内容框
盒子的两面
2D转换 移动 —— translate 1.语法:
transform:translate(x,y);
或分开写:
transform:translateX(n);
transform:translateY(n);
2.重点:
可以沿X或Y轴移动; 注意:X/Y轴起点为左上角其的移动不影响其它元素;.translate的百分比单位相对于自身元素的大小,translate:(50%,50%)自身的一半;对行内标签无效果。 旋转 —— rotate 1.语法:
transform:rotate(度数deg);
2.重点:
度数为正时,为顺时针转;度数为负时,为逆时针转;默认旋转中心为元素中心点。 缩放 —— scale 1.语法:
transform:scale(x,y);
x,y同时缩放:
transform:scale(n) ;
2.重点:
x代表宽度缩放;y代表高度缩放。x,y没有单位,值为原来的倍数。默认缩放中心为元素中心点。不影响其他元素。 2D转换综合写法 1.同时使用多个转换,格式:
transform: translate() rotate() scale() ;
Maven的生命周期: 讲解Maven测试篇之前将首先介绍一下Maven生命周期的相关概念,如果你熟知这部分概念可以略过此小节内容。
通常,我们在构建一个项目的时候,不外乎是对其进行清理、编译、测试和部署等操作。对于大多数项目,我们每次都要重复这些必要的过程,而Maven正是对这些必要的构建过程进行了抽象,它以项目的清理、初始化、编译、测试、打包、部署等构建步骤作为项目生命周期的各个阶段。
每个Maven项目,都有三个相互独立的生命周期,其中包括:
clean生命周期:负责项目的清理工作;default生命周期:负责项目的部署;site生命周期:负责创建项目的文档站点; 其中各个生命周期又包含不同的阶段(如下图所示),例如clean生命周期下有pre-clean、clean和post-clean三个阶段,分别负责项目清理前的工作、清理上次构建的项目和项目清理后的工作,这些阶段是顺序执行的,也就是说,当你执行pre-clean阶段的时候,clean和post-clean阶段不会被执行,当你执行clean阶段的时候,pre-clean阶段和clean阶段会被执行,post-clean阶段不会被执行,当你执行post-clean阶段时候,pre-clean、clean和post-clean这三个阶段都会依次被执行。同理,default生命周期和site生命周期下也分为各个不同的阶段,这些阶段和clean生命周期下的各个阶段一样,后面阶段的执行依赖于前面的阶段执行。
Maven生命周期及生命周期下的阶段示意图
此时你可能认为,当执行default生命周期下的某个阶段时,clean生命周期下的所有阶段也会被执行,其实并非这样。正如之前所说,Maven项目的每个生命周期是相互独立的,执行某个生命周期下的某个阶段,不会对另外两个生命周期下的任何阶段产生影响。
如果要对Maven生命周期下的某个阶段进行调用,运行相应的Maven命令即可。例如,调用clean生命周期下的clean阶段,运行如下命令:
mvn clean 此时clean 生命周期下的pre-clean和clean阶段将被执行。
如果要调用default 生命周期下的package阶段,运行如下命令: mvn package 此时在default生命周期内,package阶段之前所有的阶段将被执行,package阶段也将被执行。
如果要对项目进行打包,在项目打包之前可能需要对项目上一次的构建进行删除清理,运行如下命令:
mvn clean package 此时在clean生命周期内,clean阶段之前所有的阶段将被执行,clean阶段也将被执行。default生命周期内package阶段之前所有的阶段和package阶段也将被执行。
如果要执行项目测试,运行如下命令:
mvn test 此时在default生命周期内,test阶段之前所有的阶段将被执行,test阶段也将被执行。
Maven的每个阶段都绑定了一个或多个插件,调用某个阶段时,具体任务将交由这个阶段所绑定的插件来完成。比如进行项目测试时,需要调用default生命周期下的test阶段,但具体任务将是交由“maven-surefire-plugin”插件完成的,因为test阶段与“maven-surefire-plngin”插件进行了绑定。这个“maven-surefire-plngin” 插件就是一个测试运行器,它与主流的测试框架(Junit3、Junit4和TestNG)进行了集成。
引用“maven-surefire-plngin”插件依赖 因为“maven-surefire-plngin”插件是Maven内置绑定的,即使你不在“pom.xml”文件中对”maven-surefire-plngin”插件做相关配置,调用default生命周期的test阶段时,Maven也会使用“maven-surefire-plngin”插件执行相关任务。当然你还可以在“pom.xml”文件中自定义配置这个插件:
<project> [...] <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.20</version> </plugin> </plugins> </pluginManagement> </build> [...] </project> 整合TestNG 使用TestNG作为测试框架时,需要在Maven项目的“pom.xml”文件中配置TestNG依赖,这里需要在<scope/>元素中将TestNG的依赖范围配置为test。
<dependencies> [...] <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.9.8</version> <scope>test</scope> </dependency> [...] </dependencies> 你还可以在项目路径下创建一个“testng.xml”文件,这个文件主要用来描述测试套件和测试执行相关参数的配置,但它不是TesgNG必须的配置文件,如果你没有创建“testng.xml”文件,也就不需要对“maven-surefire-plngin”插件做“testng.xml”文件的相关配置。
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > <suite name="testSuite"> <test name="test"> <classes> <class name=“ATest"
导入该类所在的包,Java中键盘输入的函数在所在的包为java.util.Scanner;scanner类表示一个简单的用户扫描器,可以接受用户的输入。创建该对象,即声明变量。调用里面的功能,定义输入的值变量,键盘输入的值赋值给谁??注意Scanner包中拥有next方法,仔细查看Javaapi文档,next用于将输入的下一个标记为对应的类型,包括nextint,nextlong等等数据类型。 运行以下代码接受用户的输入年龄,姓名,成绩等
//1.引入Java的包 import java.util.Scanner; public class Test { public static void main(String [] args){ //创建对象用于接受用户的输入,test为一个对象 Scanner test=new Scanner(System.in); System.out.println("请输入您的年龄"); int age=test.nextInt(); System.out.println("请输入您的姓名"); String name=test.next(); System.out.println("尊敬的"+name+"您的年龄为"+age); } }
近日,由等级保护测评主办的“2021年网络安全优秀企业及产品名录”评选结果公布,经过专家评审和大众投票等多个环节,默安科技凭借强大的技术实力与丰富的实践经验,成功入选2021年网络安全优秀企业“云安全十强”榜单。
本次评选活动由等级保护测评主办,旨在促进我国网络安全产业自主创新能力,共同做好网络安全工作做出鼓励与鞭策,同时为客户选择网络安全解决方案和产品提供参考依据。据悉,活动启动后参选的累计申报项目达427项,期间大众投票环节参与人数达到88745人,累计预览量达247966次,累计总票数达736764票。
伴随着云计算逐步成为数字经济的技术底座、企业数字化转型的关键基础设施,云计算所面对的潜在风险也显著提升。云安全既是企业实现快速业务拓展的有效支撑,也是业务顺利推进的可靠保障,坚实的安全底座是助力企业更好发挥云服务能力的关键。
作为云计算时代的新兴网络安全公司,默安科技提供的整体解决方案贯穿左移开发安全(DevSecOps)与智慧运营安全(AISecOps)两大环节,帮助客户构建基于云的下一代安全体系,实现安全风险全生命周期管理。
此次入选2021年网络安全优秀企业“云安全十强”,是对默安科技在云安全领域综合实力的高度认可。未来,默安科技将继续秉承可持续安全运营理念,注重实际运行效果,致力于成为客户值得信赖的安全伙伴。
等级保护测评创建于2017年,旨在发布与解读国家网络安全相关政策,分享最新行业动态及前沿资讯,集结中坚力量聚合产业势能,为提升我国网络安全技术创新搭建全国性的交流平台。
ROS安装 后记:提前说一下,按照网上的大部分ROS安装教程你会在下面的第四步遇到问题,然后在网上找各种解决办法,运气好的话你会很快解决,但是也可能卡住半天没解决(比如我hh),这个时候推荐用鱼香ROS的工具,帮助你一分钟解决第四步遇到的问题。
系统:Ubuntu 18.04
安装ROS版本:melodic
前四个勾选
打开命令终端,输入以下命令
1.添加ROS源 sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' 2.添加秘钥 sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 3.安装ROS sudo apt-get update 如果部分不成功更换电脑连接手机热点试试,本人第一次安装就成功了。
sudo apt-get install ros-melodic-desktop-full 大概需要两个多G,如果有足够空间,输入Y进行安装
4.安装并初始化rosdep sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential sudo rosdep init rosdep update 但是由于网络原因,大部分小伙伴在执行sudo rosdep init时都会报错无法访问链接,因为rosdepc使用的是国内的源,rosdep初始化失败是因为其使用的是github,国内无法访问。
这里只要更换为小鱼dalao制作的国内镜像rosdepc,即可解决该问题。
wget http://fishros.com/install -O fishros && . fishros ### 上行代码运行后根据提示输入4 ### 输入回车 #根据提示rosdep初始化 rosdepc update #更新ros源 5.
1.动态sql语句查询
简单来说,查询的字段,查询的表格,还有where条件都是变量。可以作为选择屏幕或者接口数据输入,最后得出输入条件的数据。具有通用性。 其中,动态查询的关键在于:sql语句查询结果所放置内表的创建。
2.源代码
PARAMETERS: p_field TYPE char200, p_table TYPE char10, p_whe TYPE char200. *第一种创建动态内表,根据所查询的字段,去生成内表 DATA: d_ref TYPE REF TO data, lt_alv_cat TYPE TABLE OF lvc_s_fcat, ls_alv_cat LIKE LINE OF lt_alv_cat. "根据填写的字段来自建内表 CONDENSE p_field NO-GAPS. "去掉空格, "p_field:填写字段规范: CARRID ,CONNID, FLDATE 最后一个字段不填逗号 "把填写的内容,根据逗号进行拆分 DATA:lt_field TYPE TABLE OF lvc_rfname. SPLIT p_field AT ',' INTO TABLE lt_field. "循环变成fieldcat LOOP AT lt_field INTO DATA(ls_field). *根据取出的字段目录生成参考字段目录 ls_alv_cat-fieldname = ls_field. "字段名 ls_alv_cat-ref_table = p_table. "参考表 ls_alv_cat-ref_table = p_table.
HashMap.computeIfAbsent
如果需要向Map中push一个键值对,需要判断K key在当前map中是否已经存在,不存在则通过后面的 Function<? super K, ? extends V> mappingFunction 来进行value计算,且将结果当作value同key一起push到Map中。
computeIfAbsent() 方法的用法总结: 只有在当前 Map 中 key 对应的值不存在或为 null 时 ,才调用 mappingFunction,并在 mappingFunction 执行结果非 null 时,将结果跟 key 关联,mappingFunction 为空时 将抛出空指针异常。
公共代码:
Map <String, List<Integer>> map=new HashMap<>(); List<Integer> l1=new ArrayList();List <Integer> l2=new ArrayList<>(); l1.add(1);l1.add(11);l2.add(2);l2.add(22); map.put("1",l1); map.put("2",l2); 接下来就是使用了:
写法1:
List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33); System.out.println(map.computeIfAbsent("2",v->l3)); System.out.println(map); 结果:如果原来map中有2,那么不会更新原来的值,并且computeIfAbsent方法返回原有的2这条值对于的value
[2, 22] {1=[1, 11], 2=[2, 22]} 写法2:
List<Integer> l3=new ArrayList<>();l3.add(3);l3.add(33); System.out.println(map.computeIfAbsent("3",v->l3)); System.out.println(map); 结果:如果原来map中无3那么会向map中新增3这条值,并且computeIfAbsent方法返回新增的3这条值的value
[3, 33] {1=[1, 11], 2=[2, 22], 3=[3, 33]} 写法3:
贪心算法 当一个问题具有最优子结构性质时,可用动态规划法求解。有时会有更简单有效的算法。考察找硬币的例子。假设有4种硬币,它们的面值分别为二角五分、一角、五分和一分。现在要找给顾客六角三分钱。这时,自然地拿出2个二角五分的硬币、1个一角的硬币和3个一分的硬币交给顾客。这种找硬币方法与其他找法相比,拿出的硬币个数是最少的。这里使用的找硬币算法为:首先选出一个面值不超过六角三分的最大硬币,即二角五分;然后从六角三分中减去三角五分,剩下三角八分;再选出一个面值不超过三角八分的最大硬币,即又一个二角五分,如此一直做下去。这个方法实际上就是贪心算法。顾名思义,贪心算法总是做出在当前看来是最好的选择。 也就是说,贪心算法并不从整体最优加以考虑,所做的选择只是在某种意义上的最优选择。当然,我们希望贪心算法得到的最终结果也是整体最优的。找硬币算法得到的结果就是一个整体最优解。
找硬币问题本身具有最优子结构性质,可以用动态规划算法来解,但贪心算法更简单,更直接,并且解题效率更高。这利用了问题本身的一些特性。例如,上述找硬币的算法利用了硬币面值的特殊性。如果硬币面值改为一分、五分和一角一分,而要找给顾客的是一角五分钱。还用贪心算法,将给顾客1个一角一分的硬币和4个一分的硬币。然而3个五分的硬币显然是最好的找法。虽然贪心算法不是对所有问题都可以得到整体最优解,但是对范围相当广的许多问题能够产生整体最优解,如最小生成树问题、图的单源最短路径问题等。在一些情况下,即使贪心算法不能得到整体最优解,但其最终结果却是最优解的很好的近似解。
例:活动选择问题 题目描述:设有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si <fi 。如果选择了活动i,则它在半开时间区间[si, fi)内占用资源。若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的。也就是说,当si≥fj或sj≥fi时,活动i与活动j相容。
活动安排问题: 要在所给的活动集合中选出最大的相容活动子集合。
活动安排问题的关键是如何按照一定的顺序安排活动,使得选出的活动间相容并能安排尽量多的活动。
题解:由于输入的活动以其完成时间的非减序排列,所以每次总是选择具有最早完成时间的相容活动加入集合A中。直观上,按这种方法选择相容活动为未安排活动留下尽可能多的时间。也就是说,贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。
若被检查的活动i的开始时间Si小于最近选择的活动j的结束时间fi,则不选择活动i,否则选择活动i加入集合A中。
贪心算法并不总能求得问题的整体最优解。但对于活动安排问题,贪心算法greedySelector却总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。这个结论可以用数学归纳法证明。
#include<iostream> using namespace std; /*假设输入的活动结束时间按照增序排序。 若输入活动的结束时间未排序,可对活动进行排序然后进行选择。 */ int s[12],f[12]; bool a[11]; int n=11; int Selector() { a[1]=true; int j=1; int count=1; for (int i=2;i<=n;i++) { if(s[i]>=f[j]) { a[i]=true; j=i; count++; } else a[i]=false; } return count; } int main() { cout<<"活动序号:"<<endl; for(int i=1;i<=11;i++) cout<<i<<" "; cout<<endl<<"活动开始时间:"<<endl; for(int i=1;i<=11;i++) cout<<s[i]<<" "; cout<<endl<<"活动结束时间:"<<endl; for(int i=1;i<=11;i++) cout<<f[i]<<"
本系统主要是基于Java的Oracle大作业,数据库中包含触发器、用户、视图、存储过程等等在Oracle课程中讲到的所有功能。
源码地址:【Oracle大作业】基于Java+Oracle的研究生招生信息系统.zip-Oracle文档类资源-CSDN下载
开发环境:eclipse/idea/myeclipse均能运行,数据库:MySQL8.0
文档目录:
系统功能分析
研究生招生信息管理系统,是一个对研究生的各种信息进行录入等处理和统计分析的系统,根据管理的需要,招生系统管理系统主要工作包括:
1、基本数据设置。这是一个包含添加、更新、删除功能的模块,将考生的简历(如姓名、生源地、学历、报考专业等)填入学生档案表,也就是将考生的基本信息输入数据库,建立考生档案,并可对其中的错误填写进行更新和删除;
2、成绩信息处理。这是一个包含添加、更新功能的模块,将每个考生的成绩录入后可以进行考生成绩的查询和更新,也就是将考生的成绩信息输入数据库,建立考生成绩表;
3、考生录取统计。这也是一个包含录取、统计、打印功能的模块,主要是实时设置录取分数线来录取初试和复试的考生,统计、分析本年的录取情况(如:统计录取学生的成绩、年龄、来源等情况)做出相应的统计图,并将各专业录取考生信息打印出来供查看等。
系统功能模块图
文字说明
1、数据录入: 把每年报考研究生的考生情况逐一录入数据库。录入内容包括:考生自 然信息情况、考试科目及专业计划招生数、 初试和复试考试成绩、分数线设定等情况;
2、数据更新: 根据需要对已输入后的数据进行修改和删除操作;
3、数据添加: 根据需要将新的考生情况数据添加到数据库中;
4、数据统计:根据录取结构对考生按成绩或自然信息进行统计并作出统计图;
5、数据打印:将要保存的数据内容打印到相应的文件中留待查看。
系统流程图
概要结构设计
新考生档案注册
考生信息查看及更新
主操作界面
成绩录入界面
考试录取界面
成绩统计模块
初试成绩分段统计图
自然信息统计模块
源码地址: 【Oracle大作业】基于Java+Oracle的研究生招生信息系统.zip-Oracle文档类资源-CSDN下载
类型字符数byte1字节char2字节short2字节int4字节float4字节long8字节double8字节boolean至少1字节 整数型 首先Java中默认的整数型为int数据类型,其取值范围为2^31-1——-2^31,而其中long类型的取值范围为2^63-1——-2^63,如果运行以下一段程序,会出现值损失的情况,是因为long表示的数据范围大于int可表示的数据范围,int的类型值存储不了long类型的值。
public class Test { public static void main(String [] args){ int a=1; long b=2; a=b; System.out.println(a); } } 但是对于byte类型或者short类型的数据赋值给int类型,则其最终的类型为自动升级为更加高级的int类型
浮点型 浮点数=符号位+指数位+尾数位(尾数部分可能会包括不了全部的尾数,会造成精度损失,小数都是近似值),在浮点型中分为double型与float类型,而Java默认的使用double类型,如果想要使用float类型,必须在数的最后加上f,表示这是一个单精度浮点数,否则会发生值损失错误。运行以下程序,会发生信息报错。而如果在10.2后面加上f,则不会报错。
public class Test { /**这是算出函数类型的数据*/ public static String getType(Object o){ return o.getClass().toString(); } public static void main(String [] args){ float a=10.2; System.out.println(a); } } 这是因为不加上f,表示double型的数据10.2赋值给float类型的a,由大转小会损失,而加上f之后,就是将float类型赋值给float类型,不会发生值损失。
浮点型科学计数法的表示,例如int a=5.12e2,表示5.12*(10^2)=512
public class Test { /**这是算出函数类型的数据*/ public static String getType(Object o){ return o.getClass().toString(); } public static void main(String [] args){ double a=5.
问题描述
在学习Qlearning中,有使用到tornado第三方库。在安装相关库之后
pip install gym
pip install matplotlib
发现jupyter报错
The kernel failed to start as 'ioloop' could not be imported from '~\Envs\Env\lib\site-packages\tornado\__init__.py'. View Jupyter log for further details.
解决方法
可以尝试以下命令,或许可以解决问题
pip install ioloop
pip install tornado ==5
在安装完tornado==5之后,jupyter提示下载
pip install pyglet
实现截图
一、名词解释:入站规则:别人电脑访问自己电脑的规则,出站规则:自己电脑访问别人电脑的规则。
二、意义:阻挡或者允许特定程序或者端口进行连接。可以阻挡某个软件进行所有连接、允许所有连接,或者只允许安全连接,并要求使用加密来保护通过该连接发送的数据的安全性; 可以为入站和出站流量配置源IP地址及目的地IP地址,同样还可以为源TCP和UDP端口及目的地TCP和UPD端口配置规。
三、操作如下:
1、点开始——控制面板;
2、点系统和安全;
3、点Windows防火墙;
4、点高级设置;
5、点入站规则,点新建规则;
6、选中端口,点下一步;
7、选中TCP;
选中特定本地端口:输入443,点下一步;
8、选中允许连接,点下一步;
9、全部选中,点下一步;
10、输入端口名称,点完成;
11、然后选择出站规则,点新建规则,操作同上。
vue中目录的实现方法 方法1:自己封装一个目录组件,递归思想 <template> <div class="catalog"> <aside class="leftCatalog"> <h4 style="border-bottom: 1px solid #ccc;">目录</h4> <tree></tree> </aside> <div class="right">主要内容展示区域</div> </div> </template> <script> export default { components: { tree: () => import("../components/tree.vue"), }, }; </script> <style scoped> .catalog { display: flex; } .leftCatalog { width: 180px; height: 240px; overflow-y: auto; background-color: #f5f5f5; } .right { flex: 1; } </style> tree.vue文件:
<template> <div class="catalogBox"> <!-- 每一个最外层的对象,就会渲染出一个catalogItem--> <catalogItem class="catalog" v-for="(item, index) in list" :key="index" :itemText="item" ></catalogItem> </div> </template> <script> import catalogItem from "
HttpRunner的参数化 通常有三种
1.在YAML/JSON中指定参数:适合参数列表比较小的情况,好处是简单
2.内置parameterze(P) 函数引用CSV文件:适合数据量较大的情况,需提前准备CSV文件
3.调用debugtalk.py中自定义的函数生成参数列表:最灵活,需要动态生成参数时可选择此方式
第一个不用说了
第二个:先新建一个文件夹用来保存测试数据,叫data
新建一个csv文件,准备好测试数据,参数,参数 以这种格式存入
然后新建测试用例集 ,调用用例 以及读取csv中的数据赋值
使用参数的语法${P(数据文件相对路径)}
P是内置函数,parameterze的简称
config: name: 用例集-调用csv testcases: - name: 登录 testcase: testcases/test_login_fa.yml parameters: username-password: ${P(data/data.csv)} 写完后,hrun 执行,查看结果
第三点:
在debugtalk中先定义一个方法,确认测试通过后
def get_account(num): # 生成测试账号 accounts=[] for i in range(1,num+1): accounts.append({'username':'1876710500%s'%i,'password':'Aa1234567!'}) return accounts if __name__=='__main__': print(get_account(8)) 用例集中调用写好的函数,生成8条数据登录,执行后查看报告
config: name: 引用函数参数化 testcases: - name: 登录 testcase: testcases/test_login_se.yml parameters: username-password: ${get_account(8)}
phpstorm 调试配置感觉 很麻烦,踩了很多的坑,不说废话了,直接上配置
参考文章 :
https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html#configuring-xdebug-docker
这是我的PHP.ini配置
[xdebug] ;启用性能检测分析 xdebug.profiler_enable=off ;启用代码自动跟踪 xdebug.auto_trace=off ;允许收集传递给函数的参数变量 xdebug.collect_params=on ;允许收集函数调用的返回值 xdebug.collect_return=on ;调试端口 xdebug.show_exception_trace = On ;开启异常跟踪 xdebug.remote_autostart = Off ;开启远程调试自动启动 xdebug.remote_enable = On ;开启远程调试 xdebug.remote_port = 9003 xdebug.idekey=PHPSTORM xdebug.default_enable=1 xdebug.remote_log=/tmp/xdebug.log xdebug.remote_connect_back=0 xdebug.remote_host=host.docker.internal #phpstorm 官方文档上面有写 这里是dockerfile 配置
FROM php:7.3-fpm RUN mkdir -p /data/www \ && cd /usr/local/bin \ && php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" \ && php composer-setup.php \ && php -r "unlink('composer-setup.php');" \ && mv composer.
通常, 无线通信网络嵌入无线电接入技术(RAT), 该技术采用多址技术(无线蜂窝系统的一个基本功能)为多个移动终端提供到核心网络的连接。 因此, 根据其基本原理, 多址接入技术可以归类为:
正交多址 (OMA) 技术非正交多路访问 (NOMA)技术 OMA: OMA允许每个用户通过向每个用户分配不同的正交资源(时间/频率/代码) 块 (RB) 来从所需信号中完全分离不需要的信号。
具体例子:频分多址 (FDMA)、 时分多址 (TDMA)、 码分多址 (CDMA) 和正交频分多址 (OFDMA)。
NOMA: NOMA 方案允许在同一区域内同时将一个RB 分配给多个用户, 提供了许多优势, 例如基站 (BS) 接近和边缘用户之间的频谱效率和公平性, 允许将NOMA标记为未来无线接入技术的多址方案 。
NOMA主要分为两个解决方案,1.代码域 NOMA (C‑NOMA) 2.功率域NOMA (P‑NOMA)。
C-NOMA是整个RB分享给所有用户,P-NOMA是在功率域里同一RB复用为多个用户提供服务。
NOMA 非正交多址技术(NOMA)的基本思想是在发送端采用非正交发送,主动引入干扰信息,在接收端通过连续干扰消除(SIC,successive interference cancellation)接收机实现正确解调。用提高接收机的复杂度来换取频谱效率,这就是NOMA技术的本质。
NOMA的关键技术: 串行干扰删除(SIC)
串行干扰消除技术的基本思想是采用逐级消除干扰策略,在接收信号中对用户逐个进行判决,进行幅度恢复后,将该用户信号产生的多址干扰从接收信号中减去,并对剩下的用户再次进行判决,如此循环操作,直至消除所有的多址干扰。
功率分配方案 基站在发送端会对不同的用户分配不同的信号功率,来获取系统最大的性能增益,同时达到区分用户的目的,这就是功率复用技术。
大多数关于 NOMA 系统功率分配的当代研究可以大致分为两大类:1.单通道分析和2.多通道分析。
第一种情况,推导出最优功率分配方案,假设所有N用户被复用到同一个 RB内的功率域。在第二种情况下,可用带宽被划分为不同的独立的RB,在每个RB上复用用户子集。
第一步:右键桌面-显示设置
第二步:点击缩放(更改文本、应用和其他项目大小)
第三步:点击文本大小-调整合适的文本大小(可调节100-500%)-点击应用
展开
收起
<div cla> <!-- 展开收缩图标 --> <i :class="{ iconfont:true,'icon-shouqi':isOpen,'icon-zhankai1':!isOpen}" @click="changeOpen"></i> //控制他显示或者不显示 <div v-show="isOpen"></div> </div> export default { name: 'Top', data() { return { // 展开状态 isOpen: true, }; }, methods: { // 展开或者收起 changeOpen() { this.isOpen = !this.isOpen; },
//pImage 图像数据的指针首地址,不要填错!!! if (enDstPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)//黑白图像格式 { //************************Mono8 转 Bitmap******************************* Bitmap bmp = new Bitmap(stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nWidth * 1, PixelFormat.Format8bppIndexed, pImage); ColorPalette cp = bmp.Palette; // init palette for (int i = 0; i < 256; i++) { cp.Entries[i] = Color.FromArgb(i, i, i); } // set palette back bmp.Palette = cp; bmp.Save("image.bmp", ImageFormat.Bmp);//存图验证是否ok } else//彩色RGB或者BGR格式 { //*********************RGB8 转 Bitmap************************** //RGB与BGR的转换,如果原始数据就是BGR了,也可以省去这个循环,避免浪费时间 for (int i = 0; i < stFrameInfo.nHeight; i++) { for (int j = 0; j < stFrameInfo.
用新版的AS 的profiler 查看内存泄漏 记录一下使用Android Studio 的profiler 查看内存泄漏的过程。新版的AS 的profiler 功`能强大。我们可以很方便的查看到一个界面里的内存泄漏。
首先我们来看看不发生内存泄漏时候的情况:
public class MemoryLeakActivity extends AppCompatActivity { private ValueAnimator count20sToStop; // 这里有在onDestory里处理,这样做肯定会避免掉当前情况下handler的内存泄露 @Override protected void onDestroy() { super.onDestroy(); mHandle.removeMessages(FLAG); } private static int FLAG = 999; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_memory_leak); Button btn = findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); mHandle.sendEmptyMessageDelayed(FLAG, 1000); } private Handler mHandle = new Handler(Looper.myLooper()) { @Override public void handleMessage(@NonNull Message msg) { super.
1. 加串器解串器概述 加串器解串器又称串行/解串器,串行/解串器是高速数据通信中的接口电路,高速串行数据通信在许多应用中广泛出现,并且它们在继续更广泛的替换掉传统的并行数据连接系统。
并行通信和串行通信最基本的差别就在于它们对应的在两个器件之间用作传输数据的物理信道的数量。并行通信意味着数据通路除了连地通路外,还包含有许多物理信道,而串行通信中数据通路常常只存在两条指定的信道,用于传输一对差分信号,同时并不需要连地通路。
2. 加串器解串器的优势 随着数据速率的增加,有关实施并行总线的问题也随之增多。较快总线比较慢总线功耗高,而且由于定时容差的降低,信道数量的增加,布局难度也越来越大。随着数据速率的增加,保持信道间的时滞也日益重要,原因是较大的时滞差异会导致系统定时问题,因为接收器需要按对齐位组在并行数据总线中进行时钟计时。
此外,由于如今的设计日益紧凑,板级空间也格外珍贵,因此大型并行总线会消耗宝贵的 PCB 基板空间。串行解串器能够降低成本、功耗以及板级空间,可为上述设计挑战提供良好的解决方案。
通过对并行数据进行一定的串化,由n数据位串化为k数据位(n信道数减少到k),在接收端,再由k数据位解串为n数据位,减小物理消耗。
3. 汽车摄像头视频传输之加解串器芯片 FPD-Link III是许多汽车应用中用于点对点传输视频的接口。该接口利用SerDes技术可通过双绞线或同轴电缆通过低成本电缆传输高清数字视频以及双向控制通道。 FPD-Link III串行器和解串器(SerDes)已针对处理器与显示器之间或处理器与相机之间的链接进行了优化。
视频处理器将数据流传送给FPD-Link收发器芯片,经过串行转换后由收发器发出出去,经过屏蔽双绞线或者同轴线到达接收端,然后经过自适应均衡(adaptive equalizer,AEQ) 、串转并等操作后通过并行接口或者其他高数视频接口传送给处理器。接收端的数据恢复需要的时钟是从数据流中提取的,这个就是时钟恢复技术(CDR,Clock DataRecovery )。视频流和控制数据流经过同一个物理通道进行传送,但是他们的数据速率相差几百倍,所以可以通过不同的采样时钟进行恢复。
由于大部分摄像头的LVDS格式只能用于近距离传输,因此摄像头都要配备一个加串行芯片,将并行数据转换为串行用同轴或STP传输,这样传输距离远且EMI电磁干扰更容易过车规。
4. 加解串器的用法 camera数据流的大概流程:sensor -----> ISP(如果摄像头IC集成了ISP的话) -----> 串行器(STP/coax)-----> 解串器(PCB板上的解串器),然后解串器输出MIPI或者DVP之类的信号。
可以通过主机写I2C,控制PCB板上的解串器芯片,然后透过解串器-->camera上的串行器-->ISP来调整camera sensor的曝光参数。
response_hex_list = ['55', 'aa', '00', '78', '56', '34', '12', 'c0', '0b', '00', '00'] check_sum_str = hex(sum([int(i, 16) for i in response_hex_list])) print(check_sum_str) # 0x2de
腾讯云-个人域名备案-个人实操(图文详解) 准备材料1.信息验证进入微信小程序信息验证 2.主体信息3.网站信息4.上传材料(需要拍照)5.信息核对、等待审核(短信通知)幕 准备材料 1.云服务器(3个月+的购买时长)、已通过实名认证的域名
2.身份证、详细的现居住地址
3.网站内容描述
4.白色背景墙(中途会拍照)
补充材料01—域名证书.jpg(从域名管理处下载)
补充材料02—域名实名认证截图.jpg
1.信息验证 进入微信小程序 信息验证 2.主体信息 3.网站信息 4.上传材料(需要拍照) 5.信息核对、等待审核(短信通知) 审核过程中可能会收到,电话进行信息核对与更改云审核通过后,提交至本地的管局审核通过审核后,收到管局短信,登录提示网址进行操作,然后继续等待 幕 留白 —<老吉> ~ 今 ~ ❀ ~ ❀❀❀❀❀❀❀❀❀❀ ❀❀❀❀❀❀❀❀❀❀ ❀❀❀❀❀❀❀
2022年伊始,默安科技联合数世咨询举办以“软件供应链安全的时与势”为主题的访谈活动,由数世咨询创始人李少鹏主持,邀请贝壳安全研发负责人李文鹏、北京邮电大学副教授张文博、默安科技副总裁沈锡镛三位行业大咖做客网安小酒馆,从产业、企业、学术的不同维度,共同探讨软件供应链安全建设的新思路,为业界呈现了一场开年网安盛宴。
随着全球软件供应链安全事件频发,软件供应链安全逐渐成为业界关注焦点,也成为影响国家重要信息系统安全与关键信息基础设施安全的重要因素,以及网络安全保障体系和能力建设的重要环节。嘉宾们围绕软件供应链安全发展的主要驱动力、关基行业中的实施现状和落地难点、产学研成果转化、软件供应链安全的重要性等话题展开激烈讨论。
1 软件供应链安全发展的主要驱动力是什么? 北京邮电大学张文博:从宏观角度来看,随着数字经济不断发展、人们日常生活离不开各类软件和APP、个人隐私保护等需求推动着软件供应链安全的发展。客户需求是软件供应链安全发展的根源,即使需要满足法律法规与相关行业规范,规范诞生的源头仍然是需求
默安科技沈锡镛:从SolarWinds供应链攻击事件可以看出,针对软件供应链的高级攻击愈演愈烈,安全事件是驱动这个细分领域发展的重要因素;其次,从合规的角度来说,由于软件供应链安全的行业属性过强,制定通用标准难度较大,软件供应链安全的发展仍然以自发需求为主。
贝壳安全李文鹏:软件供应链安全多为自身安全需求驱动,在物联网、云计算等技术发展过程中不可避免地出现大量财产、个人隐私、商业秘密泄露等问题。同时软件供应链条越长越复杂,安全问题越突出。
2 关键信息基础设施等行业在软件供应链安全方面的现状如何?面临哪些问题? 贝壳安全李文鹏:从企业角度来说,主要面临两大痛点。第一,随着软件工业化和软件规模的不断发展,安全风险和软件膨胀成正比,如何有序管理复杂的软件供应链成为企业关心的话题。企业内部有多少应用、基础设施、关键组件不得而知。软件资产与供应链的梳理难度大是主要痛点之一。第二,从技术角度来看,市场上不缺软件供应链安全治理工具,但各个用户都有自己的软件管理流程、CI/CD流程,如何将工具与用户现有流程有机融合,实现效能最大化,是目前面临的重要挑战。
默安科技沈锡镛:之前接触的关键信息基础设施行业用户,如证券、互联网、电力等,都提到了与贝壳同样的共性问题。此外,组织内部的部门割裂也是比较严重的问题。在研发侧加强对软件供应链安全的重视程度十分重要。无论采用哪种开发模式,都应制定安全开发机制,加入第三方组件等供应链资产的梳理,或将安全融入需求分析阶段(例如有些架构漏洞无法修复,则用高可用架构替换)。总结来说,三个观点:软件供应链“底账”摸不清楚,后患无穷;应提高研发部门对安全的重视程度;软件供应链最先落地的可能不是互联网行业,而是数据密度大、供应链非常长的工业企业等。
数世咨询李少鹏:关键信息基础设施行业软件供应链中的组件可能应用并不广泛,但安全事件带来的负面影响不可小觑。在当前“离散制造”的大环境下,软件供应链安全的重要性会越来越突出。
北京邮电大学张文博:关键信息基础设施行业还面临非常严峻的合规性问题。互联网出现的初始目的是为防止“核打击”,即使在受到攻击的情况下也需要保证政府机构正常运作。因此互联网的根源实际是关键基础设施。随着互联网的发展,相关法律规范也不断完善。例如中央网络安全和信息化委员会于2021年12月印发的《“十四五”国家信息化规划》,就从政策角度指出安全与发展双轮驱动的要求。
3 软件供应链安全治理的落地会遇到哪些问题? 贝壳安全李文鹏:有些单位会严格管控所有供应链和第三方组件引入流程,但这类纯管理方式导致研发效率低,同时审核人与实际业务形态脱离,实际安全管控效果不够理想。目前常见的做法是注重安全事件的缓解,容忍某些单点突破,但需通过纵深防御机制,防止攻击链和影响范围的不断扩大,避免全面失守。但目前软件供应链安全治理落地仍然存在很大的提升空间,可能需要学术界和厂商侧共研一些解决方案。 默安科技沈锡镛:这个问题的本质可以理解为安全左移到什么程度。比如在架构评审即融入安全非常重要,安全与研发部门深入合作、共同面对和解决问题。安全左移是安全与研发的责任共担,而非将安全责任转移到研发部门。因此开发安全体系的一大特点应该是“陪伴式交付”,并且安全交付没有终点,而是一个不断改进和迭代的过程。
北京邮电大学张文博:术业有专攻——安全和开发很多时候处于“两个次元”,工作思路差异较大,双方沟通一定存在摩擦,因此共同完成安全开发工作就必须做到“宽容”。
4 高校在软件供应链安全方面的研究成果如何转化为解决问题的产品与能力? 北京邮电大学张文博:产学研转化不止在软件供应链安全领域,在很多其它科技领域都存在。主要原因:国内愿意在研发投入大量成本的企业比较有限;学术研究和企业的目标侧重点存在差异,企业更注重经济效益,很多时候是短期的回报,而从学术层面来说,能够快速产生经济价值的研究并不一定存在很高的学术创新价值。实际解决只能逐步开展,当前最实际的做法是与企业展开人才培养合作,共同为社会输送更多高精尖人才。
贝壳安全李文鹏:当前的产学研转化问题可能与国家目前的发展阶段有关,但这个问题已经引起极大的重视,从社会意识上来说已是很大的进步。
5 安全体系建设过程中,软件供应链安全应当扮演怎样的角色? 贝壳安全李文鹏:随着软件规模的增长,软件供应链安全重要性日益突出,目前应该处于一个转型的连接点,但很难定义为一个具体的角色,它是软件设计、需求评审、研发、上线全流程中必不可少的环节,需要安全与业务共同合作。其中也包括SDL,贯穿软件开发和运营全生命周期。从宏观角度来说,软件供应链安全建设需要软件工程学整个领域的转型和突破。
北京邮电大学张文博:软件供应链至少包括开发、发布、使用等阶段,涵盖整个商业活动,其中的安全不可忽略;应分阶段地落实,同时也需要统一管理。
默安科技沈锡镛:软件供应链安全实际在整个安全体系建设中扮演融合的角色,例如完整的安全开发体系就是软件供应链安全的基底,包括全流程的设计安全、编码阶段的安全、测试阶段的安全等等。
总结 从本次活动的讨论内容可以看出,软件供应链安全离不开SDL安全开发生命周期的全流程建设。默安科技是国内开发安全和DevSecOps领域的先行者,在软件供应链安全领域有着丰厚经验和技术积累,此次与数世咨询合作,邀请用户、厂商、院校专家“把酒话网安”, 通过访谈的形式讨论当下最热门安全话题之一——软件供应链安全,希望能给网安从业企业、关基行业单位带来一些开展软件供应链安全治理工作的思路和建议。未来,默安科技将继续为众多合作伙伴输出有价值的内容,提供更安全有效的产品、方案与服务。
今天使用mybatis查询mysql中的数据时,莫名其妙的所有时间都出错了,所有时间都比数据库时间多了14小时,考虑了一下,初步判定是系统时区的问题。因为mysql时区设置默认是操作系统时区,查看了下centos时区,东8区没有错,所以可以判定是代码里面设置了一个错误的时区。
现在开始调试mybatis源码,调试到mysql-connector-java-6.0.4.jar包的com.mysql.cj.jdbc.io.JdbcTimestampValueFactory的createFromTimestamp方法时,发现mysql的底层驱动程序对从数据库查询出来的时间用了一个Calender做类型转换,Calender记录中包含的时区为CST,跟中国的时区Asia/Shanghai正好差了14小时。
那么为什么mybatis连接数据库会使用CST的美国时间呢?继续查看源码发现
mysql连接数据库的时候会从mysql读取系统的时区设置,调试com.mysql.cj.mysqla.MysqlaSession.java的configureTimezone方法发现,this.getServerVariable(“system_time_zone”)从系统里面读出来的时区设置是CST
至此问题已经清楚了,是mysql设置的时区不对,登陆linux,执行mysql -uroot -p, 然后运行命令show variables like ‘%time_zone%’,发现system_time_zone项果然是CST。
至此,排查问题结束,修改一下mysql的时区设置即可。
服务器:IIS 6.1
MVC版本:MVC4.0
.NET 版本:4.0
如图,报错:
解决方法:
(先到应用程序查看一下,网站使用的应用程序是否是与项目开发使用的framework版本同级,即4.0+开发的项目程序使用2.0+的跑也会报这个错误!)
第一步:首先确认你安装了.net4.0,然后注册 .net4.0
注册方法:在cmd中输入 C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i
第二步:在IIS中单击你的网站,再单击处理程序映射。
在打开的窗口中双击ExtensionlessUrlHandler-Integrated-4.0,
如果请求路径是“*.”,那么请把请求请求路径改为“*”
第三步:单击“应用程序池”,在列表中找到你的应用程序池,并双击。 第四步:把.NET Framework 版本改为4.0的版本,单击确定。
再次运行网站,已经正常访问!
5.FastAPI显式声明参数 FastAPI允许显式声明参数属于查询参数、路径参数或者请求体;同时还可以为参数声明默认值、额外的信息及校验;也允许显式声明可选参数;
5.1可选参数 可选参数的显式声明使用 typing. Optional来声明;代码如下:
# coding: utf-8 from typing import Optional from fastapi import FastAPI app = FastAPI() @app.get(path='/add/{vara}/{varb}') async def add(vara: int, varb: int, x: Optional[int]=2, y: Optional[int] = 5): return {'added': vara + varb, 'multiply': x * y} 执行请求:
curl http://127.0.0.1:8000/add/1/2 {"added":3,"multiply":10} 5.2查询参数 查询参数使用fastapi的Query来声明,声明时可以指定默认值,代码如下:
from typing import Optional from fastapi import FastAPI from fastapi import Query app = FastAPI() @app.get(path='/add/{vara}/{varb}') async def add(vara: int, varb: int, x: Optional[int]=Query(2), y: Optional[int]=Query(5)): return {'added': vara + varb, 'multiply': x * y} 上面的代码中使用 Query(2) 替换默认值 2,Query 的第一个参数也是用于定义默认值的,当使用Query声明必须参数时,可以将 .
nginx 静态服务器:
下载安装nginx
修改配置文件:
```java ```java server { listen 8888; server_name localhost; root /file/data; location / { root /file/data; #默认当前磁盘的路径,例如D盘就是 D://file/data ,liunx就是file/data下 index index.html index.htm; add_header Access-Control-Allow-Origin *; autoindex on; # 开启目录文件列表 autoindex_exact_size on; # 显示出文件的确切大小,单位是bytes autoindex_localtime on; # 显示的文件时间为文件的服务器时间 } add_header Cache-Control "no-cache,must-revalidate"; } 重启nginx
在 D://file/data 建立 文件夹tmp,访问
问题:中文文件夹和中文的文件没办法点击,下载,因为字符集的原因,谁能帮忙解决下啊
引言 本文主要采用Pytorch来实现策略梯度算法,算法的原理可以参考我的这篇博文:深度强化学习-策略梯度算法推导,里面对该算法进行了详细推导。如果想深入理解策略梯度算法公式,可以参考我的另一篇博文:深度强化学习-策略梯度算法深入理解,里面将其与手写数字识别问题进行了类比,深入剖析了策略梯度算法公式。代码已经上传到我的Github上,喜欢的话可以点个小星星噢。
代码:https://github.com/indigoLovee/Reinforce_pytorch
1 Reinforce算法 强化学习的目标在于最大化累积奖励。采用含参函数近似最优策略,沿着策略梯度的方向,更新策略参数,可以实现累积奖励最大化。策略梯度定理如下:
策略梯度定理:
Reinforce算法的伪代码如下:
2 Reinforce算法实现 Reinforce算法代码如下(Reinforce_discrete.py脚本):
import torch as T import torch.nn as nn import torch.optim as optim from torch.distributions import Categorical device = T.device("cuda:0" if T.cuda.is_available() else "cpu") class PolicyNetwork(nn.Module): def __init__(self, alpha, state_dim, action_dim, fc1_dim, fc2_dim): super(PolicyNetwork, self).__init__() self.fc1 = nn.Linear(state_dim, fc1_dim) self.fc2 = nn.Linear(fc1_dim, fc2_dim) self.prob = nn.Linear(fc2_dim, action_dim) self.optimizer = optim.Adam(self.parameters(), lr=alpha) self.to(device) def forward(self, state): x = T.relu(self.fc1(state)) x = T.
来源:【itext学习之路】-------(第五篇)对pdf进行盖章/签章/数字签名_tomatocc的博客-CSDN博客_itext 数字签名
在上一篇文章中,我们学习了使用itext对pdf增加图片水印和文本水印,那么这篇文章我们将要学习更高级一点的水印----印章。可能你会有疑问,印章不也是一个图片吗?当然,你可以把一个印章图片来做成图片水印,但是我们这里要介绍的是,通过数字签名的方式来进行pdf签章。
首选,我们要准备好jar包。
bcpkix-jdk15on-1.49.jar bcprov-jdk15on-1.49.jar itext-asian-5.2.0.jar itextpdf-5.5.11-sources.jar itextpdf-5.5.11.jar 大家可以去maven库中进行下载,也可以直接下载我上传的jar包文件:点击下载
下载好jar包之后,我们还要去了解一门技术:数字证书,而在本文中,我们需要生成一个.p12结尾的数字证书,该证书用来对我们的pdf文档进行数字签名。生成.p12证书的方法请参考我的另一篇文章:使用JDK的keytool生成p12证书
直到这里,我们前期的准备工作就已经全部做好,接下来,我们就要步入正题:对pdf进行签章。 首先,我们创建一个SignatureInfo的实体类,用途是为了方便的增加需要签章的信息: package cn.tomtocc.pdf; import com.itextpdf.text.pdf.PdfSignatureAppearance; import java.security.PrivateKey; import java.security.cert.Certificate; public class SignatureInfo { private String reason; //签名的原因,显示在pdf签名属性中 private String location;//签名的地点,显示在pdf签名属性中 private String digestAlgorithm;//摘要算法名称,例如SHA-1 private String imagePath;//图章路径 private String fieldName;//表单域名称 private Certificate[] chain;//证书链 private PrivateKey pk;//签名私钥 private int certificationLevel = 0; //批准签章 private PdfSignatureAppearance.RenderingMode renderingMode;//表现形式:仅描述,仅图片,图片和描述,签章者和描述 //图章属性 private float rectllx ;//图章左下角x private float rectlly ;//图章左下角y private float recturx ;//图章右上角x private float rectury ;//图章右上角y public float getRectllx() { return rectllx; } public void setRectllx(float rectllx) { this.
解决报错cannot import name ‘_registerMatType‘ from ‘cv2.cv2‘
使用yolox时系统运行报这个错误
Traceback (most recent call last): File "tools/train.py", line 13, in <module> from yolox.core import Trainer, launch File "/user-data/YOLOX-main/yolox/__init__.py", line 4, in <module> from .utils import configure_module File "/user-data/YOLOX-main/yolox/utils/__init__.py", line 15, in <module> from .setup_env import * File "/user-data/YOLOX-main/yolox/utils/setup_env.py", line 9, in <module> import cv2 File "/opt/conda/lib/python3.8/site-packages/cv2/__init__.py", line 9, in <module> from .cv2 import _registerMatType ImportError: cannot import name '_registerMatType' from 'cv2.cv2' (/opt/conda/lib/python3.8/site-packages/cv2/cv2.cpython-38-x86_64-linux-gnu.so) 解决方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Opc.Ua;
using OpcUaHelper;
namespace ISCS_AutoTest
{
/// <summary>
/// 读写FEP和RETDB中的数据
/// </summary>
public class OperatorOPCUa
{
public ExpandedNodeId TypeDefinition { get; set; }
private OpcUaClient opcUaClient = new OpcUaClient();
/// <summary>
/// 连接OPC ua Server /// </summary>
/// <param name="serverUrl">服务地址</param>
public bool ConnectOpcUa(string serverUrl)
{
try
{
if(opcUaClient.Connected == true)
{
return true;
}
else
{