OpenCV For Unity 入门教程(一): 实现简单的抠图

1. 需要引入 OpenCVForUnity 命名空间,结构图如下: 2.代码如下: using OpenCVForUnity; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class RemoveImage : MonoBehaviour { public int alpha = 150; void Start() { //把图片读进三通道的容器 var src = Imgcodecs.imread(Application.streamingAssetsPath + "/open.jpg", 1); //把尺寸设置为大小 Imgproc.resize(src, src, new Size(500, 500)); //建立一个四通道的容器 var dst = new Mat(src.cols(), src.rows(), CvType.CV_8UC4); //转换色彩空间 Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2RGBA); // 遍历一下这个 dst 容器, 里面是处理图像的逻辑 会输出一个处理过的 dst 返回出来 for (int i = 0; i < dst.

模板类派生模板类

#include<iostream> using namespace std; template <typename T> class A { public: T a; public: A(T a = 0) { this->a = a; } void printfA() { cout << "a= "<<a<< endl; } }; template <typename T> class B :public A < T > { public: B(T a = 0, T b = 0) :A<T>(a) { this->b = b; } void printfB() { cout <<"a="<< a<<" b="<<b << endl; } public: T b; }; int main() { A<int> a1; a1.

弹出框的方法

1、控制弹出框的位置:http://www.cnblogs.com/popfisher/p/5608436.html 2、下拉列表的指示方向变化:https://www.jb51.net/article/118507.htm 3、横竖屏的控制:https://blog.csdn.net/yhy123456q/article/details/79803450 4、ListView的上拉加载下拉刷新:https://www.cnblogs.com/rm6700/p/6029922.html 5、启动页面的demo:https://blog.csdn.net/codingandroid/article/details/51140345

剑指Offer-(三)-从尾到头打印链表

实现思路: 顺序读取链表,并依次将各节点的val字段的值存入vector<int>arr中; 定义另一个vector<int>re,从尾至头遍历arr,依次存入re中; 最后,返回re 相关知识点: 链表节点类型的定义:要包含val域和next指针域(next为ListNode类型的指针,用于指向下一节点) vector类型的重要函数用法:size();//返回元素个数; push_back();//每次在vector后面添加一个元素 个人出错点: 循环遍历链表时,指向下一节点的语句写成了temp++(这个错误真是很白痴!!![羞愧脸]),而不是temp=temp->next。导致总是提示堆栈溢出的错误 下面给出代码: /** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : * val(x), next(NULL) { * } * }; */ class Solution { public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> arr; ListNode* temp; temp=head; while(temp!=NULL) { arr.push_back(temp->val); temp=temp->next; } int len=arr.size(); vector<int>re; for(int i=len-1;i>=0;i--) { re.push_back(arr[i]); } return re; } }; 这里补充使用栈(在C++中为stack类型)实现的方式,更简单(可以顺便学习一下stack的用法)

Java位运算的基础及使用(意义)

Java位运算的基础及使用(意义) 前言一、位运算基础二、位运算应用三、位运算试题 前言 这几天在看HashMap的源码,但里面的位运算太多,看得有点晕。故,先整理位运算相关知识。 在了解位运算的计算后,又在思考,使用位运算的意义是什么,毕竟平时开发基本没用过位运算。经大量的资料查找,整理了两个自己感觉比较好的位运算利用例子,特在此记录,分享。 另外,毕竟位运算的代码可读性差,请大家谨慎使用。 一、位运算基础 1、位运算是针对整数的二进制进行的位移操作 2、整数 32位 , 正数符号为0,负数符号为1。十进制转二进制 不足32位的,最高位补符号位,其余补零 3、在Java中,整数的二进制是以补码的形式存在的 4、位运算计算完,还是补码的形式,要转成原码,再得出十进制值 5、正数:原码=反码=补码 负数:反码=原码忽略符号位取反, 补码=反码+1 例如:十进制4 转二进制在计算机中表示为(补码) 00000000 00000000 00000000 00000100 例如:十进制-4 转二进制在计算机中表示为(补码) 11111111 11111111 11111111 11111100 负数转二进制过程(以-4为例) 原码:10000000 00000000 00000000 00000100(转二进制,最高位为符号位) 反码:11111111 11111111 11111111 11111011(符号位不变,其余取反) 补码:11111111 11111111 11111111 11111100(反码+1) -4 << 1 计算过程 -4 补码 11111111 11111111 11111111 11111100 左移一位 11111111 11111111 11111111 11111000 (这时候还是补码) # 如果最高位符号位为0,就不需要继续操作了,因为正数的补码=原码,如果最高位是1,继续往下走 转成反码 11111111 11111111 11111111 11110111 (补码-1) 转成原码 10000000 00000000 00000000 00001000 (忽略符号位取反) 转十进制 -8 左移( << ) 整体左移,右边空出位补零,左边位舍弃 (-4 << 1 = -8)右移( >> ) 整体右移,左边空出位补零或补1(负数补1,整数补0),右边位舍弃 (-4 >> 1 = -2)无符号右移( >>> )同>>,但不管正数还是负数都左边位都补0 (-4 >>> 1 = 2147483646)与( & )每一位进行比较,两位都为1,结果为1,否则为0(-4 & 1 = 0)或( | )每一位进行比较,两位有一位是1,结果就是1(-4 | 1 = -3)非( ~ ) 每一位进行比较,按位取反(符号位也要取反)(~ -4 = 3)异或( ^ )每一位进行比较,相同为0,不同为1(^ -4 = -3) 二、位运算应用 在一个系统中,用户一般有查询(Select)、新增(Insert)、修改(Update)、删除(Delete)四种权限,四种权限有多种组合方式,也就是有16中不同的权限状态(2的4次方)。

30天自制操作系统学习-第1天

第一天 1 批处理文件:直接由DOS命令行解释执行的文件,通常后缀名为.bat或.cmd。 2 镜像文件:.img后缀的文件,可用于制作操作系统文件,一个3.5英寸的软盘容量为1440k。 3 nask:作者自己制作的汇编代码编译器,代码与nasm代码相差不大。 4 qemu:虚拟机的一种,命令行操作。 在作者给出的光盘文件中找到z_tools文件夹: helloos0版本: 可以看到作者给出所需的nask.exe文件和make.exe,qemu.exe等文件。 自己在硬盘任意位置新建项目文件夹,将z_tools文件夹放置与与helloos不同版本文件夹的同一个根目录下,如下图所示: 作者给出的helloos0版本的OS是直接手动输入机器码产生的.img镜像文件,大小为1440kb,刚好为一个3.5寸软盘大小。 这个helloos.img镜像文件可以直接使用虚拟机当做系统运行的,在这里我使用的是VMware虚拟机,新建虚拟机,在最后一步配置硬件时我们不使用光驱,添加一个软盘,,选取项目下的helloos.img文件: 开启虚拟机,我们可以看到虚拟机屏幕中间出现了 hello word字样: 我们使用sublime Text查看作者给出的helloos.img文件: 可以看出.img文件为二进制数据,二进制数据是计算机可以理解的数据。但是作者给出的这个文件足足有9万多行二进制数据, 如果手动操作输入的话,不免太过浪费时间。观察数据我们可以知道,在第9行二进制数据后的数据,全部都是0000 0000 0000 0000,这些数据仅仅是为了凑够1440kb数据,凑够一个3.5英寸软盘大小。 helloos1版本: 为此我们需要学习汇编语言,使用汇编语言对内存进行分配。helloos.nas文件: 这段nask代码定义的字节数刚好1440kb,其中的DB(Define Byte)是定义字节的意思,RESB则是预占内存空间的意思, RESB 16意思是从现在占用了16个字节,但是并不适用,默认为0x00(16进制),下述定义以此类推。 你可以计算一下这样定义的字节数与作者给出的helloos.img的文件字节大小,结果恰好相等。 现在我们使用作者的nask汇编文件定义好了一个1440kb大小的helloos1.nas文件(这里的1440kb并非helloos.nas文件大小), 要如何编译成helloos.img映像文件呢。 我们需要使用nask编译helloos1.nas文件,如果你使用VM虚拟机的话可以不使用作者推荐的qemu虚拟机, 这里我们使用作者的qemu虚拟机尝试启动我们制作的helloos.img镜像系统文件,作者在这里使用了批处理文件对helloos1.nas的编译,运行。 我们在helloos1文件夹下新建文本,输入文本 cmd.exe,保存文件,文件名修改为!cons_nt.bat。 新建文本输入: ..\z_tools\nask.exe helloos.nas helloos.img 文件名修改为asm.bat, 新建文本输入: copy helloos.img ..\z_tools\qemu\fdimage0.bin ..\z_tools\make.exe -C ../z_tools/qemu 文件名修改为run.bat。 这时我们已经做好了编译helloos1.nas文件,以及使用qemu虚拟机运行编译生成的helloos1.img文件的准备。 其中!cons_nt.bat的功能是在当前目录打开cmd命令行, asm.bat的功能是使用helloos1文件夹的同级文件夹z_tools文件夹下的nask.exe根据helloos.nas生成helloos.img。 run.bat的功能是复制当前生成的hellloos.img镜像文件,使用qemu运行。 具体批处理功能其实我们查看其中内容就知道大概意思了,这里至于nask如何将.nas文件编译成.img文件;以及qemu是如何运行.img镜像文件的,我们在此并不深究。 接下来我们双击打开!cons_nt.bat文件,输入asm 可以看到在helloos1.nas文件相同目录下生成了helloos.img文件,接着我们输入run,回车键入,执行run.bat: 成功启动了qemu虚拟机,并且运行了我们使用helloos1.nas生成的helloos1.img镜像系统文件。 当然qemu的使用是使用命令行的,比较麻烦,建议启用VM虚拟机。 helloos2: helloos2与helloos1的不同之处是作者修改了其中的.nas汇编代码: ; hello-os ; TAB=4 ; 以下这段是标准FAT12格式软盘专用的代码 DB 0xeb, 0x4e, 0x90 DB "

WebSocket消息类型 入门篇(三)

WebSocket实现通讯基础(消息类型,消息转码/解码基础) WebSocket协议支持三种本地消息类型 1、文本消息 2、二进制消息 3、Ping消息 和 Pong消息 无论是注解式端点还是变成是端点,实现其发送消息的API都是相同的 RemoteEndPoint接口和他的子类RemoteEndPoint.Basic(同步发送) 和 RemoteEndpoint.Async(异步发送) 提供了发送消息的所有方法 Ping 和 Pong消息的作用: 1)两种消息通常被用来检查WebSocket连接的健康性,(连接是否有效)。 2)可以通过测量Ping和Pong消息所花费的时间来测算WebSocket连接的效率。 消息发送(同步发送) 同步发送机制是由RemoteEndPoint接口的子类RemoteEndPoint.Basic实现同步发送消息的所有方法。 RemoteEndPoint.Basic API提供了三种发送字符串的方法 第一种: 该方法把传入的文本参数发送WebSocket文本信息发送,这意味着WebSocket连接的另一端将接受一个文本格式的信息, 只有在消息发送成功或者消息发送过程中抛出错误时,该方法才会返回(异常返回:发送过程中连接断开) 方法:public void sendText(String var1) throws IOException; 第二种 WebSocket提供了一种使用WriterAPI发送String消息的方式(用于将一些高层级的对象序列化String以便发送) 方法:public Writer getSendWriter() throws IOException; 第三种 WebSocket协议允许把大的WebSocket消息分解成多个小片段,使实现在整个消息被完全传送之前开始发送消息,并获得性能优化。(分片发送) 方法:public void sendText(String var1, boolean var2) throws IOException; //var2是消息结束标识,如果消息未结束则为false,如果消息为最后消息片段则为true。 RemoteEndPoint.Basic API提供了三种发送二进制消息的方法 第一种 和第一种发送字符串方法一样,一次发送完整信息,只有在消息完全发送成功,或者发送过程中抛出异常才会返回。 方法:public void sendBinary(ByteBuffer var1) throws IOException; 第二种 分片发送二进制消息 方法:public void sendBinary(ByteBuffer var1, boolean var2) throws IOException; /var2是消息结束标识,如果消息未结束则为false,如果消息为最后消息片段则为true。

