BlockCanary源码解析

BlockCanary源码解析 在讲解BlockCanary源码之前,我们还是需要将一些前置的知识点。本文不讲Handler的原理了,不太懂的同学自己去百度看一下吧。 什么是卡顿 在讲解卡顿问题之前,我们需要讲一下帧率这个概念。帧率是以帧称为单位的位图图像连续出现在显示器上的频率。我将一个例子,电影播放。电影其实就是很多张照片(帧)的一个集合,那为什么看起来是一个连续的过程呢?因为电影每一秒出现过的图片不止一张。实际上电影一般一秒出现的图片张数会在20-30张。假设电影一秒出现了24张图片,那么这个电影的帧率就是24。帧率就是一秒中,出现了多少帧。 知道了什么是帧率,那么问题来了,为什么会出现卡顿呢?卡顿在我们的视觉上面的表现就是原本是流畅的动画画面,现在变的不流畅了。我们上面讲过,动画其实是由很多图片构成。如果在一个24帧的电影中,突然有一秒钟,在这一秒钟出现了掉帧。也就是原本0...23的图片变成了 0...10...12...23.中间的某一帧没有渲染出来,那么这个在我们视觉上就会出现不流畅的现象。也就是卡顿的现象。上面就是电影上出现卡顿的现象。那么在我们android系统上呢? Android渲染机制 在高刷手机没有出现之前,我们手机屏幕的帧率是60。就是意味着1秒钟会有60个画面出现。那么也就是16ms就要有一个画面渲染。Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染, 如果每次渲染都成功,这样就能够达到流畅的画面所需要的60帧,为了能够实现60fps,这意味着程序的大多数操作都必须在16ms内完成。如果超过了16ms那么可能就出现丢帧的情况。如果掉帧的频率很高,也就是导致卡顿的情况。 BlockCanary源码解析 那么在android中,BlockCanary是怎么帮助我们去做卡顿检测的呢。今天我们就来讲解一下BlockCanary检测卡顿的原理。 一般我们都通过以下的代码方式去开启我们的卡顿检测。 public class DemoApplication extends Application { @Override public void onCreate() { // ... // Do it on main process BlockCanary.install(this, new AppBlockCanaryContext()).start(); } } 这段代码主要有两部分,一部分是install,一部分是start。我们先看install部分 install阶段 BlockCanary#install() public static BlockCanary install(Context context, BlockCanaryContext blockCanaryContext) { //BlockCanaryContext.init会将保存应用的applicationContext和用户设置的配置参数 BlockCanaryContext.init(context, blockCanaryContext); //etEnabled将根据用户的通知栏消息配置开启 setEnabled(context, DisplayActivity.class, BlockCanaryContext.get().displayNotification()); return get(); } BlockCanary#get() //使用单例创建了一个BlockCanary对象 public static BlockCanary get() { if (sInstance == null) { synchronized (BlockCanary.

Android bug修复记录

深色模式切换FC 报错日志 java.lang.ClassCastException: android.view.View$BaseSavedState cannot be cast to android.widget.CompoundButton$SavedState 问题分析:深色模式切换时Activity会重建,进而引发一些列问题 相关问题解决链接 id重复导致 深色适配 还有个取巧的解法,既然是Activity销毁重建导致,我们可以让他不重建 <activity android:name=".MyActivity" android:configChanges="uiMode" /> 未设置id导致 gradle:Cannot query the value of this provider because it has no value available 查看project的build.gradle文件中的buildToolsVersion指定的版本,然后打开SdkManager,查看对应版本的SDK Platform是否下载,如果没有下载,下载后重新进行gradle编译,解决! windows android studio terminal 异常问题 现象如下图,看了idea.log半天没搞明白 修复方式如下,我的是这里的路径搞错了

Android:Binder思考笔记

基础知识 进程空间划分 一个进程空间分为用户空间与内核空间。用户空间与内核空间都是虚拟内存,映射到物理内存。所有进程的内核空间映射到同一块物理内存,是共享的二者区别: 进程间,用户空间的数据不可共享,即用户空间=不可共享空间进程间,内核空间的数据可共享,所以内核空间=可共享空间 进程内用户空间与内核空间进行交互需要系统调用,主要函数 copy_from_user():将用户空间的数据拷贝到内核空间copy_to_user():将内核空间的数据拷贝到用户空间 传统的进程间通讯方式 Android基于Linux内核,Linux进程通讯方式有socket、共享内存、管道、信号量等 工作流程: 发送数据:通过系统调用copy_from_user()将数据从用户空间copy到内核缓存区接收数据:通过系统调用copy_to_user()将数据从内核空间copy到用户空间 缺点: 效率低下,需要做两次数据拷贝。用户空间->>内核空间->>用户空间接收数据的缓存由接收方提供,接收方不知道需要多大缓存 Binder Binder 是什么 以我的理解,binder 是client、service与ServiceManager沟通的桥梁,是一种类似驱动的存在 与其他IPC对比 从性能的角度:Binder数据拷贝只需要一次,而管道、消息队列、Socket需要2次,但共享内存方式一次内存拷贝都不需要;从性能角度看,Binder性能仅次于共享内存。从稳定性的角度:Binder是基于C/S架构的,稳定性较好;共享内存实现方式复杂,没有客户与服务端之别, 需要充分考虑到访问临界资源的并发同步问题,否则可能会出现死锁等问题;从这稳定性角度看,Binder架构优越于共享内存。(PS:简单解释下C/S架构,是指客户端(Client)和服务端(Server)组成的架构,Client端有什么需求,直接发送给Server端去完成,架构清晰明朗,Server端与Client端相对独立,稳定性较好)从安全的角度:传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Android作为一个开放的开源体系,拥有非常多的开发平台,App来源甚广,因此手机的安全显得额外重要;对于普通用户,绝不希望从App商店下载偷窥隐射数据、后台造成手机耗电等等问题,传统Linux IPC无任何保护措施,完全由上层协议来确保。Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志

C++ 模板函数、模板类:如果没有被使用就不会被实例化

C++中如果一个模板函数没有使用过,那么其局部静态变量都不会被实例化: class A { public: A() { edward::print("A ctor"); } }; template<typename T> void test() { static A a; } int main() { test<int>(); //如果注释掉则不会有输出 return 0; } A ctor 如果不显示地调用test函数,局部静态变量a是不会被实例化的。 同样的,如果一个静态类没有被实例化,那么他的成员也不会被实例化,就算这个静态类实例化了,但是没有使用一些静态变量、方法,那么这些没有使用的东西是不会被实例化的。注意:成员变量在模板类实例化后无论是否使用都存在。 class A { public: A() { edward::print("A ctor"); } }; template<typename T> class Test { public: static A a; A aa; }; template<typename T> A Test<T>::a; int main() { Test<int> test; // test.a; //如果取消注释会多打印一条语句 return 0; } A ctor

编辑ip地址

有时候创建虚拟机的时候忘了开启ip 需要手动添加: 输入vi /etc/sysconfig/network-scripts/ifcfg-ens*进入编辑页面,按i进行编辑,加入自定义ip(用以前这个虚拟机的ip)就ok啦!

Arduino从零开始(1)——按钮控制LED

0.前言 本文主要介绍Arduino对于开关和条件判断函数的使用。 目录 0.前言 1.介绍 2.按钮控制LED 2.1下拉模式: 2.2上拉模式 3.扩展实验: 1.介绍 前篇介绍了点亮LED,这次案例我们尝试通过一个简单的传感器——按钮,来实现对LED控制。将控制按钮分解的话,能看到一个十分简单的构造。 (注意按钮方向) 如上图所示,这个按钮有四个引脚,分别1-2导通,3-4导通,中间一个开关连接。这里或许朋友们会有疑问了,对于一个常开开关而言,这里为什么会有四个引脚,只需要两个引脚不就可以了吗?比如工业上常用的欧姆龙行程开关,如下图: 常开端一对引脚,常闭端一对引脚,触碰按钮后,原本的常开和常闭端相互切换状态。而对于实验用的这个四脚小开关,这里的四个引脚的其中一个是为了给下拉电阻做引脚而准备的,常规的欧姆龙开关一般是和工业控制器如PLC等搭配使用。而对于PLC而言,首先是电源,一般PLC电源采用DC24V,而Arduino一般是DC5V,就电源上自然Arduino就不如PLC抗干扰能力强,再一个PLC电源线以及接线一般是采用具有一定抗干扰能力的双绞线,而我们对Arduino实验时一般是采用面包线,两者抗干扰能力也不在一个级别上,所以如果Arduino在读取开关信号时不接上拉或下拉电阻,那么其误动作的概率就很大。Arduino本身有自带上拉电阻,所以实际使用过程中更推荐使用上拉模式来读取开关信号。(这里虽然说Arduino相比较PLC而言抗干扰能力上不如PLC,但并不是说Arduino就不能用于工控了。做好屏蔽,外部的抗干扰等,依旧可以实现工控,毕竟一块Arduino的价格是一个PLC的几分之一。自己做的一条自动化生产线也是采用Arduino来设计的,虽然其中有坑,但都还是解决掉了。) 电路中上下拉电阻的作用: 上拉电阻——是将不确定信号通过一个电阻钳位在高电平,电阻同时限流作用下来电阻——是将不确定信号通过一个电阻钳位在低电平 两者最终的目的都是提高电路稳定性,避免误动作。 2.按钮控制LED 分别介绍两种模式下拉与上拉。 2.1下拉模式: 接线图如下: 代码如下: void setup() { pinMode(13,OUTPUT); pinMode(2,INPUT); digitalWrite(13, LOW); } void loop() { if(digitalRead(2)==HIGH){//读取2号引脚状态,并做判断 digitalWrite(13, HIGH); } } 说明: 1.下拉模式即——pinMode(2,INPUT);。通常状态下2号引脚为低,触发高电平时有效,即将2与5V接通。 2. if语句常用判定式:<,<=,==,>=,>,!=。 布尔运算式: 例符号逻辑if(digitalRead(2)==HIGH && digitalRead(2)==HIGH){//.... }&&与if(digitalRead(2)==HIGH || digitalRead(2)==HIGH){//.... }||或 3.对于“==”判断,要小心使用成了单个等号如if(x=10)。这里单个等号是赋值运算,将恒为真。 2.2上拉模式 相比较下拉模式的接线图,上拉模式下就简单许多了。接线图如下: 代码如下: void setup() { pinMode(13,OUTPUT); pinMode(2,INPUT_PULLUP); digitalWrite(13, LOW); } void loop() { if(digitalRead(2)==LOW){ digitalWrite(13, HIGH); } } 说明:

vite+rollup

一、安装依赖: 1、npm init -y 2、npm install vite -D 3、npm install sass -D 二、在根目录新建index.html文件 三、修改package.json 1、人口文件: "main": "index.html", 2、执行脚本命令:"scripts": { "dev": "vite" } 注意: 在html 中引入外部样式表,scss 有效。如: <link rel="stylesheet" href="./index.scss"> 在html声明内部样式表lang="scss"无效。如 <style lang="scss"> $var:10px; h1{ font-size: 20px; } </style> 查看rollup 包体积分析:rollup-plugin-visualizer - npm 1、安装rollup-plugin-visualizer npm install --save-dev rollup-plugin-visualizer 2、在vite.config.js中: import { visualizer } from "rollup-plugin-visualizer"; plugins: [vue(), visualizer() ], import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite'

Linux——安装mysql数据库

目录 1、准备阶段 2、具体步骤 2.1、卸载mariadb 2.2、上传mysql并解压 2.3、安装mysql 2.4、查看版本 2.5、启动mysql服务 2.6、登录mysql 2.7、修改密码 2.8、配置mysql远程访问 2.9、修改编码 3、卸载mysql 3.1、查看mysql的安装情况 3.2、删除安装包 3.3、在/根目录下查询mysql 3.4、查找后的结果 3.5、根据查找后的结果进行删除 1、准备阶段 1、需要准备一台服务器,这里推荐大家去安装一个本地的虚拟机,VMware就是一款不错的虚拟机软件。 2、需要一个远程连接到虚拟机的工具,我这里使用的工具是MobaXterm。 3、mysql安装包下载: 链接:https://pan.baidu.com/s/1TOa1IeO68kogGCXxoveAfA 提取码:jwzn 2、具体步骤 2.1、卸载mariadb linux系统会自动携带一个数据库,我们需要把它给卸载掉 通过以下代码可以查看mariadb rpm -qa | grep mariadb 卸载mariadb yum remove mariadb-libs-5.5.52-1.el7.x86_64 -y 再次查看是否卸载成功 rpm -qa | grep mariadb 2.2、上传mysql并解压 创建mysql目录到/usr/local目录下 mkdir mysql 上传安装包到/usr/local/mysql中,进行解压 tar -xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar 2.3、安装mysql 注意:按照依赖关系依次安装rpm包 依赖关系依次为common→libs→client→server 按照顺序依次输入下列命令 rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm yum install -y net-tools

Off World Live 插件:广播UE4内部的音频信号到NDI

目的:广播UE4内部的音频信号到NDI 缘起:发现NDI-IO插件,不能对UE4的音频信号进行捕获并广播,只能对接收到外部的NDI音频信号进行捕获并广播,并且不能进行修改(比如此处将接收的Audio改成其他音效,编译将提示报错,如下:) 解决方法:下载这个软件 https://offworld.live/download-center 官方文档:http://docs.offworld.live/#/ 操作方法: 会在场景自动创建这三个Actor 预览任意视频 发现音视频均已同时开始传输 赶紧试试吧~ 对了,这个插件有几天试用期,过了就有水印,没办法人家做的就是好,编辑状态都能看到NDI实时信号

清理linux系统内存缓存

查看当前系统状态: free -h total used free shared buff/cache available Mem: 15Gi 3.2Gi 4.1Gi 8.0Mi 8.0Gi 11Gi Swap: 0B 0B 0B 一、下面先解释一下输出的内容: Mem 行(第二行):是内存的使用情况。 Swap 行(第三行):是交换空间的使用情况。 total: 列显示系统总的可用物理内存和交换空间大小。 used: 列显示已经被使用的物理内存和交换空间。 free: 列显示还有多少物理内存和交换空间可用使用。 shared: 列显示被共享使用的物理内存大小。 buff/cache: 列显示被 buffer 和 cache 使用的物理内存大小。 available: 列显示还可以被应用程序使用的物理内存大小。 二、linux服务器内粗缓存过高导致运行慢 执行如下命令清除缓存: echo 1 > /proc/sys/vm/drop_caches 当然,这个文件可以设置的值分别为1、2、3。 echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys/vm/drop_caches echo 3 > /proc/sys/vm/drop_caches 它们所表示的含义为: echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。 echo 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。 slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。 echo 3 > /proc/sys/vm/drop_caches:表示清除pagecache和slab分配器中的缓存对象。 三、执行命令

git进阶学习:git reset

git reset 作用 重置回退压缩提交撤销 撤销add撤销commit 原理: 移动 HEAD 分支的指向 (若指定了 –soft,则到此停止) 使索引看起来像 HEAD (若未指定 –hard,则到此停止) 使工作目录看起来像索引 -soft :仅修改HEAD -[mixed]:(默认)取消暂存所有的东西,回到git add 和 git commit 命令执行之前。 -hard:将当前提交替换工作区 用法 重置回退 git reset 提交id :重置为该提交IDgit reset HEAD^x: ^代表上x次git reset HEAD~x:~x代表上x次,不带x是1HEAD~2^ 和 HEAD~3等价,~3,~2,~1,HEAD,指定了四次提交。 撤销 特点:不用移动HEAD,HEAD所指的文件版本不变。撤销暂存文件(撤销add) git reset fileName 撤销提交(撤销commit) git reset commitId 压缩提交 移动HEAD至需要被压缩的提交的前一个提交,然后直接提交,中间的提交都将被压缩。 git reset *–*soft 需要被压缩的前一个提交git commit 提交

git 进阶学习:git checkout

git checkout 作用 带提交引用:检出到对应的分支带路径:重置文件 git checkout 和git reset 的区别 git checkout :是修改HEAD指向新的分支引用,然后将该引用的内容填充索引(staged)区。git reset:是移动HEAD所在分支的指向,然后将该次提交内容填充至索引区或工作区。不带路径的不同点: checkout 移动HEAD的指针的指向,不会重置。reset:移动HEAD本身,会改变分支的head的值。 带路径的不同点: checkout 相当于git reset --hard file, 会覆盖工作区。 覆盖图 下面的速查表列出了命令对树的影响。 “HEAD” 一列中的 “REF” 表示该命令移动了 HEAD 指向的分支引 用,而 “HEAD” 则表示只移动了 HEAD 自身。 特别注意 WD Safe? 一列——如果它标记为 NO,那么运行该命 令之前请考虑一下。

一键换肤 自定义css样式实现

在项目中有很多时候都有一键换肤的需求。刚好接了这样的一个需求,就把过程记录下来。 我用了自定义css来实现。 创建皮肤样式文件 定义css样式名称 样式名称必须是以 – 开头 文件内引用皮肤样式 设置根节点 使用setProperty()方法让自己定义的样式名称与样式做一个映射 此时 样式名称的定义 与样式已经完成 注:为了项目更好的维护,建议把样式名称跟样式单独放在一个文件内,使用的时候引入即可。 然后在使用的时候通过var()方法使用即可 换肤的时候我们只需要让样式名称对应不同的样式即可 自己随便写了个例子供参考,ok 大功告成 !

H3C(华三)交换堆叠/IRF配置实例

概念简介: 把多台网络设备组合一起当作一台设备来管理和使用,之前称之为堆叠技术,现在都叫虚拟化了。 华为的堆叠技术叫做VSS,锐捷的堆叠技术叫做VSU,华三的堆叠技术叫做IRF。 不同厂商的尽管叫法名字不一样,但目的都是相同的,就是把多台设备虚拟化成一台设备进行管理。所以无论是VSS、VSU还是IRF技术均支持虚拟化、链路和设备级备份。 应用需求: 两台H3C-WS5850-28F-WiNet(H3C1、H3C2)希望堆叠成一台交换机进行管理。 堆叠域:domain 0 H3C1作为主设备,堆叠口:gi1/0/27、gi1/0/28 H3C2作为从设备,堆叠口:gi1/0/27、gi1/0/28 注意事项: 1、尽量使用光口最好是10GB以上的光口,电口及千兆光口有可能会导致堆叠不成功。 2、H3C1的28口连接H3C2的27口,H3C1的51口连H3C2的28口(建议交叉连r接)。 3、在两台交换机都配置完成后在分别执行irf-port-configuration active,执行前先保存配置。 4、建议在配置完成后在接线。 5、堆叠后配置会以主机配置为准,主机的配置会同步给备机。备机原有的配置会丢失,不会同步给主机。 6、同一拓扑内同一组设备必须在同一个domain下,默认domain为0,member序号即是虚拟化后【大设备】的slot【板卡】序号。 配置实例: 1、主设备的配置 [H3C1]irf domain 0 //同一拓扑内如果有其它堆叠组,domain不能重复 [H3C1]irf member 1 priority 20 //priority:优先级,大的为主设备,其余为备,默认值为1 [H3C1]int range GigabitEthernet 1/0/27 to GigabitEthernet 1/0/28 [H3C1-if-range]shutdown //端口加入irf-port之前必须先shutdown [H3C1]irf-port 1/1 [H3C1-irf-port1/1]port group interface GigabitEthernet 1/0/27 [H3C1-irf-port1/1]port group interface GigabitEthernet 1/0/28 [H3C1]int range GigabitEthernet 1/0/27 to GigabitEthernet 1/0/28 [H3C1-if-range]undo shutdown 2、从设备的配置 [H3C2]irf domain 0 //需要跟第一台交换机保持一致 [H3C2]irf member 1 renumber 2 //把从设备默认的成员编号1重新编号为2 [H3C2]save //重启前保存配置 <H3C2>reboot //重启设备 //这步之后重启设备,接口名将会由 1/0/* 变成 2/0/* [H3C2]irf member 2 priority 10 //这条命令可不写,priority默认是 1 [H3C2]int range GigabitEthernet 2/0/27 GigabitEthernet 2/0/28 [H3C2-if-range]shutdown [H3C2]irf-port 2/2 //renumber的数字为n,则此处为n/n [H3C2-irf-port2/2]port group interface GigabitEthernet 2/0/27 [H3C2-irf-port2/2]port group interface GigabitEthernet 2/0/28 [H3C2]int range GigabitEthernet 2/0/27 to GigabitEthernet 2/0/28 [H3C2-if-range]undo shutdown 3、激活 irf 配置 [H3C1]irf-port-configuration active [H3C2]irf-port-configuration active 完成上述配置后,接线,堆叠完成。

四个在线计算和实时绘制TEC等电离层参数的Website

这个网站电离层等参数计算可以计算和绘制IRI参数:电子和离子(O+, H+, He+, O2+, NO+)密度,总电子含量,电子,离子和中性(CIRA-86)温度,赤道垂直离子漂移和其他。 目前这个网站有了新的计算界面,大家也可以试一试新界面: 这个网站实时绘制可实时呈现全球近实时f2层临界频率和峰值高度 同样这个网站Australian Space Weather Alert System也可以完成绘制 下面这个网站Ionosphere Monitoring Service over Europe是欧洲的一个电离层监测服务 这样的网站目前有很多,通过这四个网站,也可以在里面找到其他的相关资源,能为学习电离层方面的内容提供一些抓手。

B/S与C/S的区别

B/S与C/S的优缺点比较 C/S和B/S是当今世界开发模式技术架构的两大主流技术。C/S是美国 Borland公司最早研发,B/S是美国微软公司研发。目前,这两项技术以被世界各国所掌握,国内公司以C/S和B/S技术开发出产品也很多。 B/S 优点: 1、维护和升级方式简单。B/S架构的软件只需要管理服务器,所有的客户端只是浏览器,根本不需要做任何的维护。无论用户的规模有多大,有多少分支机构都不会增加任何维护升级的工作量,所有的操作只需要针对服务器进行;客户机越来越“瘦”,而服务器越来越“胖” 2、分布性强。只要有网络。浏览器,可以随时随地进行查询、浏览业务处理。 3、客户机配置门槛低。B/S模式操作简单,内存占用少,而C/S模式内存占用大,安装复杂 4、业务扩展简单方便。通过增加页面即可增加服务器功能 缺点: 1、应用服务器运行数据负荷较重 2、在跨浏览器上,BS结构不尽如人意。 3、在速度和安全性上需要花费很多设计成本,响应速度不及C/S 4、用户体验不是很理想,B/S需要单独界面设计,各个浏览器厂商的对浏览器的解析的标准不同。 客户端服务器端的交互是请求-响应模式,通常需要刷新页面,这并不是客户乐意看到的。 C/S 优点: 1、应用服务器运行数据负荷较轻。最简单的C/S体系结构的数据库应用由两部分组成,即客户应用程序和数据库服务器程序。二者可分别称为前台程序与后台程序。运行数据库服务器程序的机器,也称为应用服务器。一旦服务器程序被启动,就随时等待响应客户程序发来的请求;客户应用程序运行在用户自己的电脑上,对应于数据库服务器,可称为客户电脑,当需要对数据库中的数据进行任何操作时,客户程序就自动地寻找服务器程序,并向其发出请求,服务器程序根据预定的规则作出应答,送回结果,应用服务器运行数据负荷较轻。 2、C/S结构的界面和操作简单丰富。具有较强的事务处理能力。响应速度快。 3、由于客户端实现与服务器的直接相连,没有中间环节,只有一层交互,因此响应速度较快。 4、C/S结构的安全性能可以很容易保证,实现多层认证也不难。 5、能充分发挥客户端PC的处理能力,很多工作可以在客户端处理后再交给服务器,所以C/S客户端相应速度快 缺点: 1、维护成本高昂 C/S结构的软件需要针对不同的操作系统系统开发不同版本的软件,产品升级困难 2、客户机配置门槛高 因为客户端中不仅包含了界面渲染也包含了部分业务逻辑处理,所以对内存、cpud等的资源有很大依赖。并且客户端需要人为安装,对使用人员有一定要求 3、客户端需要安装专用的客户端软件 4、对客户端的操作系统一般也会有限制。可能适应于WinXP,但不能用于WinVista或Win7。或者不适用于微软新的操作系统等等,还有Linux、Unix等等操作系统。 1、定义 B/S结构(Browser/Server)是浏览器服务器这种开发模式,就是只安装维护一个服务器(Server),而客户端采用浏览器(Browse)运行软件。 C/S又称Client/Server或客户/服务器模式。需要做客户端服务器端 。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,如Oracle、Sybase、Informix或 SQL Server。客户端需要安装专用的客户端软件。 客户端/服务器模式与浏览器端/服务器模式,即C/S模式与B/S模式之间的区别,其实与RCP和TCP程序的区别一样,在于运行平台和数据交换模式的区别。 2、B/S架构 Browser/Server 模式是从传统的 C/S 发展起来的计算方式。C/S 是松散耦合系统通过消息传递机制进行对话由客户端发出请求给服务器服务器进行相应处理后经传递机制送回客户端;B/S 模式则把C/S 模式的服务器端进一步深化分解成应用服务器(Web 服务器)和多个数据库服务器同时简化 C/S 中的客户端将客户端的计算功能移至 Web 服务器仅保留其表示功能从而成为一种由表示层(Browser)、功能层(Web Server)与数据库服务层(DATABASE Server)构成的三层分布式结构。 B/S模式中,无需安装客户端程序,只需要通过浏览器即可访问,升级时也无需在客户端安装,因而传播更加广泛,如谷歌、百度等。 2.1、客户端-服务器-数据库(B/S三层结构) 客户机端只有 Browser一般没有应用程序,借助于 Java applet、VBScript、JavaScript、ActiveX 等技术可以处理一些简单的客户端处理逻辑显示用户界面和 Web Server 端的运行结果。它向 URL 所指定的 Web 服务器提出服务申请,Web 服务器对用户进行身份验证后用 TCP/IP 协议把所需的文件资料传送给用户,客户端只是接收文件资料并显示在浏览器上。 服务器端由 Web Server 和 DATABASE Server 构成,Web Server 负责接受远程或本地的数据查询请求然后运行服务器脚本借助于 CGI、ADO、API、JDBC 等中间部件把数据请求发送到 DB Server 上以获取相关数据再把结果数据转化成 HTML 及各种脚本传回客户的 Browse。

Git系列之暂时保存更改

文章の目录 一、使用场景二、存储临时改动三、恢复改动写在最后 在git中,可以暂时提取分支上所有的改动并存储,让开发人员得到一个干净的工作副本,临时转向其他工作。 一、使用场景 分支临时切换 二、存储临时改动 git stash 三、恢复改动 git stash pop 写在最后 如果你感觉文章不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O??? 如果你觉得该文章有一点点用处,可以给作者点个赞;\\*^o^*// 如果你想要和作者一起进步,可以微信扫描二维码,关注前端老L;~~~///(^v^)\\\~~~ 谢谢各位读者们啦(^_^)∠※!!!

为什么科来找不到网络适配器呢

重新安装了3次软件,网卡和IP也对着呢,找不到原因,一直显示“无法找到网络适配器”,头大呀 但是物理机可以找到网卡和ip,MAC地址扫描也可以找到ip地址呀 老师们,有什么操作错误,请帮忙看下

EDPLVO: Efficient Direct Point-Line Visual Odometry论文笔记

EDPLVO: Efficient Direct Point-Line Visual Odometry 本文介绍了一种使用点和线的有效直接视觉里程计 (VO) 算法。直线上的像素一般采用直接法。但是,原始光度误差仅针对点定义。似乎很难将其扩展到线条。在以前的工作中,线上点的共线约束要么被忽略 [1],要么将繁重的计算负载引入最终的优化系统 [2]。本文扩展了线的光度误差。我们证明了 2D 线上的点的 3D 点是由 2D 线的端点的反深度决定的,并为这个问题推导出了一个封闭形式的解决方案。该属性可以显着减少变量数量以加快优化速度,并且可以使共线约束完全满足。此外,我们引入了一种两步法来进一步加速优化,并证明了该方法的收敛性。实验结果表明,该的算法优于最先进的直接 VO 算法。 介绍 没有闭环的vslam称为视觉里程计也就是前端VO。 主要两点: 基于学习的方法(深度学习):基于学习的方法近年来取得了显着进展。然而,由于这些方法需要强大的 GPU,它们对于嵌入式系统上的实时应用程序是不可行的。 传统的 VSLAM 和 VO 系统仍然更适合这些应用(轻量且实时)。 传统方法通常分为两类,即基于特征的(间接)和直接方法。 基于特征的方法长期以来一直主导着这一领域。同时,最近的研究表明,直接方法显示出高精度和鲁棒性,即使在通常对基于特征的方法具有挑战性的低纹理场景中也是如此。因此,本文重点介绍 VO 的直接方法。 基于特征点的方法:(最小化重投影误差) 根据图像上的特征匹配关系得到相邻帧间的相机运动估计,它需要对特征进行提取和匹配,然后根据匹配特征构建重投影误差函数,并将其最小化从而得到相机的相对运动。 单目:2D-2D对极几何; 2D-3D:PNP; 3D-3D:ICP。 ==重投影误差:==利用我们计算得到的三维点的坐标(注意不是真实的)和我们计算得到的相机位姿(当然也不是真实的)进行第二次投影,也就是重投影。重投影误差:指的真实三维空间点在图像平面上的投影(也就是图像上的像素点)和重投影(其实是用我们的计算值得到的虚拟的像素点)的差值。 再说的简单点: 重投影误差指的是空间中某个3D点通过估计的相机位姿重投影得到的像素点,与实际拍摄图像中的像素点之间的误差(欧氏距离) 欧式距离也称欧几里得距离,是最常见的距离度量,衡量的是多维空间中两个点之间的 绝对距离 。说的再明白点 :就是我们平时学的计算二维平面上两点之间的距离。 直接法:(光度误差)光流法改进,基于灰度不变假设 直接法是假设两帧图像中的匹配像素的灰度值不变,构建光度误差函数, 也将其最小化求解帧间的相机运动。 光流法:提取图像特征点,与特征点法不同的是,光流法通过图像灰度值 (RGB)值匹配特征点,光流描述了像素在图像中的运动,再利用三角/对极几何/PnP等算法估算相机运动。减少特征点匹配所需的计算量,精度也有保证。直接法:直接使用像素块,也可以提取图像角点 (角点像素突出因此能够进行更好的匹配),通过计算灰度值(RGB)值直接解算得到运动估计(R,t)。利用像素移动直接计算得到相机的移动。一般需要位姿的初始估计,通过初始的位姿估计来得到匹配的图像特征点,通过灰度值(RGB)值优化位姿估计。运算速度快,但是由于灰度不变假设,过快的图像运动,容易陷入局部最优解。半直接法:以SVO为代表,将图像分块来做匹配。指通过对图像中的特征点图像块进行直接匹配来获取相机位姿,而不像直接匹配法那样对整个图像进行匹配。 随着一批不需提取特征的方法,如SVO(选取关键点来采用直接法,这类方法称为稀疏方法(sparse));LSD(选取整幅图像中有梯度的部分来采用直接法,这种方法称为半稠密方法(simi-dense)),直接法渐露其自身优势。DSO(Direct Sparse Odometry,稀疏直接运动估计算法),DSO的前端和LSD-SLAM相似,后端则抛弃了图优化的框架。 总结一下:直接法将数据关联(data association)与位姿估计(pose estimation)放在了一个统一的非线性优化问题中,最小化光度误差。而特征点法则分步求解,即,先通过匹配特征点求出数据之间关联,再根据关联来估计位姿。这两步通常是独立的,在第二步中,可以通过重投影误差来判断数据关联中的外点,也可以用于修正匹配结果。 下面是介绍了直接法的一些具体实现: LSD-SLAM 2014年 Large Scale Direct monocular SLAM 将直接法应用到了半稠密的单目SLAM中 1、提出了地图梯度与直接法的关系,以及像素梯度与极线方向在稠密重建中的角度关系; 2、在CPU上实现了实时半稠密场景的重建; 3、具有回环检测功能;

Quartus18.1 lite免费教育版下载及安装

目录 一、下载1、首先注册intel官网账号2、进入下载界面找到Quartus18.1教育版3、下载项目 二、安装 一、下载 intel官网: www.intel.cn 1、首先注册intel官网账号 随便在官网注册个账号,国内的邮箱也可以使用。 2、进入下载界面找到Quartus18.1教育版 注册好账号后,点击左上角的支持。 进入下载界面。 下滑此界面,找到英特尔FPGA。点击。 找到如图所示软件版本。下滑进入下载选项界面。 3、下载项目 下载如图所示勾选的三个文件。 新建一个文件夹将这三个文件安防到一起。 二、安装 此版本安装过程很简单,一路默认即可, 只需注意需要使用管理员权限运行安装包和注意更改安装路径。 以管理员身份运行 QuartusLiteSetup-18.1.0。 接受条款。点击next。 修改安装路径,注意,原来的路径是C:\intelFPGA_lite\18.1 这里直接将其改为D:\intelFPGA_lite\18.1,只修改盘符,其余不变。然后点击next。 按默认的下载选项勾选: 然后等待几分钟,安装完成。