CS架构&BS架构

一、CS架构 CS(Client/Server):客户端----服务器结构。C/S结构在技术上很成熟,它的主要特点是交互性强、具有安全的存取模式、网络通信量低、响应速度快、利于处理大量数据。因为客户端要负责绝大多数的业务逻辑和UI展示,又称为胖客户端。它充分利用两端硬件,将任务分配到Client 和Server两端,降低了系统的通讯开销。C/S结构的软件需要针对不同的操作系统系统开发不同版本的软件,加之产品的更新换代十分快,已经很难适应百台电脑以上局域网用户同时使用。 C/S 架构是一种典型的两层架构,其客户端包含一个或多个在用户的电脑上运行的程序,而服务器端有两种,一种是数据库服务器端,客户端通过数据库连接访问服务器端的数据;另一种是Socket服务器端,服务器端的程序通过Socket与客户端的程序通信。 二、BS架构 BS(Browser/Server):浏览器----服务器结构,是目前应用系统的发展方向。BS是伴随着Internet技术的兴起,对C/S架构的改进,为了区别于传统的C/S 模式,特意称为B/S模式。在这种结构下,通过浏览器来进入工作界面,极少部分事务逻辑在前端(Browser)实现,主要事务逻辑在服务器端(Server)实现,形成三层(3-tier)结构。这样使得客户端电脑负荷大大简化(因此被称为瘦客户端),减轻了系统维护、升级的支出成本,降低了用户的总体成本(TCO)。 BS的主要特点是分布性强、维护方便、开发简单且共享性强、总体拥有成本低。但数据安全性问题、对服务器要求过高、数据传输速度慢、软件的个性化特点明显降低,难以实现传统模式下的特殊功能要求。它是瘦客户端,对大量的数据输入以及报表的应答等都需要通过浏览器与服务器进行交互,通信开销大,而且对于实现复杂的应用构造有较大的困难。

数据库隔离级别及实现原理

事情的起源于一个面试,面试官让我说说数据库的隔离级别,以及他们各自对应着什么问题,这个还好说,说出来后他接着追问readcommited的原理,当时楞了一下,因为的确没接触过,虽然知道肯定是锁的作用,但不知道怎么说好,怎么着手,就直接说不清楚了。。。然后就凉了。。。下面记录一下吧! 所谓的数据库事务操作其实就是一组原子性的操作,要么全部操作成功,要么全部操作失败。 并行事务的四大问题: 1.更新丢失:和别的事务读到相同的东西,各自写,自己的写被覆盖了。(谁写的快谁的更新就丢失了) 2.脏读:读到别的事务未提交的数据。(万一回滚,数据就是脏的无效的了) 3.不可重复读:两次读之间有别的事务修改。 4.幻读:两次读之间有别的事务增删。 对应隔离级别 1.READ UNCOMMITTED:读未提交,不处理。 2.READ COMMITTED:读已提交,只读提交的数据,无脏读; 3.REPEATABLE READ:可重复读,加行锁,两次读之间不会有修改,无脏读无重复读; 4.SERIALIZABLE: 串行化,加表锁,全部串行,无所有问题。 1.READ UNCIMMITTED(未提交读) 事务还没提交,而别的事务可以看到他其中修改的数据的后果,也就是脏读。 2.READ COMMITTED(提交读) 首先大多数数据库系统的默认隔离级别是READ COMMITTED,这种隔离级别就是一个事务的开始,只能看到已经完成的事务的结果,正在执行的,是无法被其他事务看到的。这种级别会出现读取旧数据的现象 3.REPEATABLE READ(可重复读) REPEATABLE READ解决了脏读的问题,该级别保证了每行的记录的结果是一致的,也就是上面说的读了旧数据的问题,但是却无法解决另一个问题,幻行,顾名思义就是突然蹦出来的行数据。指的就是某个事务在读取某个范围的数据,但是另一个事务又向这个范围的数据去插入数据,导致多次读取的时候,数据的行数不一致。 总结:虽然读取同一条数据可以保证一致性,但是却不能保证没有插入新的数据 4.SERIALIZABLE(可串行化) SERIALIZABLE是最高的隔离级别,它通过强制事务串行执行(注意是串行),避免了前面的幻读情况,由于他大量加上锁,导致大量的请求超时,因此性能会比较低下,在需要数据一致性且并发量不需要那么大的时候才可能考虑这个隔离级别。 下面是各个隔离级别的原理: READ_UNCOMMITED 的原理: 1,事务对当前被读取的数据不加锁; 2,事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加 行级共享锁,直到事务结束才释放。 下面分别对应上面1,2产生的表现: 1,事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,能读到事务2对该记录的修改版本,即使该修改尚未被提交。 2,事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束。 READ_COMMITED 的原理: 1,事务对当前被读取的数据加 行级共享锁(当读到时才加锁),一旦读完该行,立即释放该行级共享锁; 2,事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加 行级排他锁,直到事务结束才释放。 表现: 1,事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,读到的只能是事务2对其更新前的版本,要不就是事务2提交后的版本。 2,事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束。 REPEATABLE READ 的原理: 1,事务在读取某数据的瞬间(就是开始读取的瞬间),必须先对其加 行级共享锁,直到事务结束才释放; 2,事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加 行级排他锁,直到事务结束才释放。 表现: 1,事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,读到的仍然是第一次读取的那个版本。 2,事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束。 SERIALIZABLE 的原理: 1,事务在读取数据时,必须先对其加 表级共享锁 ,直到事务结束才释放; 2,事务在更新数据时,必须先对其加 表级排他锁 ,直到事务结束才释放。 表现: 1,事务1正在读取A表中的记录时,则事务2也能读取A表,但不能对A表做更新、新增、删除,直到事务1结束。 2,事务1正在更新A表中的记录时,则事务2不能读取A表的任意记录,更不可能对A表做更新、新增、删除,直到事务1结束。 这里咋一看觉得能理解,但细想没有特别搞清,主要是这里面出现的几种锁,下面是数据库涉及和本文涉及到的锁的解释: 这里只针对MySQL,其他的可能有细微差别,但总体都是一个思想; MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比如,

托管代码和非托管代码的区别

什么是托管代码? 托管代码是一microsoft的中间语言,他主要的作用是在.NET FRAMEWORK的CLR执行代码前去编译源代码,也就是说托管代码充当着翻译的作用,源代码在运行时分为两个阶段: 1. 源代码编译为托管代码,(所以源代码可以有很多种,如VB,C#,J#) 2. 托管代码编译为microsoft的平台专用语言。 编译器把代码编译成中间语言(IL),而不是能直接在你的电脑上运行的机器码。中间语言被封装在一个叫程序集(assembly)的文件中,程序集中包含了描述你所创建的类,方法和属性(例如安全需求)的所有元数据。你可以拷贝这个程序集到另一台服务器上部署它。 托管代码在公共语言运行库(CLR)中运行。这个运行库给你的运行代码提供各种各样的服务,通常来说,他会加载和验证程序集,以此来保证中间语言的正确性。当某些方法被调用的时候,运行库把具体的方法编译成适合本地计算机运行的机械码,然后会把编译好的机械码缓存起来,以备下次调用。(这就是即时编译)随着程序集的运行,运行库会持续地提供各种服务,例如自动垃圾回收、运行库类型检查和安全支持等。这些服务帮助提供独立于平台和语言的、统一的托管代码应用程序行为。 Visual Basic .NET和C#只能产生托管代码。如果你用这类语言写程序,那么所产生的代码就是托管代码。如果你愿意,Visual C++ .NET可以生成托管代码。当你创建一个项目的时候,选择名字是以.Managed开头的项目类型。例如.Managed C++ application。 什么是非托管代码? 非托管代码就是在Visual Studio .NET 2002发布之前所创建的代码。例如Visual Basic 6, Visual C++ 6, 最糟糕的是,连那些依然残存在你的硬盘中、拥有超过15年历史的陈旧C编译器所产生的代码都是非托管代码。托管代码直接编译成目标计算机的机械码,这些代码只能运行在编译出它们的计算机上,或者是其它相同处理器或者几乎一样处理器的计算机上。非托管代码不能享受一些运行库所提供的服务,例如安全和内存管理等。如果非托管代码需要进行内存管理等服务,就必须显式地调用操作系统的接口,通常来说,它们会调用Windows SDK所提供的API来实现。就最近的情况来看,非托管程序会通过COM接口来获取操作系统服务。 跟Visual Studio平台的其他编程语言不一样,Visual C++可以创建非托管程序。当你创建一个项目,并且选择名字以M FC,ATL或者Win32开头的项目类型,那么这个项目所产生的就是非托管程序。 区别: 托管代码是一种中间语言,运行在CLR上; 非托管代码被编译为机器码,运行在机器上。托管代码独立于平台和语言,能更好的实现不同语言平台之间的兼容; 非托管代码依赖于平台和语言。托管代码可享受CLR提供的服务(如安全检测、垃圾回收等),不需要自己完成这些操作; 非托管代码需要自己提供安全检测、垃圾回收等操作。 托管代码就意味着托管数据?答案是否定的。 对于Visual Basic和C#来说,生活是简单的,因为你没有其它选择。当你在那些语言里面声明一个类,那么这个类的实例会在托管堆中被创建,垃圾收集器(GC)会帮我们管理这些对象的回收。但是在Visual C++中,你有另一个选择。即使你正创建一个托管程序,你可以决定哪些类是托管类型,哪些类是非托管类型的。 这就是非托管类型: class Foo { private: int x; public: Foo(): x(0){} Foo(int xx): x(xx) {} }; 这就是托管类型 __gc class Bar { private: int x; public: Bar(): x(0){} Bar(int xx): x(xx) {} }; 他们唯一的区别就是类Bar的定义中有__gc关键字。这个关键字会给代码带来巨大的区别。

CSS3实现三种切角效果

效果一: 代码:<div class="cornerCut">corner cutcorner cutcorner cutcorner cut</div> CSS: .cornerCut{ width:200px; margin: 10px 20px; height: 200px; background:#58a; color:#fff; text-align: center; font-size:10px; background:linear-gradient(45deg,transparent 15px, #58a 0); } 效果二: 代码:<div class="cornerCut2"></div> CSS: .cornerCut2{ width:200px; margin: 10px 20px; height: 200px; background:#58a; background:linear-gradient(-45deg,transparent 15px, #58a 0) bottom right, linear-gradient(45deg,transparent 15px, #58a 0) bottom left, linear-gradient(135deg,transparent 15px, #58a 0) top left, linear-gradient(-135deg,transparent 15px,#58a 0) top right; background-size: 50% 50%; background-repeat: no-repeat; } 效果三: 代码:<div class="cornerArc"></div>

Vue面试中,经常会被问到的面试题/Vue知识点整理

看看面试题,只是为了查漏补缺,看看自己那些方面还不懂。切记不要以为背了面试题,就万事大吉了,最好是理解背后的原理,这样面试的时候才能侃侃而谈。不然,稍微有水平的面试官一看就能看出,是否有真才实学还是刚好背中了这道面试题。 (都是一些基础的vue面试题,大神不用浪费时间往下看) 一、对于MVVM的理解? MVVM 是 Model-View-ViewModel 的缩写。 Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。 View 代表UI 组件,它负责将数据模型转化成UI 展现出来。 ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。 在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。 ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。 二、Vue的生命周期 beforeCreate(创建前) 在数据观测和初始化事件还未开始 created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来 beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。 mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。 beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。 updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。 beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。 destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。 1.什么是vue生命周期? 答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。 2.vue生命周期的作用是什么? 答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。 3.vue生命周期总共有几个阶段? 答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

Ubuntu源码编译opencv3.4.2时提示libswresample.so.3 ..... not found (try using -rpath or -rpath-link)

在编译opencv3.4.2时提示如题错误(见下图): 我在/usr/local/ffmpeg/lib下找到了libswresample.so,说明是链接问题,所以修改Makefile,从报错信息可得知:是opencv_test_superres.dir/处出了问题,首先cd到该目录,ls如下: 修改link.txt,修改前文件为: 添加-Wl,-rpath,/usr/local/ffmpeg/lib,/usr/local/ffmpeg/lib是libswresample.so.3的路径: 保存,退出,继续make,该问题解决。 在opencv3.4.2的编译过程中出现多次该类型问题,用相同方法解决。我有过ffmpeg配置是否正确的疑惑,但是在相同环境下编译opencv.3.2.0的时候并没有出现过该问题。 最后,如果有更好的解决方法再更新,另外如果来访的哪位大佬知道更好的解决方法,也请指教。

51单片机之定时器/计数器应用实例(方式0、1、2、3)

硬件:STC89C52RC开发工具:Keil uVision4 对于刚接触单片机的同学来说可能会对定时器/计数器的应用很蒙圈,特别是初值的计算和各种定时方式的选择。下面希望能给你带来一个清晰的思路。 定时器:一般用于软件计时,给定时器设置一个时间,时间到了系统停止当前的工作跳转到事先定义好的定时器中断函数里,函数里可以做一些周期性的事情。 计数器:一般用于检测外来脉冲信号,给计数器设置一个次数,次数到了系统停止当前的工作跳转到事先定义好的计数器中断函数里,函数里做相应的事情。 先说一下相关的寄存器,也可以直接跳过,看后面的实例分析。 配置定时器或者计数器就是对相应的寄存器进行赋值,下面是相关的寄存器描述: 第一部分寄存器: 对照着上面这一字节的每一位,进一步解析: 位(符号) 功能 TMOD.7 (GATE) 置1时,只有在脚为高、TR1=1时才可打开定时器/计数器1 置0时,TR1=1即可打开定时器/计数器1 TMOD.3 (GATE) 置1时,只有在脚为高、TR1=1时才可打开定时器/计数器0 置0时,TR1=1即可打开定时器/计数器0。 TMOD.6 ( /) 置1时,用作计数器1(从T1/P3.5脚输入) 置0时,用作定时器1 TMOD.2 (/ ) 置1时,用作计数器0(从T0/P3.4脚输入) 置0时,用作定时器0 TMOD.5/TMOD.4 (M1、M0) 定时器/计数器1 选择工作方式 方式0:M1=0,M0=0 ,13位定时器/计数器 方式1:M1=0,M0=1 ,16位定时器/计数器 方式2:M1=1,M0=0 ,8位自动重载定时器 方式3:M1=1,M0=1 ,定时器/计数器1 此时无效 TMOD.1/TMOD.0 (M1、M0) 定时器/计数器0 选择工作方式 方式0:M1=0,M0=0 ,13位定时器/计数器 方式1:M1=0,M0=1 ,16位定时器/计数器 方式2:M1=1,M0=0 ,8位自动重载定时器 方式3:M1=0,M0=0 ,双8位定时器/计数器 /*1*/ TMOD|=0x00; //选择定时器0,工作方式为0, /*2*/ TMOD|=0x30; //选择定时器1,工作方式为1 /*3*/ TMOD|=0x40; //选择计数器1,工作方式为0 用或运算是为了在给相应位赋值时不会影响无关位。可以试着解读TMOD=0xDA 第二部分寄存器: 主要看T开头的,I开头是外部中断,先不管。 位(符号) 功能 TCON.7 (TF1)

unity 动态添加动画帧事件

在游戏开发中,为了实现更好的效果,动画的应用还是很广泛的, 下面主要说一下如何动态的为动画添加相应的动画帧事件。 1.首先创建动画文件,动画根据需求自行编辑 2.脚本一定要加在播放动画的物体上: 3.代码的具体实现: 找到animator上所有的动画clip根据动画名字找到自己想修改的动画文件添加对应的帧事件 private void AddAnimationEvent() { //获取动画组件中所有动画 AnimationClip[] clips = animator.runtimeAnimatorController.animationClips; for (int i = 0; i < clips.Length; i++) { //根据动画名字 找到你要添加的动画 if (string.Equals(clips[i].name, "Animation")) { //添加动画事件 AnimationEvent events = new AnimationEvent(); //添加第一个事件 带参数 events.functionName = "event_0"; events.time = 0.02f; events.stringParameter = "参数0"; clips[i].AddEvent(events); //添加第二个事件 不带参数 events.functionName = "event_1"; events.time = 0.04f; clips[i].AddEvent(events); break; } } animator.Rebind(); } private void event_0(string parma) { Debug.Log("第一个事件:" + parma); } private void event_1() { Debug.

各种数据结构的时间复杂度分析

对于同一个数据结构来说,底层实现的不同往往会呈现出不同的时间复杂度。以数组为例: .普通数组实现顺序数组实现二分搜索树(平衡)插入O(1)O(n)O(logn)查找O(n)O(logn)O(logn)删除O(n)O(n)O(logn) 文章目录 1. 动态数组2. 数组栈3. 数组队列4. 循环数组队列数组和链表 5. 链表6. 链表栈7. 链表队列8. 双链表9. 循环链表10. 数组链表11. 集合12. 映射13. 优先队列14. 最大堆15. 线段树16. Trie前缀树17. 并查集18. AVL树19. 2-3树20. 红黑树21. 哈希表 1. 动态数组 对于一个基于Java E[]实现的动态数组Array来说,它的时间复杂度如下: 增:O(n)删:O(n)改:已知索引 O(1);未知索引 O(n)查:已知索引 O(1);未知索引 O(n)resize:通过均摊复杂度分析得 O(1) 2. 数组栈 对于一个基于动态数组Array实现的数组栈ArrayStack来说,它的时间复杂度如下: void push(E): O(1) 均摊E pop(): O(1) 均摊E peek(): O(1)int getSize(): O(1)boolean isEmpty(): O(1) 3. 数组队列 对于一个基于动态数组Array实现的数组队列ArrayQueue来说,它的时间复杂度如下: void enqueue(E): O(1) 均摊E dequeue(): O(n)E front(): O(1)int getSize(): O(1)boolean isEmpty(): O(1) 4. 循环数组队列 对于一个基于Java E[]实现的循环队列LoopQueue来说,它的时间复杂度如下:

将maven项目导出jar包

对于将maven项目导出jar包有好几种方式,我认为这种方式是最容易而且是最方便的, 这是我一个maven项目的结构: 步骤如下: 1.在pom.xml中添加构建插件,在依赖后面输入代码: <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.5.5</version> <configuration> <appendAssemblyId>false</appendAssemblyId> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.database.test.Test</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>assembly</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 2.点击箭头所指处 3.点击edit configurations 4.点击➕ 5.选择maven 6.只需加上clean package即可 7.点击运行刚刚配置的运行项目 、 8.打开项目根目录,找到target文件夹,里面含有jar包,就是这个项目导出的包。如图所示: maven项目导出至此jar完毕

关于URL中带空格的问题

URL中的空格有时候被编码成%20,有时候被编码成加号+,曾经迷糊过一段时间,后来查了下资料才搞明白。 一个URL的基本组成部分包括协议(scheme)、 域名、端口号、路径和查询字符串(路径参数和锚点标记就暂不考虑了)。路径和查询字符串之间用问号?分离。例如http://www.example.com/index?param=1,路径为index,查询字符串(Query String)为param=1。URL中关于空格的编码正是与空格所在位置相关:空格被编码成加号+的情况只会在查询字符串部分出现,而被编码成%20则可以出现在路径和查询字符串中。 造成这种混乱局面的原因在于:W3C标准规定,当Content-Type为application/x-www-form-urlencoded时,URL中查询参数名和参数值中空格要用加号+替代,所以几乎所有使用该规范的浏览器在表单提交后,URL查询参数中空格都会被编成加号+。而在另一份规范RFC2396,定义URI)里, URI里的保留字符都需转义成%HH格式(Section 3.4 Query Component),因此空格会被编码成%20,加号+本身也作为保留字而被编成%2B,对于某些遵循RFC 2396标准的应用来说,它可能不接受查询字符串中出现加号+,认为它是非法字符。所以一个安全的举措是URL中统一使用%20来编码空格字符。 Java中的URLEncoder本意是用来把字符串编码成application/x-www-form-urlencoded MIME格式字符串,也就是说仅仅适用于URL中的查询字符串部分,但是URLEncoder经常被用来对URL的其他部分编码,它的encode方法会把空格编成加号+,与之对应的是,URLDecoder的decode方法会把加号+和%20都解码为空格,这种违反直觉的做法造成了当初我对空格URL编码问题的困扰。因此后来我的做法都是,在调用URLEncoder.encode对URL进行编码后(所有加号+已被编码成%2B),再调用replaceAll(“\\+”, “%20″),将所有加号+替换为%20。 例如:对空格的处理方式 1、先把空格:换成%20,再用encodeURI加密 2、获取参数,再用decodeURI解密

Could not resolve all artifacts for configuration ':classpath'

今天刚开始用grpc,结果遇到 Could not resolve all artifacts for configuration ':classpath' 原因在于,之前创建了一个maven文件,但该maven文件的格式存在错误。 将该maven文件删除,重启git bush看是否可以 如果还不可以,用ccleaner清除一下垃圾注册表之类的,然后重启git bush!