简介 LinkedBlockingDeque是一个由链表结构组成的双向阻塞队列,即可以从队列的两端插入和移除元素。双向队列因为多了一个操作队列的入口,在多线程同时入队时,也就减少了一半的竞争。
相比于其他阻塞队列,LinkedBlockingDeque多了addFirst、addLast、peekFirst、peekLast等方法,以first结尾的方法,表示插入、获取获移除双端队列的第一个元素。以last结尾的方法,表示插入、获取获移除双端队列的最后一个元素。
LinkedBlockingDeque是可选容量的,在初始化时可以设置容量防止其过度膨胀,如果不设置,默认容量大小为Integer.MAX_VALUE。
LinkedBlockingDeque类有三个构造方法:
public LinkedBlockingDeque() public LinkedBlockingDeque(int capacity) public LinkedBlockingDeque(Collection<? extends E> c) LinkedBlockingDeque源码详解 LinkedBlockingDeque类定义为:
public class LinkedBlockingDeque<E> extends AbstractQueue<E> implements BlockingDeque<E>, java.io.Serializable 该类继承自AbstractQueue抽象类,又实现了BlockingDeque接口,下面介绍一个BlockingDeque接口,该接口定义如下:
public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> BlockingDeque继承自BlockingQueue和Deque接口,BlockingDeque接口定义了在双端队列中常用的方法。
LinkedBlockingDeque类中的数据都被封装成了Node对象:
static final class Node<E> { E item; Node<E> prev; Node<E> next; Node(E x) { item = x; } } LinkedBlockingDeque类中的重要字段如下:
// 队列双向链表首节点 transient Node<E> first; // 队列双向链表尾节点 transient Node<E> last; // 双向链表元素个数 private transient int count; // 双向链表最大容量 private final int capacity; // 全局独占锁 final ReentrantLock lock = new ReentrantLock(); // 非空Condition对象 private final Condition notEmpty = lock.
项目管理案例教程(第三版)习题及答案
第一章软件项目管理概述 一、填空题 1、实现项目目标的制约因素有(项目范围)、(成本)、(进度计划)、(客户满意度)等。 2、项目管理包括(启动过程组)、(计划过程组)、(执行过程组)、(控制过程组)、(收尾过程组)5个过程组。 二、判断题 1、搬家属于项目。(对) 2、项目是为了创造一个唯一的产品或提供一个唯一的服务而进行的永久性的努力。(错) 3、过程管理就是对过程进行管理,目的是要让过程能够被共享、复用,并得到持续的改进。(对) 4、项目具有临时性的特征。(对) 5、日常运作存在大量的变更管理,而项目基本保持连贯性的。(错) 6、项目开发过程中可以无限制地使用资源。(错) 三、选择题 1、下列选项中不是项目与日常运作的区别的是(C) A. 项目是以目标为导向的,日常运作是通过效率和有效性体现的。 B. 项目是通过项目经理及其团队工作完成的,而日常运作是职能式的线性管理。 C.项目需要有专业知识的人来完成,而日常运作的完成无需特定专业知识。 D.项目是一次性的,日常运作是重复性的。 2、下列选项中最能体现项目的特征(C) A.运用进度计划技巧 B.整合范围与成本 C.确定期限 D.利用网络进行跟踪 3、以下都是日常运作和项目的共同之处,除了(D) A.由人来做 B.受限于有限的资源 C.需要规划、执行和控制 D.都是重复性工作 4、项目经理的职责不包括(D) A.开发计划 B.组织实施 C.项目控制 D.提供资金 5、下列选项中属于项目的是(C) A.上课 B.社区保安 C.野餐活动 D.每天的卫生保洁 6、下列选项中正确的是(C) A.一个项目具有明确的目标而且周期不限 B.一个项目一旦确定就不会发生变更 C.每个项目都有自己的独特性 D.项目都是一次性的并由项目经理独自完成 7、(B)是为了创造一个唯一的产品或提供一个唯一的服务而进行的临时性的努力。 A.过程 B.项目 C.项目群 D.组合 8、(B)是一系列伴随着项目的进行而进行,目的是确保项目能够达到期望结果的一系列管理行为。 A.人力资源管理 B.项目管理 C.软件项目管理 D.需求管理 9、下列活动中不是项目的是(C) A.野餐活动 B.集体婚礼 C.上课 D.开发操作系统 10、下列选项中不是项目的特征的是(C) A.项目具有明确的目标 B.项目具有限定的周期 C.项目可以重复进行 D.项目对资源成本具有约束性 四、问答题 1、项目管理知识体系(PMBOK)包括哪10个知识领域? 答:项目集成管理、项目范围管理、项目时间管理、项目成本管理、项目质量管理、项目人力资源管理、项目沟通管理、项目风险管理、项目采购管理、项目干系人管理
2、请简述项目管理的5个过程组及其关系。(可简答) 答:(1)启动过程组:主要是确定一个项目或一个阶段可以开始了,并要求着手实行;定义和授权项目或者项目的某个阶段。(2)计划过程组:为完成项目所要达到的商业要求而进行的实际可行的工作计划的设计、维护,确保实现项目的既定商业目标。计划基准是后面跟踪和监控的基础。(3)执行过程组:根据前面制定的基准计划,协调人力和其他资源,去执行项目管理计划或相关子计划。(4)控制过程组:通过监控和检测过程确保项目达到目标,必要时采取一些修正措施。集成变更控制是一个重要的过程。(5)收尾过程组:取得项目或阶段的正式认可并且有序地结束该项目或阶段。向客户提交相关产品,发布相关结束报告,并且更新组织过程资产并释放资源。 关系:各个过程组通过其结果进行连接,一个过程组的结果或输出是另一个过程组的输入。其中,计划过程组、执行过程组、控制过程组是核心管理过程组。
这是希望你在build之前创建一个独立的文件夹来存储build文件。你应该按照下面的方式进行cmake:
cd opencv mkdir build cd build cmake -D CMAKE_BUILD_TYPE=RELEASE -D \ CMAKE_INSTALL_PREFIX=/usr/local .. 一定要注意后面的两个点不能省略,这两个点指明了opencv源码的位置。
如果你执行了上面的操作以后仍然报错,那么查看一下你的opencv文件夹里是否存在CMakeCache.txt,该文件是上次cmake时候留下的缓存文件,将该文件删除,然后再执行上面的操作,就不会报错了
转载请注明原创地址:https://blog.csdn.net/qq_30356613/article/category/6897125
ORBSLAM中对于特征点的匹配在不同情况下有不同的匹配方式。分为以下几种:
1. 按照投影进行匹配
2. 按照bow向量节点进行匹配
3. 针对初始化地图点的匹配
4. 针对单目三角化的匹配
5. 基于相似矩阵的匹配
6. 通过匹配来提出冗余地图点
一、首先看按照投影进行的匹配
按照投影方式的不同将其分为上一帧投影到当前帧(tracking线程的按照运动模型进行位姿估计),关键帧投影到当前帧(tracking线程的重定位),地图点投影到当前帧(tracking线程的局部地图追踪进行位姿估计),地图点通过相似矩阵投影到关键帧(回环检测线程中)
1、地图点投影到当前帧的方式匹配(tracking线程的局部地图追踪进行位姿估计)
总体思路是遍历所有地图点,分别向当前帧进行投影,在当前帧中找到一个描述子距离最相近的特征点作为其匹配点。
首先根据地图点在金字塔中的层数确定该地图点在当前帧的搜索半径,然后以该地图点在当前帧的投影(在tracking线程中调用Frame::isInFrustum(MapPoint *pMP, float viewingCosLimit)来确定地图点在当前帧的投影像素坐标)为中心进一步确定地图点在当前帧的投影区域。得到当前帧在投影位置搜索半径内的所有特征点。分别计算这些特征点描述子与当前地图点最优描述子的距离,找到最小距离对应的特征点,作为当前地图点在该帧中的匹配。匹配筛选(剔除误匹配):(1)匹配描述子距离小于阈值。(2)这里的匹配还计算了第二最优匹配点(描述子距离第二小),目的是计算第一匹配点/第二匹配点的比率(小于1),当比率大时说明第二匹配点和第一匹配点相当,第一匹配点描述子没有特别的“优越性”,在这种情况下不妨舍弃这对匹配,防止发生误匹配。将得到的匹配地图点添加进当前帧的地图点容器中,索引坐标为该地图点对应的特征点在当前帧的特征索引。
2、上一帧投影到当前帧的匹配方式(tracking线程的按照运动模型进行位姿估计)
总体思路是遍历上一帧中所有地图点,分别向当前帧进行投影,在当前帧中找到一个描述子距离最相近的特征点作为其匹配点。
首先根据上一帧地图点在上一帧图像金字塔中的层数确定该地图点在当前帧图像金字塔中的层数,根据金字塔层数确定搜索半径,然后将该地图点的世界坐标系下的坐标根据相机内参数矩阵和旋转平移矩阵(注意这里的旋转平移矩阵是根据上一帧的旋转平移矩阵和上一帧的位姿变化速度推算的当前帧的初始位姿)投影到当前帧,得到上一帧地图点在当前帧的像素坐标(判断投影后的像素坐标的有效性),以投影结果为中心以金字塔层数确定的搜索半径为半径作为搜索区域,从而得到当前帧在投影区域内的所有特征点。分别计算这些特征点描述子与上一帧待追踪地图点的最优描述子距离,找到最小距离对应的特征点,作为上一帧待追踪地图点在该帧中的匹配点。最后进行匹配筛选(剔除误匹配):(1)匹配描述子距离小于阈值。(2)这里的匹配还计算了第二最优匹配点(描述子距离第二小),目的是计算第一匹配点/第二匹配点的比率(小于1),当比率大时说明第二匹配点和第一匹配点相当,第一匹配点描述子没有特别的“优越性”,在这种情况下不妨舍弃这对匹配,防止发生误匹配。(3)如果需要判别匹配点的方向则通过梯度方向直方图进行筛选。将得到的匹配地图点添加进当前帧的地图点容器中,索引坐标为该地图点对应的特征点在当前帧的特征索引。
3、关键帧投影投影到当前帧的匹配方式(tracking线程的重定位)
总体思路是遍历关键帧中所有地图点,分别向当前帧进行投影,在当前帧中找到一个描述子距离最相近的特征点作为其匹配点。
首先根据当前帧的初始位姿(在重定位过程中PNP方式来计算位姿作为当前帧的初始位姿)和相机内参数矩阵,将关键帧的地图点映射到当前帧,从而得到关键帧的地图点在当前帧的映射像素坐标,将映射的像素坐标作为中心,然后根据地图点到光心的距离推算该特征点对应的高斯金字塔层数,从而确定搜索半径并确定关键帧地图点在当前帧匹配的搜索区域,从而得到当前帧在投影区域内的所有特征点。分别计算这些特征点描述子与上一帧待追踪地图点的最优描述子距离,找到最小距离对应的特征点,作为上一帧待追踪地图点在该帧中的匹配点。最后进行匹配筛选(剔除误匹配):(1)匹配描述子距离小于阈值。(2)这里的匹配还计算了第二最优匹配点(描述子距离第二小),目的是计算第一匹配点/第二匹配点的比率(小于1),当比率大时说明第二匹配点和第一匹配点相当,第一匹配点描述子没有特别的“优越性”,在这种情况下不妨舍弃这对匹配,防止发生误匹配。(3)如果需要判别匹配点的方向则通过梯度方向直方图进行筛选。将得到的匹配地图点添加进当前帧的地图点容器中,索引坐标为该地图点对应的特征点在当前帧的特征索引。
4、地图点通过相似矩阵投影到关键帧(回环检测线程中计算得到相似矩阵之后匹配当前检测关键帧(回环末端)和回环关键帧(回环始帧)的局部地图点进行匹配)
总体思路是遍历回环关键帧的所有共视图地图点,将这些地图点利用求得的sim矩阵投影到当前检测关键帧下,在当前关键帧中找到一个描述子距离最相近的特征点作为其匹配点。
首先根据当前帧的相似变换矩阵(在回环检测过程中通过sim求解器求解)和相机内参数矩阵,将回环关键帧的共视地图点映射到当前检测关键帧,从而得到共视地图点在当前待检测回环关键帧的映射像素坐标,将映射的像素坐标作为中心,然后根据地图点到光心的距离推算该特征点对应的高斯金字塔层数,从而确定搜索半径并确定关键帧地图点在当前帧匹配的搜索区域,从而得到当前帧在投影区域内的所有特征点。分别计算这些特征点描述子与上一帧待追踪地图点的最优描述子距离,找到最小距离对应的特征点,作为上一帧待追踪地图点在该帧中的匹配点。最后进行匹配筛选(剔除误匹配):(1)匹配描述子距离小于阈值。
二、按照bow向量节点进行匹配
按照BOW向量节点进行匹配有一个明显的优势是在此之前不需要知道任何关于两个匹配对象的几何关系,在第一节中讲到的按照投影的方式进行的匹配,都是给定两匹配对象的初步几何关系,然后根据初步的几何关系确定一个投影区域(投影中心和投影半径),在投影区域内寻找匹配。而相对于投影的匹配方式,按照BOW节点向量进行搜索匹配就不需要预先的集合关系了,按照BOW向量进行的匹配直接根据之前维护的词袋模型,在所有相同bow节点下的特征点中进行搜索匹配,同样更快速。这种方式往往在无法给定两匹配对象之间的初步几何关系时使用。根据匹配对象不同又分为:(1)关键帧和当前帧通过词袋进行快速匹配(1.用在tracking线程根据参考关键帧进行线程追踪过程中2.重定位)(2)关键帧和当前帧通过词袋进行快速匹配(回环检测)
具体如下:
1、关键帧和当前帧通过词袋进行快速匹配(1.用在tracking线程根据参考关键帧进行线程追踪过程中2.重定位)
总体思路是遍历关键帧中所有特征向量和当前帧中的所有特征向量,计算在同一BOW节点下两特征向量的距离,找到一对描述子距离最相近的特征点作为匹配点。
首先取出关键帧和当前帧的特征向量(注意这里的特征向量是根据节点id排序好的特征向量(用DBOW库中的特征向量),便于我们进行搜索),然后遍历关键帧的每一个特征向量,在当前帧的同一节点下搜索其匹配点(计算同一节点特征向量对应描述子的距离最小匹配作为其匹配点)。最后进行匹配筛选(剔除误匹配):(1)匹配描述子距离小于阈值。(2)这里的匹配还计算了第二最优匹配点(描述子距离第二小),目的是计算第一匹配点/第二匹配点的比率(小于1),当比率大时说明第二匹配点和第一匹配点相当,第一匹配点描述子没有特别的“优越性”,在这种情况下不妨舍弃这对匹配,防止发生误匹配。(3)如果需要判别匹配点的方向则通过梯度方向直方图进行筛选。将得到的匹配地图点添加进匹配地图点容器中,索引坐标为该地图点对应的特征点在当前帧的特征索引。
2、关键帧和关键帧帧通过词袋进行快速匹配(回环检测)
总体思路是遍历关键帧1中所有特征向量和关键帧2中的所有特征向量,计算在同一BOW节点下两特征向量的距离,找到一对描述子距离最相近的特征点作为匹配点。
首先取出关键帧1和关键帧2的特征向量(注意这里的特征向量是根据节点id排序好的特征向量(用DBOW库中的特征向量),便于我们进行搜索),然后遍历关键帧1的每一个特征向量,在关键帧2的同一节点下搜索其匹配点(计算同一节点特征向量对应描述子的距离最小匹配作为其匹配点)。最后进行匹配筛选(剔除误匹配):(1)匹配描述子距离小于阈值。(2)这里的匹配还计算了第二最优匹配点(描述子距离第二小),目的是计算第一匹配点/第二匹配点的比率(小于1),当比率大时说明第二匹配点和第一匹配点相当,第一匹配点描述子没有特别的“优越性”,在这种情况下不妨舍弃这对匹配,防止发生误匹配。(3)如果需要判别匹配点的方向则通过梯度方向直方图进行筛选。将得到的匹配地图点添加进匹配地图点容器中,索引坐标为该地图点对应的特征点在当前帧的特征索引。
三、针对单目初始化的匹配(单目初始化中)
总体思路是针对单目初始化的匹配,由于在单目初始化之前并没有深度信息即还没有计算地图点,因此不能和一般的匹配一样通过遍历地图点进行匹配,只能通过遍历图像的特征点。
首先取帧1中的所有特征点,根据给定参数搜索窗口确定搜索半径,根据该特征点在帧1中的2D位置估计其在帧2中的搜索中心,从而根据搜索中心和半径确定搜索范围,在帧2中搜索当前特征点的匹配点。最后进行匹配筛选(剔除误匹配):(1)匹配描述子距离小于阈值。(2)这里的匹配还计算了第二最优匹配点(描述子距离第二小),目的是计算第一匹配点/第二匹配点的比率(小于1),当比率大时说明第二匹配点和第一匹配点相当,第一匹配点描述子没有特别的“优越性”,在这种情况下不妨舍弃这对匹配,防止发生误匹配。(3)如果需要判别匹配点的方向则通过梯度方向直方图进行筛选。将得到的匹配地图点添加进匹配地图点容器中,索引坐标为该地图点对应的特征点在当前帧的特征索引。
四、针对单目三角化的匹配(在localmapping线程中新建地图点时调用)
此匹配方式主要应用于localmapping线程中新建地图点,此次新建地图点是针对于tracking线程中没有匹配到的地图点。总体思路是针对单目的尺度不确定性,在计算地图点深度时进行的匹配,利用三角测量筛选匹配点的正确性。匹配的是当前处理的关键帧及其相邻关键帧。
首先循环所有关键帧1中的所有BOW节点,并在关键帧2中寻找与其具有相同BOW节点的特征点索引,循环关键帧2中找到的相同BOW节点下特征点索引,计算两关键帧中特征点的描述子距离,从而选择最小的描述子距离的一对特征点作为一对匹配点。注意这里在确定匹配之前需要进行对极约束(关键帧2中的匹配点距离根据关键帧1计算得到的极线的距离来判断匹配点是否满足对极几何)。最后进行匹配筛选(剔除误匹配):(1)匹配描述子距离小于阈值。(2)如果需要判别匹配点的方向则通过梯度方向直方图进行筛选。将得到的匹配地图点添加进匹配地图点容器中,索引坐标为该地图点对应的特征点在当前帧的特征索引。
五、基于相似矩阵的匹配(用于回环检测计算相似矩阵之后)
获取关键帧1 2的相机位姿以及相机1->相机2的位姿变换相似矩阵
双向匹配:
根据相似矩阵将关键帧1中的地图点向关键帧2中投影,确定投影区域,并在投影区域内寻找关键帧1中地图点的匹配
根据相似矩阵将关键帧2中的地图点向关键帧1中投影,确定投影区域,并在投影区域内寻找关键帧2中地图点的匹配
根据双向匹配结果,如果两次匹配都能成功,则确定该对匹配是有效的.将其存入vpMatches12容器 最终返回匹配点对个数
六、通过匹配来提出冗余地图点
1、融合地图点匹配(用于局部建图线程的关键帧地图点及其相邻帧的融合)
将MapPoints投影到关键帧pKF中,并判断是否有重复的MapPoints
1> 如果MapPoint能匹配关键帧的特征点,并且该点有对应的MapPoint,那么将两个MapPoint合并(选择观测数多的)
2> 如果MapPoint能匹配关键帧的特征点,并且该点没有对应的MapPoint,那么为该点添加MapPoint
投影方式和剔除误匹配的方式与上述方式类似,不再赘述。
2、融合地图点(用于回环检查线程,根据相似矩阵融合当前关键帧和地图点融合)
根据相似矩阵Scw映射地图点到关键帧。
主要思路: 将回环地图点根据当前关键帧的位姿(相似矩阵)映射到当前关键帧,在当前关键帧中寻找回环地图点的代替点,存储进vpReplacePoint
投影方式和剔除误匹配的方式与上述方式类似,不再赘述。
转载请注明原创地址: https://blog.csdn.net/qq_30356613/article/category/6897125 单目相机由于深度是未知的,因此我们需要对其进行初始化,在 ORB-SLAM 中将其用单独的类来表示,并将它写成单独的文件 initializer.cc,注意单目相机即使在进行初始化之后,仍然存在尺度问题,初始化将第一帧的位移作为单位长度,后面的深度和位移都是依据这一标准进行的,所以尺度问题是单目 slam 的理论缺点。 单目 slam 初始化需要两帧进行,第一帧作为参考初始化帧,第二帧作为当前帧。在第一帧来临时建立初始化器,并将该帧的特征点存储起来,初始化器Initializer的构造函数中有三个参数,分别是初始化参考帧的引用,标准差 sigma 和 RANSAC 迭代次数 iterations (选择 8 点时使用), initializer.cc 只存在一个外部调用函数 initialize() ,此函数通过计算当前帧的相机位姿和匹配点对应的 3D 点来对单目 slam 初始化。初始化中通过 RANSAC 的方法来优化初始化的效果,用 8 点法来同步计算单应性矩阵 H 和基础矩阵 F ,从而计算出两者分别的得分,得分方式是通过计算投影误差的和来确定。得分越高证明当下模型下的矩阵越可信,然后选择得分高的矩阵进行分解,从而得到相机位姿和三维匹配点。 其中主要涉及到的算法分别是:8点-DLT方法计算基础矩阵,8点-DLT方法计算单应矩阵,根据基础矩阵分解得到相机位姿和3D匹配点,根据单应矩阵分解得到相机位姿和3D匹配点。
一、8点DLT方法计算基础矩阵:
(参考高翔slam14讲)
首先应明白基础矩阵的几何意义是什么?它解决的问题是如何通过两幅图像中的像素匹配点来估算两幅图像点的变换矩阵F(基础矩阵)。
设的空间位置为:,在两帧图像中的像素坐标分别为:
则有:,这里K为相机内参数矩阵,R,t为旋转矩阵和平移矩阵。
取齐次坐标有: 取,这里x1,x2是两个像素点的归一化平面上的坐标。代入上式得:
两边同时左乘,得到:
两边同时左乘,得到:
将p1,p2带入上式得到:
从而得到对极约束的代数表示,其中为基础矩阵F,为本质矩阵E
然后根据8点法求解本质矩阵E,进而求解基础矩阵F
设,分别是匹配点的归一化坐标,,并将E写成向量形式则有:
用SVD方法求解上述方程,E的解对应的是最小奇异值对应的奇异向量,证明过程参考《Multiple view geometry in computer vision》.page592 A5.3
由此求得本质矩阵E,进而求取基础矩阵F
二、本质矩阵分解得到旋转矩阵R和平移向量t
(参考 multiple view geometry in computer vision 9.6节的相关知识)
上个算法中通过8点法得到了本质矩阵E,但实际上本质矩阵需要满足自身的约束,对于一个本质矩阵E来讲,它的奇异值有两个相等,并且第三个为零。证明如下:
上面可以看出,其中S是向量t对应的反对称矩阵,形式如下:设t(t1,t2,t3)
则,而却对于任意的反对称矩阵S,我们都有如下结论:
微信公众号是否二次开发,即微信公众号是否使用了公众平台开发接口(其中主要如:自定义菜单接口、配置第三方开发服务器接口、调用外部链接等)。
接下来介绍如何用手机直观的去判断微信公众号是否二次开发,主要从自定义菜单和调用外部链接来判断。
(一) 如何判断微信公众号是否使用自定义菜单接口
首先,微信公众号中,认证订阅号和服务号(认证和非认证)都可以生成自定义菜单。判断操作步骤如下:
1. 打开一个微信公众号,查看应用最下方的是否为输入框,如图1所示,就是未使用自定义菜单的公众号。大部分的微信公众号,如果未使用自定义菜单功能,基本上都没有做二次开发,因为自定义菜单是公众号二次开发使用的最普遍功能。
图1
2. 查看最下方的是否是如图2的菜单栏,或如图3的输入框,虽然图3显示是输入框,但是最左边有个切换按钮,点击之后菜单栏会显示。
图2
图3
(二)如何判断微信公众号是否调用外部链接
首先外部链接是相对于微信公众号官方链接来区别的,微信公众号官方链接的域名是mp.weixin.qq.com,除此之外的链接都属于非微信公众号官方链接的外部链接。
微信公众号调用外部链接的主要方式是通过自定义菜单的跳转功能,点击菜单会跳转到运营者设定的网页(也许是官方页面,也许是外部页面)。判断操作步骤如下:
1. 打开有自定菜单功能的微信公众号,如图4点击自定义菜单,打开如图5界面。
图4
图5
2. 在图5界面,将页面下滑,会出现图6所示的“此网页由XXXXXXX.com 提供”的字样,此处就是如何分辨是否调用外部链接的地方。
图6
3. 还有一种特殊情况,就是网页无法下拉,这个时候就需要点击微信右上方的“详情”按钮,如图7所示。
图7
4. 如图7点击“详情”按钮之后,会弹出如图8的界面,在其中找到“复制链接”按钮并点击,再将链接粘贴至输入框内,这样就能获取到当前页面的真实链接。
图8
如有疑问,欢迎指正和讨论~
type - 基本层类型 类型:Number,默认:0 layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
layer.closeAll(); //关闭所有层 layer.closeAll(‘dialog’); //关闭信息框 layer.closeAll(‘page’); //关闭所有页面层 layer.closeAll(‘iframe’); //关闭所有的iframe层 layer.closeAll(‘loading’); //关闭加载层 layer.closeAll(‘tips’); //关闭所有的tips层
//监听提交,发送请求
form.on('submit(add)', function(data){
$.post("<%=basePath%>platformUser/updateScore",data.field,function(data){
// 获取 session
if(data.code!=200){
layer.alert(data.msg, {offset: 't',icon: 5});
}
if(data.code==200){
layer.alert(data.msg, {offset: 't',icon: 6},function () {
layer.close(layer.index);
window.parent.location.reload();
});
}
});
return false;
}); 转载于:https://www.cnblogs.com/SeaWxx/p/9140411.html
一、问题描述: 最近重装Windows 10系统后准备升级软件版本,发现MySQL新版本为5.7.10,于是按照以前的操作方式安装(①解压ZIP;②安装Windows服务;③启动MySQL服务;③修改root默认空密码),然后先后发现了启动失败、修改密码失败等问题,遂整理以下操作以分享。(实测安装版没有此问题)
问题 启动失败,MySQL 服务无法启动、服务没有报告任何错误。 启动失败,MySQL 服务无法启动、服务没有报告任何错误。 原因:MySQL 5.7.6 changelog:废弃了mysql_install_db,使用mysqld –initialize (formerly known as “mysqld –bootstrap,” now deprecated.)替代。 总结:MySQL将需要使用命令–initialize初始data,具体请看”操作步骤”。
问题 修改密码失败,Access denied for user ‘root’@’localhost’ (usering password: NO)。 修改密码,Access denied for user ‘root’@’localhost’ (usering password: NO)。 原因:MySQL 5.7.4 changelog:可以跳过 -skip-random-password 选项来默认生成随机密码。 MySQL 5.7.5 changelog:还是默认生成随机密码,但是选项修改为 –insecure。 总结:MySQL升级日中”提升MySQL安全性”将抛弃空”“密码初始方式,通过命令–initialize初始data并生成随机密码。
问题 在dos环境下使用net start mysql来启动服务,但是报错 原因:因为当前用户的操作权限太低了。 解决方法:切换到管理员模式就可以启动了。所以我们要以管理员身份来运行cmd程序来启动mysql。
二、安装步骤: 下载链接:https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.22-winx64.zip 1.解压至目录D:\Program Files\MySQL\mysql-5.7.10
2.复制新文件my.ini,并存入mysql的根目录下,新文件my.ini粘贴以下内容:
# For advice on how to change settings please see # http://dev.
参考链接
下载https://github.com/coreybutler/nvm-windows/releases,本次安装直接是通过直接下载安装包的方式,直接点击下载链接中的nvm-setup.zip,下载后直接进行安装,选择nvm安装路径,第二个路径为下载的node.js的路径,通过测试发现,第二个路径并没有生效,下载的node.js的路径仍然为nvm路径。
通过查找资料,可以设置安装目录下install.cmd文件可以更改下载路径,在本次安装中没有进行对应设置,如果想进一步设置,可以参考链接,进行对应设置。
cmd中键入命令
nvm install v8.11.2 进行自定义版本的下载。
cmd中键入命令
nvm use 8.11.2 设置当前使用的版本。
nvm node 命令 报错:'node' 不是内部或外部命令,也不是可运行的程序或批处理文件。
更改NVM_SYMLINK的路径就可以使用node.js的命令了,如果不更改路径会报不能找到命令的错误。参考链接
输入中文时,如果候选栏显示英文乱码、无法显示中文,如下图所示,可按如下方式处理:
cd ~/.config rm -rf SogouPY* sogou* 然后注销登录 或者重启 即可。
有些同学这样做了以后还是不行,包括我自己也会。可以试下以下方法:
如果是剛安裝完的搜狗輸入法,則輸入: sudo apt-get install -f,進行依賴性檢查,判斷是否缺依賴項。如果是之前一直可以输入中文的,突然无法输入的,则不是依赖项的问题,进行下一步。输入命令:killall fcitx 关闭输入法进程。删除配置文件,ubuntu下搜狗的配置文件在 ~/.config下的3个文件夹里:rm -r SogouPY SogouPY.users sogou-qimpanel然后重启。
注释:本文翻译自OpenCV3.0.0 document->OpenCV-Python Tutorials,包括对原文档种错误代码的纠正
1.概述
现在我们知道特征匹配,让我们把它和calib3d模块混合起来,找到复杂图像中的对象
2.目标
在这一章中,我们将混合来自calib3d模块的特征匹配和findHomography,以在复杂图像中查找一直对象。
3.基础
那么我们在上一章节做了什么?我们使用一个queryImage,在其中找到了一些特征点,我们又拍了一个trainImage,在那张图片中找到了特征,我们找到了它们中最好的匹配。简而言之,我们在另一个混乱的图像中发现了一个物体某些部分的位置。该信息足以在trainImage上准确找到对象。
为此,我们可以使用calib3d模块中的一个函数,即cv2.findHomography()。如果我们通过这两个图像中的一组点,它将找到该对象中的每个变换。然后我们可以使用cv2.perspectiveTransform()来查找对象。它需要至少四个正确的点来找到转换。
我们已经看到,匹配时可能会出现一些可能的错误,这可能会影响结果。为了解决这个问题,算法使用RANSAC或LEAST_MEDIAN(可以由标志决定)。所以提供正确估计的好匹配被称为内点,其余称为离群点。cv2.findHomography()返回一个指定内点和外点的掩码。
let do it!
4.代码
首先,像往常一样,在图像中找到SIFT特征,并应用比率测试来查找最佳匹配。
# -*- coding: utf-8 -*- ''' 特征匹配和Homography查找对象: 1.将特征匹配和calib3d模块混合起来,找到复杂图像中的对象。 2.将来自calib3d模块的特征匹配和findHomography 3.可以使用cv2.findHomography()。如果找到这两个图像中的一组点,它将找到该对象的每个变换。 4.然后使用cv2.perspectTransform()来查找对象。它至少需要四个正确的点来找到转换。 5.匹配的时候可能会有一丢丢错误。 栗子: ''' import cv2 import numpy as np from matplotlib import pyplot as plt MIN_MATCH_COUNT = 10 img1 = cv2.imread('box.png', 0) # 查询图片 img2 = cv2.imread('box_in_scene.png', 0) # 训练图片 # 初始化SIFT探测器 sift = cv2.xfeatures2d.SIFT_create() # 用SIFT找到关键点和描述符 kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.
文中基于apache的httpclient 4.5.2,代理服务器有用户名密码鉴权。
首先,对于鉴权,我们需要设置身份认证,并通过配置的身份认证信息来创建一个httpclient;
接下来需要创建一个代理,并设置到请求信息中;
最后是执行请求。
代码如下:
CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope(代理IP, 代理port), new UsernamePasswordCredentials(鉴权用户名, 鉴权密码)); CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); HttpHost proxy = new HttpHost(代理IP, 代理port); RequestConfig config = RequestConfig.custom().setProxy(proxy).build(); HttpPost req = new HttpPost(目标URL);// GET请求用HttpGet req.setConfig(config); CloseableHttpResponse resp = client.execute(req); try { System.out.println(resp); } finally { resp.close(); }在测试中笔者犯了几个很低级的错误,首先目标URL不能是localhost/127.0.0.1,因为这样其实代理服务器请求的是自己,但是因为代理服务器本地并没有部署对应服务,所以会返回失败,笔者这里返回的是503错误。另一个是因为笔者请求的代理是部署在公有云上的,如果使用的是内网IP也是不行的,因为根本找不到那个IP,所以使用前要确认代理是部署在哪的。 参考文献:
https://blog.csdn.net/ktlifeng/article/details/51099370
https://blog.csdn.net/zhangbin666/article/details/78351096?locationNum=4&fps=1
由于测试需要,找了好久才找到相关的代码,emmm
接下来贴一下这部分代码吧
local event_layout = ccui.Layout:create()
function GameTest:get_mouse_pos()
local function onTouchBegan(touch, event) return true end local function onTouchEnded(touch, event) local location = touch:getLocation() local event_x = location["x"] or 0 local event_y = location["y"] or 0 end local listener = cc.EventListenerTouchOneByOne:create() listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN ) listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED ) local eventDispatcher = event_layout:getEventDispatcher() eventDispatcher:addEventListenerWithSceneGraphPriority(listener, event_layout) end
然后就能拿到鼠标点击的位置了
注释:本文翻译自OpenCV3.0.0 document->OpenCV-Python Tutorials,包括对原文档种错误代码的纠正
1.目标
学习SIFT算法的概念学习如何找到SIFT关键点和描述符 2.理论
在最后几章,我们看到了一些角落探测器,如Harris Corner等。它们是旋转不变的,这意味着,即使图像旋转,我们也可以找到相同的角落。这是显而易见的,因为角落在旋转中也是角落。但是缩放呢?如果图像缩放,角落可能不是角落。例如,请看下面的简单图片。放大同一个窗口时,小窗内的小图像的一个角落是平坦的。所以Harris Corner的角落是规模不变的。
因此,2004年,不列颠哥伦比亚大学的D.Lower在他的论文中提出了一种新的算法——尺度不变特征变换(SIFT),该算法从尺度不变关键点获取图像的特征,提取这个关键点并计算其描述符。(本文很容易理解,并被认为是SIFT上最好的资料,所以这个解释只是本文的一个简短摘要)。
SIFT算法主要涉及四个步骤,我们将逐一看到它们:
2.1 尺度空间极值检测(Scale-space Extrema Detection)
从上图可以看出,我们不能使用相同的窗口来检测不同比例的关键点。小角落也行,但是要检测更大的角落,我们需要更大的窗口。为此,使用缩放空间滤波。其中高斯拉普拉斯是为具有各种值的图像找到的。LoG作为一个斑点检测器,可以检测由于变化而产生的各种大小的斑点。简而言之,作为一个缩放参数,例如,在上面的图像中,低的高斯核为小角赋值较高,而高斯的高斯核适合较大的角。因此,我们可以找到跨尺度和空间的局部最大值,它给出了值的列表,这意味着尺度下(x,y)处存在潜在的关键点。
但这个LoG花费代价有点大,所以SIFT算法使用高斯差分,这是LoG的近似值。随着这两个不同图像的高斯模糊差异,可以得到高斯差分,让它为和。这个过程是在高斯金字塔的不同八度的图像中完成的。它在下面的图像中表示:
一旦找到这个DoG,图像就会在比例和空间上搜索到局部极值。例如,图像中的一个像素与其8个邻居以及下一个尺度的9个像素和先前尺度的9个像素进行比较。如果它是一个局部极值,这是一个潜在的关键点,它基本上意味着关键点最好在这个范围内表现出来,它显示在下面的图像中:
针对不同的参数,本文给出了一些经验数据,可以总结为八度数(number of octaves)=4,比例级数(number of scale levels)=5,初始,等作为最优值。
2.2 关键化本地点(Keypoint Localization)
一旦找到潜在的关键点位置,就必须对其进行改进以获得更准确的结果。他们使用泰勒级数展开的尺度空间来获得更精准的极值位置,并且如果这个极值的强度小于阈值(根据纸张为0.03),它将被拒绝。该阈值在OpenCV中被称为contrastThreshold。
DoG对边缘有更高的响应,所以边缘也需要去除。为此,使用类似Harris角点检测器的概念。他们用2*2的Hessian矩阵(H)来计算失真曲线,我们从Harris角点检测器知道,对于边缘,一个特征值比另一个大。所以这里他们使用了一个简单的函数。
如果此比率比阈值(在OpenCV中称为edgeThreshold)高,则丢弃该关键点。在纸上给出10,因此它消除了任何低对比度关键点和边缘关键点,剩下的就是强烈的兴趣点。
2.3 方向分配(Orientation Assignment)
现在为每个关键点分配一个方向以实现图像的旋转不变性。在关键点位置周围取决于尺度,并在该区域计算梯度幅度和方向。创建一个方向直方图,其中36个方框覆盖360度,(用等于关键点尺度的1.5倍的梯度幅度和高斯加权窗口进行加权,得到直方图中的最高峰值,并且在任何高于80%的峰值也被认为是计算方向。)创建具有相同位置和规模但方向不同的关键点,有助于匹配的稳定性。
2.4 关键点描述符(keypoint Descriptor)
现在创建关键点描述符。关键点周围有一个16*16的街区(Block)。它分为16个4*4大小的字块。对于每个字块,创建8个方向直方图。所以共有128bin值可用。它被表示为形成关键点描述符的向量。除此之外,它还采取了几项措施来实现对光照变化、旋转等的鲁棒性。
2.5 关键点匹配(Keypoint Matching)
两幅图像之间的关键点通过识别它们最近的邻居来匹配。但在某些情况下,第二个最接近的匹配可能非常接近第一个。这可能是由于噪音或其它的原因。在那种情况下,采用最近距离与第二距离的比率,如果它大于0.8,则被拒绝。根据文章,它被排除了大约90%的错误匹配,而丢弃的只有5%的匹配正确。
所以这是SIFT算法的总结。欲了解更多细节和理解,强烈建议阅读原文。记住一件事,这个算法是获专利的。所以这个算法被包含在OpenCV的非自由模块中。
3.OpenCV中的SIFT
现在让我们来看看OpenCV中提供的SIFT函数。让我们从关键点检测并开始绘制它们,首先,我们必须构建一个SIFT对象。我们可以将不同的参数传递给它,这些参数是可选的,并且在文档中有很好的解释。
# -*- coding: utf-8 -*- ''' SIFT(尺度不变特征变换)介绍 SIFT算法主要涉及四个步骤: 1.尺度空间极值检测(scale-space Extrema Detection) 2.关键点本地化 3.方向分配 4.关键点描述符 5.关键点匹配 下面的demo是OpenCV中的SIFT函数:cv2.SIFT() ''' import cv2 img = cv2.imread('5.jpg') gray = cv2.
注释:本文翻译自OpenCV3.0.0 document->OpenCV-Python Tutorials,包括对原文档种错误代码的纠正
1.目标
我们将了解harris corner detection背后的概念学习函数:cv2.cornerHarris()、cv2.cornerSubPix() 2.理论
在上一章中,我们看到角落是图像中各个方向强度变化很大的区域。早在1988年,Chris Harris & Mike Stephens就在其论文A Combined Corner and Edge Detector中发现了这些角落的一个早期尝试,现在它被称为harris Corner Detector。他把这个简单的思想变成了一种数学形式。它基本找到了所有方向上的(u,v)位移的强度差异。这表示如下:
窗口函数是一个矩形窗口或高斯窗口,它给在其中的像素加权。
我们必须使边角检测的函数 最大化,这意味着,我们必须最大限度地利用第二个参数。将泰勒展开式应用于上述方程并使用一些数学步骤(请参阅你喜欢的任何标准教科书以获得完整推导),我们的最终方程式为:
其中M为:
这里I_x和I_y分别是在x和y方向上的导数(使用cv2.Sobel()可以得到)。
然后是主要部分。在此之后,他们创建了一个分数,基本上是一个等式,它将决定一个窗口是否可以包含边角。
其中:
和 是M的特征值 所以这些特征值的值决定了一个区域是角落,边缘还是平面。
当 很小,也就是介于 和 之间,该区域是平面.当 ,也就是当 或相反时,该区域是边缘.当 很大,即当 和 都很大并且R介于 之间, 该区域是边角. 可以如下图表示:
所以Harris Corner检测的结果是一个灰度图像与这些数值,合适的阈值会给出图像中的边角。所以我们会用一个简单的图像来做到这点。
3.OpenCV中的harrisCorner检测器
为此,OpenCV中有cv2.cornerHarris(),它的参数是:
Img:输入图像,应该是灰度和float32类型blockSize:这是考虑边角检测的领域大小ksize:使用Sobel衍生物的孔径参数k:harris Corner检测器的自由参数 下面是一个栗子:
# -*- coding: utf-8 -*- ''' harris Corner检测 1.OpenCV中的函数cv2.cornerHarris()和cv2.cornerSubPix() 2.cv2.cornerharris()参数: img:输入图像 blockSize:这是考虑检测的领域大小 ksize:使用Sobel衍生物的孔径参数 k:harris Corner检测器的自由参数 ''' import cv2 import numpy as np filename = 'blox.
原创
标题:激光样式
x星球的盛大节日为增加气氛,用30台机光器一字排开,向太空中打出光柱。
安装调试的时候才发现,不知什么原因,相邻的两台激光器不能同时打开!
国王很想知道,在目前这种bug存在的情况下,一共能打出多少种激光效果?
显然,如果只有3台机器,一共可以成5种样式,即:
全都关上(sorry, 此时无声胜有声,这也算一种)
开一台,共3种
开两台,只1种
30台就不好算了,国王只好请你帮忙了。
要求提交一个整数,表示30台激光器能形成的样式种数。
注意,只提交一个整数,不要填写任何多余的内容。
DFS:
每一台机器都只有开和关两种状态,机器关闭是不需要满足任何条件的,打开机器需要判断其左右两边是否有机器打开。
在深搜过程中,让每一台机器都尝试关闭/打开这2种状态,当深搜完最后一台时,激光样式+1,回溯。
public class Main{ static int arr[]=new int[32]; static long total=0L; static int Judge(int value) { if(arr[value-1]==1 || arr[value+1]==1) { return 0; //相邻的灯有灯开 } return 1; } static void fun(int num) { if(num==31) { total++; return; } int i=0; for(i=0;i<=1;i++) { //0表示关灯,1表示开灯 if(i==0) { //关灯一定可以 fun(num+1); } if(i==1) { //试着开灯 if(Judge(num)==1) { arr[num]=1; fun(num+1); arr[num]=0; //回溯 } } } } public static void main(String args[]) { fun(1); System.
简介 栅栏类似于闭锁,它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。
CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用。
CyclicBarrier源码解析 CyclicBarrier的类图如下: 通过类图我们可以看到,CyclicBarrier内部使用了ReentrantLock和Condition两个类。它有两个构造函数:
public CyclicBarrier(int parties) { this(parties, null); } public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程使用await()方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
CyclicBarrier的另一个构造函数CyclicBarrier(int parties, Runnable barrierAction),用于线程到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景。
await方法 调用await方法的线程告诉CyclicBarrier自己已经到达同步点,然后当前线程被阻塞。直到parties个参与线程调用了await方法,CyclicBarrier同样提供带超时时间的await和不带超时时间的await方法:
public int await() throws InterruptedException, BrokenBarrierException { try { // 不超时等待 return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen } } public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException { return dowait(true, unit.
前言 在项目开发中,记录日志是必做的一件事情。而当我们使用Springboot框架时,记录日志就变得极其简单了。
springboot内置了slf4j日志框架,我们只需要添加依赖,做一些简单的配置就ok了。
下面,我们就来看看在Springboot项目中如何使用slf4j。
如何在Springboot中使用slf4j记录日志 首先,我们还是新建一个Springboot工程。
在创建工程时,我们直接加入所需要的依赖。(Web依赖里包含tomcat,所以我们需要一起加入,以便测试)
在这里,博主使用的时IDEA。
需要注意的是,Lombok这个依赖需要安装插件,我们直接可以在线安装:
打开File -- setting -- Plugins
然后直接搜Lombok就可以安装了。
关于lombok还有很多别的功能,比如使用@Data注解可以为一个bean自动生成getter , setter方法及toString 方法 。。。
好了,现在我们已经创建好了项目,我们可以看一下pom文件
lombok的依赖已经成功加入。
现在,我们在yml文件中配置日志级别:info
这样,我们的配置就完成了。
测试 接下来就是测试了:
我们新建一个Controller
package com.space.slf4j; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author zhuzhe * @date 2018/6/3 16:17 * @email 1529949535@qq.com */ @Slf4j @RestController public class TestController { @RequestMapping("/log") public String testLog(){ log.info("######### info #########"); log.debug("######### debug #########"); log.error("######### error #########"); return null; } } 加入@Slf4j的注解。此时,你会发现在该类中你可以直接使用一个log对象。这就证明你的插件和依赖起作用了。
在使用python时经常会遇到一些编码的错误
例如'gbk' codec can't decode byte 0xbe in position 18: illegal multibyte sequenc
源代码片段为
很明显从错误中我们可以指导,这是因为文本文档采用的是gbk编码,这个时候我们需要转换成python能识别的编码,比如utf-8
描述 给定两个字符串,请设计一个方法来判定其中一个字符串是否为另一个字符串的置换。
置换的意思是,通过改变顺序可以使得两个字符串相等。
您在真实的面试中是否遇到过这个题? 是 样例 "abc" 为 "cba" 的置换。
"aabc" 不是 "abcc" 的置换。
使用哈希表即可轻松解决问题。
class Solution { public: /** * @param A: a string * @param B: a string * @return: a boolean */ bool Permutation(string &A, string &B) { // write your code here unordered_map<char,int> str1; for(auto ch:A) str1[ch]++; unordered_map<char,int> str2; for(auto ch:B) str2[ch]++; if(str1==str2) return true; else return false; } };
刚刚在测试接口时,修改一直提示提交失败,很奇怪,之前跟移动端联调接口时,也偶尔会出现这样的问题,sql 确定没问题,怎么就提交失败呢?因为是偶尔出现的情况而且不知道怎么复现,就安慰自己说是可能有什么机制当 sql 连接超过某个时间就不执行了也就没有多思考。
现在再次遇到这个情况才认真的捋了捋,当接口中判断到修改的返回执行行数为0时就返回提交失败,代码如下:
if (mobileUserService.update(user) > 0) { return Msg.success("提交成功!"); }else{ return Msg.error("提交失败!"); } 那也就是说,此时的修改执行的行数确实是0。于是将日志打印的修改的 sql 语句拿到数据库中执行了如下:
从上面的结果可以看出,MySQL 中执行没有报错但是受影响行数确实是0。为什么呢?改了其中一个字段值后再执行,受影响行数就变成1了。
查询资料发现,MySQL 为了提升性能,当它发现要执行的修改内容与数据库中完全一致时,对它而言,此时修改是毫无意义的,反而会消耗一次执行修改的性能,于是它就不再做修改,因而受影响行数就是0。
那么基于 MySQL 这样的做法,我们在程序中怎么做呢?
个人认为,第一种方法是在修改操作执行前手动做一次查询,若要修改的内容与数据库中的一致,那就直接返回成功的信息。第二种方法是,去掉代码中对执行行数的判断,执行后直接返回成功。因为一般情况下,数据库都会执行成功。
----------------------------------------------------------------------------------- END -------------------------------------------------------------------------------
项目经常涉及到时间戳和Date类型的相互转换、时间类型处理等,我有时候一段时间不写就又忘记了,故而写篇笔记备忘下!
本文主要包含的有:
时间戳与Date类型的相互转换判断是否为同一天日期格式化给日期加上指定时长得到指定时间节点的Date 1、时间戳转Date 注:以下的方法中很多常量和方法我都没有提取出来,正式项目中还是建议大家封装在时间处理类中,规范化操作
public static void main(String[] args) { // 10位的秒级别的时间戳 long time1 = 1527767665; String result1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time1 * 1000)); System.out.println("10位数的时间戳(秒)--->Date:" + result1); Date date1 = new Date(time1*1000); //对应的就是时间戳对应的Date // 13位的秒级别的时间戳 double time2 = 1515730332000d; String result2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time2); System.out.println("13位数的时间戳(毫秒)--->Date:" + result2); } 10位数的时间戳(秒)--->Date:2018-05-31 19:54:25 13位数的时间戳(毫秒)--->Date:2018-01-12 12:12:12 尤其要注意上面10位的秒级别的时间戳时,不能用int来定义time1变量,否则会得到错误的结果:
public static void main(String[] args) { // 10位的秒级别的时间戳 int time1 = 1527767665; //错误做法 String result1 = new SimpleDateFormat("
SPOOL 命令可以把查询结果输出到指定文件中,这样可以保存查询结果并方便打印。SPOOL命令的语法格式如下: SPO[OL] [file_name[.ext] [CRE[ATE] | REP[LACE] | APP[END]] | OFF | OUT] 参数 file_name 用于指定脱机文件的名称,默认的文件扩展名为LST。在该参数后面可以跟一个关 键字,该关键字有以下几种情况: CRE[ATE]:表示创建一个新的脱机文件,这也是SPOOL 命令的默认状态。 REP[LACE]:表示替代已经存在的脱机文件。 APP[END]:表示把脱机内容附加到一个已经存在的脱机文件中。 OFF | OUT:表示关闭SPOOL 输出。 【案例】使用 spool 命令创建emp.txt 文件,并将scott.emp 表中销售员(SALESMAN)的记录保存到该文件中,代码如下。 SQL> spool c:\emp.txt SQL> select empno,ename,job,sal from scott.emp where job='SALESMAN'; EMPNO ENAME JOB SAL ---------- ---------- --------- ---------- 7499 ALLEN SALESMAN 1600 7521 WARD SALESMAN 1250 7654 MARTIN SALESMAN 1250 7844 TURNER SALESMAN 1500 SQL> spool off
上面程序的执行结果是:从 spool 命令开始(但不包括该命令行),一直到spool off 命令行(包括该命令行)之间的所有内容都被写入emp.
大小写有区别
一般写为:yyyy-MM-dd HH:mm:ss,其中在小时部分有hh和HH的区别,hh为12小时格式,HH为24小时格式。还有最主要的是MM和mm的区别,MM代表的是月份只能用在月份上,mm代表的是分钟只能用在分钟上这两个必须固定。其它的位置必须用小写的,大写的C#就不认识了。
C# yyyyMMddHHmmss转yyyy-MM-dd HH:mm:ss –转自 https://blog.csdn.net/u010997144/article/details/52038284 1、yyyyMMddHHmmss转yyyy-MM-dd HH:mm:ss
[csharp] view plain copy
string temp_time = "20091225091010"; DateTime dateTime = DateTime.ParseExact(temp_time, "yyyyMMddHHmmss", CultureInfo.CurrentCulture, DateTimeStyles.None); 或者
[csharp] view plain copy
string temp_time = "20091225091010"; string results = DateTime.ParseExact(temp_time, "yyyyMMddHHmmss", null).ToString("yyyy-MM-dd HH:mm:ss"); 2、yyyy-MM-dd HH:mm:ss转yyyyMMddHHmmss
[csharp] view plain copy
string src = "2009-12-25 09:10:10"; string result = DateTime.ParseExact(src, "yyyy-MM-dd HH:mm:ss", null).ToString("yyyyMMddHHmmss");
基于Spring SpringMVC Mybaits框架基础上。
安装好redis: Redis 安装(Windows和Linux ) https://blog.csdn.net/qq_22860341/article/details/77533372
1,引入依赖或者jar
<!--redis--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.1.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.3</version> </dependency> 或者
jedis-2.9.0.jar commons-pool2-2.4.2.jar spring-data-redis-1.7.1.RELEASE.jar 2,配置redis.properties
redis.host=127.0.0.1 redis.port=6379 redis.password=19931009 redis.maxIdle=300 redis.maxWaitMillis=1000 redis.maxTotal=600 redis.maxWait=-1 redis.testOnBorrow=true redis.testOnReturn=true redis.projectNam=ssm_redis redis.timeout=100000 defaultCacheExpireTime=3600 3,在springmvc.xml中配置中加入
<!--引入redis.properties配置多个以逗号或者/分割--> <context:property-placeholder location="classpath:url.properties,classpath:redis.properties"/> <!-- jedis 连接池配置 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}"/> <property name="maxWaitMillis" value="${redis.maxWait}"/> <property name="testOnBorrow" value="${redis.testOnBorrow}"/> </bean> <!-- redis连接工厂 --> <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="poolConfig" ref="poolConfig"/> <property name="port" value="
1、工程目录结构及功能简要说明:
首先,该文章目的主要是记录自己学习过程,遇到的问题的一些总结,用thymelea模板f和bootstrap等搭建一个菜单框架。
工程结构如下:
2、配置文件及代码:
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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yu</groupId> <artifactId>springBoot</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springBoot</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!-- 基础组件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 测试组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 热部署组件 --> <dependency> <groupId> org.springframework.boot</groupId> <artifactId> spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- web支持 --> <dependency> <groupId>org.
In our fictional world we sometimes have some rather complicated classes, which need to be constructed. The classes contain different implementations of an interface depending on how they are constructed. In order to simplify the building of these classes and encapsulate the knowledge about building the class away from the consumers, a builder may be used. Multiple concrete builders reduce the complexity of the constructor in the implementation. When new builders are required, a constructor does not need to be added, a new builder just needs to be plugged in.
一、对AOP的初印象 首先先给出一段比较专业的术语(来自百度):
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方 式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个 热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑 的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高 了开发的效率。 然后我们举一个比较容易理解的例子(来自:Spring 之 AOP):
要理解切面编程,就需要先理解什么是切面。用刀把一个西瓜分成两瓣,切开的切口就是切面;炒菜,锅与炉子共同来完成炒菜,锅与炉子就是切面。web层级设计中,web层->网关层->服务层->数据层,每一层之间也是一个切面。编程中,对象与对象之间,方法与方法之间,模块与模块之间都是一个个切面。
我们一般做活动的时候,一般对每一个接口都会做活动的有效性校验(是否开始、是否结束等等)、以及这个接口是不是需要用户登录。
按照正常的逻辑,我们可以这么做。 这有个问题就是,有多少接口,就要多少次代码copy。对于一个“懒人”,这是不可容忍的。好,提出一个公共方法,每个接口都来调用这个接口。这里有点切面的味道了。 同样有个问题,我虽然不用每次都copy代码了,但是,每个接口总得要调用这个方法吧。于是就有了切面的概念,我将方法注入到接口调用的某个地方(切点)。
这样接口只需要关心具体的业务,而不需要关注其他非该接口关注的逻辑或处理。 红框处,就是面向切面编程。
二、AOP中的相关概念 看过了上面的例子,我想大家脑中对AOP已经有了一个大致的雏形,但是又对上面提到的切面之类的术语有一些模糊的地方,接下来就来讲解一下AOP中的相关概念,了解了AOP中的概念,才能真正的掌握AOP的精髓。 这里还是先给出一个比较专业的概念定义:
Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。Target(目标对象):织入 Advice 的目标对象.。Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程 然后举一个容易理解的例子: 看完了上面的理论部分知识, 我相信还是会有不少朋友感觉到 AOP 的概念还是很模糊, 对 AOP 中的各种概念理解的还不是很透彻. 其实这很正常, 因为 AOP 中的概念是在是太多了, 我当时也是花了老大劲才梳理清楚的.
注释:本文翻译自OpenCV3.0.0 document->OpenCV-Python Tutorials,包括对原文档种错误代码的纠正
3.10 OpenCV中的图像变换 第一节:傅里叶变换(Fourier Transform)
1.目标
使用OpenCV查找图像的傅里叶变换利用Numpy中可用的FFT函数傅里叶变换的一些应用我们将学习以下函数:cv2.dft()、cv2.idft()等 2.原理
傅里叶变换用于分析各种滤波器的频率特性。对于图像,使用2D离散傅里叶变换(DFT)来查找频域。称为快速傅里叶变换(FFT)的快速算法用于计算DFT。有关这些细节可以在任何图像处理或信号处理教科书中找到。请参考其它资源部份。
对于一个正弦信号, ,我们可以说f是信号的频率,如果取其频率域,我们可以在f处看到一个尖峰。如果信号被采样以形成离散信号,我们得到相同的频域。但是在范围 或 或 ,你可以将图像视为在两个方向上采样的信号。因此,在X方向和Y方向进行傅里叶变换将为你提供图像的频率表示。
更直观地说,对于正弦信号,如果幅度在短时间内变化得如此之快,则可以说它是高频信号。如果变化缓慢,则是低频信号。你可以将相同的想法扩展到图像。图像中振幅的变化幅度如何?在边缘点,或噪音?所以我们可以说,边缘和噪音是图像中的高频内容,如果振幅没有太大的变化,则它是低频分量。(一些链接被添加到附加资源中,通过示例直观地解释频率转换)。
现在我们将看到如何找到傅里叶变换。
3.Numpy中的傅里叶变换
首先,我们将看到如何使用Numpy查找傅里叶变换。Numpy有一个FFT软件包来做到这一点。np.fft.fft2()为我们提供了频率变换,这将是一个复杂的数组。它的第一个参数是灰度的输入图像,第二个参数是可选的,它决定输出数组的大小。如果它大于输入图像的大小,则在计算FFT之前,输入图像用0填充。如果它小于输入图像,输入图像将被裁剪。如果没有参数传递,则输出数组大小将与输入相同。
现在一旦得到结果,零频率分量(直流分量)将位于左上角。如果要将它置于中心,则需要在两个方向上将结果移动 。这只是通过np.fft.fft2()完成的(分析起来更容易)。一旦你找到频率变换,就可以找到幅度谱。
示例如下:
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('5.jpg', 0) f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布 fshift = np.fft.fftshift(f) # 默认结果中心点位置是在左上角,转移到中间位置 magnitude_spectrum = 20 * np.log(np.abs(fshift)) # 结果是复数,求绝对值才是振幅 # 结果展示 plt.subplot(121), plt.imshow(img, 'gray') plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(magnitude_spectrum, 'gray') plt.title('Magnitude Spectrum'), plt.
2019独角兽企业重金招聘Python工程师标准>>> 其实两者相辅相成,作用刚好相反 urlencode()函数原理就是首先把中文字符转换为十六进制,然后在每个字符前面加一个标识符%。 urldecode()函数与urlencode()函数原理相反,用于解码已编码的 URL 字符串,其原理就是把十六进制字符串转换为中文字符 转载于:https://my.oschina.net/u/3848823/blog/1821039
注释:本文翻译自OpenCV3.0.0 document->OpenCV-Python Tutorials,包括对原文档种错误代码的纠正
该章节分为以下四个小节:
(一) Contours:Getting Started(轮廓:开始)
(二) Contours Features(轮廓特征)
(三) Contours Properties(轮廓属性)
(四) Contours:More Functions(轮廓:更多方法)
(五) Contours Hierarchy(轮廓分级)
第一小节:Contours:GettingStarted 1.目标:
明白什么是轮廓学会找到这些轮廓,绘制轮廓学习这些函数:cv2.findContours(),cv2.drawContours() 2.什么是轮廓
轮廓可以简单地解释为连接所有连续点(沿着边界),具有相同颜色或强度的曲线。轮廓是形状分析和物体检测和识别的有用工具。
为了更高的准确率,使用二值图像。在寻找轮廓之前,应用阈值或canny边缘检测findContours函数修改源图像,所有想要在找到轮廓后保存源图像,提前把源图像赋值给其它变量再OpenCV中,查找轮廓就像从黑色背景中找到白色物体,所以记住,找到的物体应该是白色的,背景应该是黑色的。 下面的栗子:在二值图像中找到轮廓
''' Opencv中的轮廓: demo1 ''' import cv2 img = cv2.imread('2.jpg') # 图像灰度化 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 3*3核的高斯滤波 gray = cv2.GaussianBlur(gray, (3, 3), 0) # canny边缘检测 gray = cv2.Canny(gray, 100, 300) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # binary是最后返回的二值图像 #findContours()第一个参数是源图像、第二个参数是轮廓检索模式,第三个参数是轮廓逼近方法 #输出是轮廓和层次结构,轮廓是图像中所有轮廓的python列表,每个单独的轮廓是对象边界点的(x,y)坐标的Numpy数组 binary, contours, hierarchy = cv2.
DNS协议 我们之前已经了解过ARP协议。 如果说ARP协议是用来将IP地址转换为MAC地址,那么DNS协议则是用来将域名转换为IP地址(也可以将IP地址转换为相应的域名地址)。 我们都知道,TCP/IP中使用的是IP地址和端口号来确定网络上某一台主机上的某一个程序,不免有人有疑问,为什么不用域名来直接进行通信呢? 1. 因为IP地址是固定长度的,IPv4是32位,IPv6是128位,而域名是变长的,不便于计算机处理。 2. IP地址对于用户来说不方便记忆,但域名便于用户使用,例如www.baidu.com这是百度的域名。 总结一点就是IP地址是面向主机的,而域名则是面向用户的。 hosts文件 域名和IP的对应关系保存在一个叫hosts文件中。 最初,通过互联网信息中心来管理这个文件,如果有一个新的计算机想接入网络,或者某个计算IP变更都需要到信息中心申请变更hosts文件。其他计算机也需要定期更新,才能上网。 但是这样太麻烦了,就出现了DNS系统。
DNS系统 一个组织的系统管理机构, 维护系统内的每个主机的IP和主机名的对应关系如果新计算机接入网络,将这个信息注册到数据库中用户输入域名的时候,会自动查询DNS服务器,由DNS服务器检索数据库,得到对应的IP地址 我们可以通过命令查看自己的hosts文件: 在域名解析的过程中仍然会优先查找hosts文件的内容。 DNS理论知识 一、DNS域名结构 1、域名的层次结构 域名系统必须要保持唯一性。 为了达到唯一性的目的,因特网在命名的时候采用了层次结构的命名方法: 1. 每一个域名(本文只讨论英文域名)都是一个标号序列(labels),用字母(A-Z,a-z,大小写等价)、数字(0-9)和连接符(-)组成 2. 标号序列总长度不能超过255个字符,它由点号分割成一个个的标号(label) 3. 每个标号应该在63个字符之内,每个标号都可以看成一个层次的域名。 4. 级别最低的域名写在左边,级别最高的域名写在右边。 域名服务主要是基于UDP实现的,服务器的端口号为53。 关于域名的层次结构,如下图所示: eg :我们熟悉的,www.baidu.com 1. com: 一级域名. 表示这是一个企业域名。同级的还有 “net”(网络提供商), “org”(⾮非盈利组织) 等。 2. baidu: 二级域名,指公司名。 3. www: 只是一种习惯用法。
2、域名的分级 域名可以划分为各个子域,子域还可以继续划分为子域的子域,这样就形成了顶级域、二级域、三级域等。 如下图所示: 其中顶级域名分为:国家顶级域名、通用顶级域名、反向域名。
国家顶级域名中国:cn, 美国:us,英国uk…通用顶级域名com公司企业,edu教育机构,gov政府部门,int国际组织,mil军事部门 ,net网络,org非盈利组织…反向域名arpa,用于PTR查询(IP地址转换为域名) 二、域名服务器 域名是分层结构,域名服务器也是对应的层级结构。 有了域名结构,还需要有一个东西去解析域名,域名需要由遍及全世界的域名服务器去解析,域名服务器实际上就是装有域名系统的主机。
由高向低进行层次划分,可分为以下几大类:
分类作用根域名服务器最高层次的域名服务器,本地域名服务器解析不了的域名就会向其求助顶级域名服务器负责管理在该顶级域名服务器下注册的二级域名权限域名服务器负责一个区的域名解析工作本地域名服务器当一个主机发出DNS查询请求时,这个查询请求首先发给本地域名服务器 注:一个域名服务器所负责的范围,或者说有管理权限的范围,就称为区 我们需要注意的是: 1. 每个层的域名上都有自己的域名服务器,最顶层的是根域名服务器 2. 每一级域名服务器都知道下级域名服务器的IP地址 3. 为了容灾, 每一级至少设置两个或以上的域名服务器
npm install vue-i18n
在main.js中引入vue-i18n import VueI18n from 'vue-i18n' import LangEn from '../static/en' import LangZhCHS from '../static/zhCHS' Vue.use(VueI18n) const i18n = new VueI18n({ locale: 'en', // 语言标识 messages:{ 'en': LangEn, 'zhCHS': LangZhCHS, } }) 挂载到Vue的实例上 new Vue({ el: '#app', router, i18n, //<==== template: '<App/>', components: { App } }) en.js里为
module.exports={ message: { hello: 'hello', about: 'about', welcome: "Welcome" } }用发为 {{ $t("message.welcome") }}
在js中去掉双引号,,如果插件里用值的话应用this指向
属性中用法
:placeholder="$t('placeholder.enter')" 遇到的问题: 绑定在data中的值,在切换中英文时不会自动更新,正在寻找解决办法,如有高手知道,可以指点一二。
2018.03.22自答:
random = [(2, 2), (3, 4), (4, 1), (1, 3)] #按第二个元素升序排列 s = sorted(random,key=lambda x:x[1]) print(s) #按第一个元素降序排列 ss = sorted(random,key=lambda x:x[0]) print(ss) sort()函数用法
sorted(iterable[, cmp[, key[, reverse]]]) 参数说明 iterable -- 可迭代对象。cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。 返回值 返回重新排序的列表。
转一个lambda用法
我想问一下,modbus主站发送数据,主站是不是必须等到从站回了数据才可以发送下一帧数据,谢谢
不需要。modbus就是向特定地址写数据。你从站怎么写,和我主站怎么写没直接关系。当然如果你们写的是同一个地址的,那可能就有先后的,这取决于你的业务逻辑设计。
不需要。modbus就是向特定地址写数据。你从站怎么写,和我主站怎么写没直接关系。当然如果你们写的是同一个地址的,那可能就有先后的,这取决于你的业务逻辑设计。 485总线的需要吗?
485总线要等的吧,一次收发结束后再进行下一次收发,如果没收到的话等过了超时时间再开始下一次收发
首先到官网站点下载mysql源码或源文件:
https://dev.mysql.com/downloads/mysql/
因为8.0版本是当前最新版本,如果用源码编译安装的话不确定是不是很稳定,官方也不是很推荐编译安装,所以我这里直接选择了用rpm安装:
我的系统是centos7 64位,所以我选择了
Red Hat Enterprise Linux/Oracle Linux系列
我下载了捆绑完整包:
mysql-8.0.11-1.el7.x86_64.rpm-bundle.tar
查询系统是否已经安装过mysql
因为我之前安装过一遍,所以rpm 查询到已安装包列表:
[root@jordy jordy]# rpm -qa | grep mysql
mysql-community-client-8.0.11-1.el7.x86_64
mysql-community-libs-8.0.11-1.el7.x86_64
mysql-community-common-8.0.11-1.el7.x86_64
mysql-community-server-8.0.11-1.el7.x86_64
卸载:
按一定顺序(因包之间有相互依赖)卸载即可:
rpm -e mysql-community-server-8.0.11-1.el7.x86_6
rpm -e mysql-community-client-8.0.11-1.el7.x86_64
rpm -e mysql-community-libs-8.0.11-1.el7.x86_64
rpm -e mysql-community-common-8.0.11-1.el7.x86_64
查看是否卸载成功:
用rpm -qa 查看,已经卸载完毕:
root@jordy jordy]# rpm -qa | grep mysql
[root@jordy jordy]#
然后我们正式开始安装:
cd /usr/local/src/mysql/mysql-8.0/rpm
[root@jordy rpm]# ll
total 1179692
-rw-r--r-- 1 root root 603985920 Apr 9 01:20 mysql-8.
原链接:获取id
https://music.163.com/song?id=29984255&userid=267688655 mp3链接:
http://music.163.com/song/media/outer/url?id=xxx.mp3 转载于:https://www.cnblogs.com/maoriaty/p/9103802.html
当前系统需要集成 AnyChat 插件,本人于是研究了一下官方相关demo。运行 AnyChatSampleServer 示例代码报错
Exception in thread "main" java.lang.UnsatisfiedLinkError 错误解决记录
当前的 JDK 是 64位的,而调用的 xxx.dll 代码是32位的,换成JDK32位并重新编译代码后,异常解决。 Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\Workspaces\tempWorkspacee\java_anychat_server\AnyChatSampleServer\anychatserver4java.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1938) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at com.bairuitech.anychat.AnyChatServerSDK.<clinit>(AnyChatServerSDK.java:271) at com.bairuitech.server.SampleServer.main(SampleServer.java:29) 运行效果
05-29 09:14:43:912 Welcome use AnyChat! (V7.0 Build Time:May 15 2018 17:10:13)
05-29 09:14:43:948 Business server(Java) still running, press 'q' to exit.
第1步: hosts路径:C:\Windows\System32\drivers\etc 修改 hosts文件,在hosts中添加,最后一行添加: #Google主页
203.208.46.146 www.google.com
#这行是为了方便打开Android开发官网 现在好像不翻墙也可以打开
74.125.113.121 developer.android.com
#更新的内容从以下地址下载
203.208.46.146 dl.google.com
203.208.46.146 dl-ssl.google.com
74.125.237.1 dl-ssl.google.com
第2步:
打开Android SDK Manager-->Tools-->options
在“Others”里面将Force https://...sourcses... 前面额方块打上勾。
该界面的HTTP Proxy Server和HTTP Proxy Port中分别填写:mirrors.neusoft.edu.cn和80
然后重新打开Android SDK Manager,就可以更新了!
QQ交流群:162136059
面向对象主要有四大特性
· 抽象
o 忽略一个主题中与当前目标无关的东西,专注的注意与当前目标有关的方面.(就是把现实世界中的某一类东西,提取出来,用程序代码表示,抽象出来的一般叫做类或者接口).抽象并不打算了解全部问题,而是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一个数据抽象,而是过程抽象.
o 数据抽象 -->表示世界中一类事物的特征,就是对象的属性.比如鸟有翅膀,羽毛等(类的属性)
o 过程抽象 -->表示世界中一类事物的行为,就是对象的行为.比如鸟会飞,会叫(类的方法)
· 封装
o 封装就是把过程和数据包围起来,对数据的访问只能通过特定的界面.如私有变量,用set,get方法获取
· 继承
o 一种联结类的层次模型,并且允许和鼓励类的重用,提供一种明确表达共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),原始类称为新类的基类(父类).派生类可以从它的父类哪里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要.因此可以说,继承为了重用父类代码,同时为实现多态性作准备.
· 多态
o 多态是指允许不同类的对象对同一消息做出响应.多态性包括参数化多态性和包含多态性.多态性语言具有灵活/抽象/行为共享/代码共享的优势,很好的解决了应用程序函数同名问题.总的来说,方法的重写,重载与动态链接构成多态性.java引入多态的概念原因之一就是弥补类的单继承带来的功能不足.
o 动态链接 -->对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将调用子类中的这个方法,这就是动态链接.
注意继承与重载:子类与父类的关系,重载方法的调用问题
子类对象可以直接当成父类对象用,但是反过来就不行.比如:人是父类,学生是人的子类,所以学生对象一定具备人对象的属性,但是人对象就未必具有学生对象的特性.但是子类对象当做父类来用,将失去子类所有特性,只保留与父类同名的属性和方法,此时可以对父类方法进行重写.
一个类中如果定义了重载的方法,则系统在调用方法时,会根据参数的类型自动选择调用合适的方法
五大基本原则 · 单一职责原则SRP(Single Responsibility Principle)
o 是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。
· 开放封闭原则OCP(Open-Close Principle) o 一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,
o 那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。
· 替换原则(the Liskov Substitution Principle LSP) o 子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,
o 也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。
· 依赖原则(the Dependency Inversion Principle DIP)
o 具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,
o 这个时候,B不应当直接使用A中的具体类:而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到
o 了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。
· 接口分离原则(the Interface Segregation Principle ISP) o 模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来
easyui1.3.3
获得当前页的所有行数据: $('#id').datagrid('getRows');获得所有数据源 :$('#id').datagrid('originData ');当文字超过单元格长度可以自动换行nowrap:false清除数据:$('#id').datagrid('loadData',rows);(var rows= [];)easyui手动跳转至几页:$('#id').datagrid('getPager').pagination('select',pageNum(数字));重新给datagrid加载数据 不会自动跳转至第一页easyui隐藏列: hidden:trueeasyui datagrid加载成功函数: onLoadSuccess:function(data){ if(data.total==0){ } }没有数据的json格式: {total:0,rows:[]} datagrid增加一行 ('#id').datagrid('appendRow',json格式的字符串(包含{field字段名:值}));若json格式不对或数据名称不匹配 行会为空datagrid url 访问 返回json格式匹配field字段 可以通过 ('#id').datagrid('load',{VAL:val});({后台获取的数据字段名:数据} )datagrid更新 ('#id').datagrid('updateRow',index:索引数字,row:{更新的字段:数据}); 注:获取某行 通过直接赋值的方式改变它的值再调用reload不能更新数据
获得索引:index=('#id').datagrid('getRowIndex',row);
删除行('#id').datagrid('deleteRow',index);获得选中行的数据:$('#id').datagrid('getSelected')给一列添加按钮: formatter:btnFun btnFun(val,row,index){ //val表示单元格的值 //row当前行 //index当前行的索引 return '<button type="button"></button>' }
ThreadLocal简介 变量值的共享可以使用public static的形式,所有线程都使用同一个变量,如果想实现每一个线程都有自己的共享变量该如何实现呢?JDK中的ThreadLocal类正是为了解决这样的问题。
ThreadLocal类并不是用来解决多线程环境下的共享变量问题,而是用来提供线程内部的共享变量,在多线程环境下,可以保证各个线程之间的变量互相隔离、相互独立。在线程中,可以通过get()/set()方法来访问变量。ThreadLocal实例通常来说都是private static类型的,它们希望将状态与线程进行关联。这种变量在线程的生命周期内起作用,可以减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。
我们先通过一个例子来看一下ThreadLocal的基本用法:
public class ThreadLocalTest { static class MyThread extends Thread { private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>(); @Override public void run() { super.run(); for (int i = 0; i < 3; i++) { threadLocal.set(i); System.out.println(getName() + " threadLocal.get() = " + threadLocal.get()); } } } public static void main(String[] args) { MyThread myThreadA = new MyThread(); myThreadA.setName("ThreadA"); MyThread myThreadB = new MyThread(); myThreadB.setName("ThreadB"); myThreadA.
把毫秒值转变为对应的年月日时分秒格式的时间
import java.text.SimpleDateFormat; import java.util.Date; // 1416471971031 Date d = new Date(1416471971031L); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String s = sdf.format(d); System.out.println(s); // 将毫秒转化为时分秒 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); // 减去时区差 String hms = sdf.format(((end - start) - TimeZone.getDefault().getRawOffset())); System.out.println(hms);
背景 在JDK 1.2以前,Java中的引用定义很传统:如果reference类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。这种定义很纯粹,但是太过狭隘,一个对象在这种定义下,只有被引用或者没有被引用这两种状态,对于如何描述一些“食之无味,弃之可惜”的对象就显得无能为力。我们对于这样一类对象需要一种新的引用方式:当内存空间还足够时,则能保留在内存之中;如果内存空间在进行垃圾回收后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能都是符合这样的应用场景。
所以,JDK 1.2对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种,这4种的引用强度依次逐渐减弱。
强引用
强引用是指在程序代码中普遍存在的,类似Object obj = new Object()这类的引用,只要强引用还存在,垃圾回收器永远不会回收掉被引用的对象。
软引用
软引用用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。在JDK 1.2之后,提供了SoftReference类来实现软引用。
应用场景:软引用通常用来实现内存敏感的缓存。如果内存空间还有剩余,就可以暂时保留缓存,当内存不足时,就可以将缓存清除,这样就保证了使用缓存的同时,不会耗尽内存。
弱引用
弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾回收之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK 1.2之后,提供了WeakReference类来实现弱引用。
应用场景:弱应用同样可用于内存敏感的缓存。与软引用不同的是,在内存空间还足够时,软引用的对象不会被回收,但是,弱引用的对象有可能会被回收,其存活时间相比于弱引用更短一点。
虚引用
虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是在这个对象被垃圾回收器回收时收到一个系统通知。在JDK 1.2之后,提供了PhantomReference类来实现虚引用。
应用场景:可以用虚引用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。
软引用、弱引用和虚引用可以和一个引用队列(ReferenceQueue)联合使用,如果它们所引用的对象被垃圾回收,Java虚拟机就会把这个引用加入到与之关联的引用队列中。采用软引用、弱引用和虚引用可以预防Java虚拟机抛出OOM异常以及内存泄漏的问题。
软引用、弱引用和虚引用存在的必要性 在Java程序中,如果我们想回收一个对象,可以把对象引用置为null,这样,在下次垃圾回收之前,就可以回收该对象,如下所示:
Object object = new Object(); object = null; 但是手动置为null这种方式太繁琐,而且我们编写程序时也不能一直保证对引用的置空操作是正确的,这种方式完全违背了Java虚拟机自动回收垃圾的概念。同时,采用该种方式会存在以下问题:
对于需要系统缓存的Java程序,在程序运行期间,缓存内容就不能被垃圾回收器回收,如果我们已经不再需要某项缓存,那将其置为null,是不是就可以了呢?
答案是不行的,若缓存使用HashMap<Product, Integer>来实现,其中,key代表一种商品缓存信息,value为商品剩余数目,当商品售空时,我们将指向Product商品的引用(假设为productRef)productRef置为null,然而垃圾回收器并不会回收Product对象,因为在HashMap的Node结点中,仍然保留着一个对Product对象的引用,若是想要回收该对象,必须还得将该条目从HashMap中删除,否则会产生内存泄漏问题。这同样违背了Java虚拟机自动回收垃圾的概念。
对于上述的问题,我们都可以通过软引用和弱引用解决。对于使用单个引用的对象,示例代码如下所示:
public class ReferenceTest1 { // 循环检测引用队列是否有值 static class CheckReferenceQueueThread extends Thread { private ReferenceQueue<Object> referenceQueue; public CheckReferenceQueueThread(ReferenceQueue<Object> referenceQueue) { this.referenceQueue = referenceQueue; } @Override public void run() { super.
PHP学习路上的第一个完整的极小极小的项目,总算是看着了做项目的希望了,特意做个记录
登录界面:
html代码(login.html):
<form action="login.php" method="post"> <fieldset> <legend>用户登录</legend> <ul> <li> <label>用户名:</label> <input type="text" name="username"> </li> <li> <label>密 码:</label> <input type="password" name="password"> </li> <li> <label> </label> <input type="checkbox" name="remember" value="yes">7天内自动登录 </li> <li> <label> </label> <input type="submit" name="login" value="登录"> </li> </ul> </fieldset> </form> login.php:(登陆处理页)
<?php header('Content-type:text/html; charset=utf-8'); // 开启Session session_start(); // 处理用户登录信息 if (isset($_POST['login'])) { # 接收用户的登录信息 $username = trim($_POST['username']); $password = trim($_POST['password']); // 判断提交的登录信息 if (($username == '') || ($password == '')) { // 若为空,视为未填写,提示错误,并3秒后返回登录界面 header('refresh:3; url=login.
python中 any()和all() 方法 目录
python中 any()和all() 方法
all(iterable)
any(iterable)
day20201204 补 any() 相当于下面的用法 all() 相当于下面的用法
总结
参考链接
可以用来判断 值是否为空. any 只要iterable 中有一个为真, 则返回真. all 有一个 为假 ,返回假. all(iterable) all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否不为 0、''、False 或者 iterable 为空, 如果是返回 True,否则返回 False。 1. 来看一个例子
# 简单来说 如果每个元素都是有值的,返回True names = ('name', 'laoda', 'laoer',) names2 = ('name', 'laoda', 'laoer', False) names3 = ('name', 'laoda', 'laoer', []) print(all(names)) # True print(all(names2)) # False print(all(names3)) # False any(iterable) any() 函数用于判断给定的可迭代参数 iterable 是否全部为空对象,如果都为空、0、false,则返回 False, 如果不都为空、0、false,则返回 True.
具体的参数在HystrixCommandProperties类中
circuitBreaker.sleepWindowInMiliseconds //熔断器打开后多少秒内 熔断状态变成半熔断状态(对该微服务进行一次请求尝试,不成功则状态改成熔断,成功则关闭熔断器
circuitBreaker.RequestVolumeThreshold //断容器最小请求数,达到这个值过后才开始计算是否打开熔断器
circuitBreaker.ErrorThresholdPercentage // 错误百分比条件,达到熔断器最小请求数后错误率达到百分之多少后打开熔断器
对应的配置(yml/properties) 【详细自己去上面的配置类去查看】
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 3000 在这里做个笔记
下载ngrok的压缩包到本地 。官网地址:https://ngrok.com/ 用户登陆/注册,成功后出现如下图,按照步骤指导进行操作即可。
A) 第一步下载压缩文件;
B) 第二步解压,unzip ngrok.zip的路径地址(路径根据实际情况填写)
C) 第三部authtoken后面的就是你账号自动生成的token
D) 第四部help 验证是否配置成功
E) 第五部直接放入你要映射的本地的地址 ./ngrok http localhost:80(该端口号根据实际情况填写)执行完2 E)后如果出现下图即表示成功
测试映射是否成功 在浏览器中输入映射的地址 出现如下图即成功
如果外网进行访问的话,直接给出这个链接即可。如果是联调测试,直接在服务器管理上添加一个反向代理路径就可以啦 这样测试就方便多多啦!小番外:(楼主在安装的时候出现一个小插曲:映射后输入地址 页面显示 invalid host header)
按照网上的添加disableHostCheck各种不行 发现按照官方的 ./ngrok http 80这样一直会报这个错 无意中看到./ngrok http localhost:80写法 然后尝试了一下 顺利映射成功。
devServer: { disableHostCheck: true, }总结:楼主写这篇文章主要为了记录学习到的新技术,熟话说好记性不如烂笔头嘛。更多的还是为了和广大的技术友们分享喽!说不定有些朋友就用到啦。
要想获取整个摄像头画面在整个屏幕的画面只需要比平常的操作多一步即可,例如通常海思SDK通常提供的VENC例子里的流程是:VI->VPSS->VENC,而我们把他修改成VI->VPSS->虚拟VO->VENC,这样我们就可以获取所有摄像头在屏幕显示的画面。虚拟VO配置如下:
s32Ret = SAMPLE_COMM_VO_MemConfig(VO_VIRT, "ddr1"); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("BJ_Multimedia_VO_MemConfig failed with %d!\n", s32Ret); goto END_4HD_HOMO_0; } HI_S32 startVoVirtual(VIDEO_NORM_E gs_enNorm) { HI_S32 s32Ret; VO_DEV voDev = VO_VIRT; VO_PUB_ATTR_S stVoPubAttr; VO_VIDEO_LAYER_ATTR_S stLayerAttr; VO_CHN_ATTR_S stChnAttr; HI_U32 u32Width = 1920; HI_U32 u32Height = 1080; HI_S32 WIN_NUM = 4; int i; VO_CHN chn; stVoPubAttr.u32BgColor = 0x00000000; stVoPubAttr.enIntfType = VO_INTF_VGA | VO_INTF_HDMI; stVoPubAttr.enIntfSync =(VIDEO_ENCODING_MODE_PAL == gs_enNorm) ? VO_OUTPUT_1080P50 : VO_OUTPUT_1080P60; stVoPubAttr.bDoubleFrame = HI_FALSE; s32Ret = HI_MPI_VO_SetPubAttr(voDev, &stVoPubAttr); if (s32Ret !
虚拟机增加磁盘进行磁盘分区 查看磁盘情况
[root@localhost /]#df
查看设备
[root@localhost /]#ls /dev/sd*
增加磁盘
[root@localhost /]#ls /dev/sd*
找到对应增加的设备(假设增加的sdb)
[root@localhost /]#fdisk /dev/sdb
输入n,新建分区
p 设置主分区
1-4 选择分区号
选择 sector
选择容量
看到磁盘分区成功
[root@localhost /]#ls /dev/sd*
磁盘格式化(假设ext4格式 sdb1)
[root@localhost /]#mkfs.ext4 /dev/sdb1
创建目录
[root@localhost /]#mkdir /home/xxx/mountdir
挂载到目录(将相应设备分区挂载到目录)
[root@localhost /]#mount /dev/sdb1 /home/xxx/mountdir
查看是否挂载成功
[root@localhost /]#df
VMware虚拟机扩展分区容量 有时候一开始进行磁盘分区时给对应分区容量分配少了,需要进行分区扩容;
VMware设置里选择扩展磁盘容量
[root@localhost /]#ls /dev/sd*
sda sda1 sda2 sda3
假设进行/dev/sda3分区进行扩展
查看/dev/sda3是否进行挂载
[root@localgost /]# df
如果挂载了需要卸载磁盘分区
[root@localhost /]# umount /dev/sda3
[root@localhost /]# fdisk /dev/sda
在操作系统中,低优先级任务想要得到CPU的使用权,是建立在高优先级任务遇到阻塞语句的前提下,比如等待事件标志、等待消息、等待信号量、遇见延迟函数等
而在低优先级任务执行过程中,高优先级任务在干什么,或者说CPU在干什么
在抢占式操作系统中,高优先级任务是不会等待低优先级任务彻底执行完毕后,通过调度器切换任务而获得CPU使用权,而是高优先级任务的就绪条件一满足就会立刻夺过CPU的使用权,暂时中断正在执行的低优先级任务,但CPU在执行低优先级任务时,是如何实时知道高优先级任务就绪了呢,由结果倒推原因,那就是CPU不是一直特别专一的只执行低优先级任务,而是有一个大扫描,会实时检测高优先级任务的运行条件是否已满足,一旦满足就会发生抢占事件,否则继续执行低优先级任务
其实仔细研究过操作系统后便知,这是操作系统的任务切换机制,操作系统跟人一样必须有一个心跳,整个系统按照这个心跳有序正确的工作,这个心跳就是系统时钟,系统时钟一般是由定时器产生,每隔一定时间便产生一次中断,系统便在这个中断里做一些事情,这当中就包括调度器的任务切换,即一次中断到来后便检测高优先级任务的就绪条件是否满足,条件满足则切换任务,不满足则继续执行当前任务,这就在现象上表现出,操作系统能实时知道高优先级任务何时就绪了,以便切换到高优先级任务而执行
最近启动模拟器的时候报一下错误:
Emulator: Process finished with exit code 1 Emulator: [6216]:WARNING:android/android-emu/android/featurecontrol/FeatureControlImpl.cpp:160:Failed to load advanced feature default setting:E:\Android\Sdk\emulator\lib\advancedFeatures.ini 模拟器闪退了.
百度了一通发现根本找不到答案,网上没有类似遇到这种问题,后来自己根据提示,进入了目录发现自己的SDK 目录下 \emulator 缺少了很多文件.正常应该是这样:
而我的目录下是这样的:
少了一大堆东西,,把这些少了的东西都补上,启动模拟器就不会报错了. 扩展: 为什么会少这么多东西呢?平时启动都很正常的模拟器,为啥突然变成这样, 原因是360安全卫士,有时候清理垃圾的时候,把这些文件当成垃圾或者病毒给误删除了!所以开发尽量不要安装360,免得后面报一些很偏的错误,找都不好找!
1. 简介 在Java的漫长发展过程当中,其项目的配置方式也发生了很多次变化。 第一阶段:都是通过xml来配置bean。缺点:随着项目不断扩大,需要将xml分别放到不同的配置文件中。
第二阶段:因为JDK1.5支持了注解配置,于是配置文件的方式也发生了变化。对与基本配置用xml,而对于业务开发则使用注解来配置。
第三阶段:使用Java配置。配置Java类进行注解来配置属性。
2. 配置注解 Spring的Java配置方式是通过@Configuration和@Bean这两个注解来实现的。 其中@Configuration作用于类上,相当于一个xml配置文件。 而@Bean作用于方法上,相当于一个<bean>标签。
3. 用注解代替配置文件 在springboot中会使用@PropertySource来指定读取的配置文件,并且通过@Value注解获取值。 <1>如何配置多个配置文件? 配置多个配置文件的示例如下:
//在类上配置注解如下 @PropertySource(value="classpath:jdbc.properties","test.properties") <2>如果配置文件不存在,如何解决? 可以通过配置忽略文件不存在的情况,防止程序抛出ClassNotFoundException。
//在类上配置注解如下 @PropertySource(value={"classpath:jdbc.properties"}, ignoreResourceNotFound=true) 4. 数据库配置 之前的配置方式如下:
<!-- 定义数据源 --> <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> <!-- 数据库驱动 --> <property name="driverClass" value="${jdbc.driverClassName}" /> <!-- 相应驱动的jdbcUrl --> <property name="jdbcUrl" value="${jdbc.url}" /> <!-- 数据库的用户名 --> <property name="username" value="${jdbc.username}" /> <!-- 数据库的密码 --> <property name="password" value="${jdbc.password}" /> <!-- 检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240--> <!--如果要取消则设置为0 --> <property name="idleConnectionTestPeriod" value="60" /> <!
C语言中,本身没有bool(布尔型变量)。但是我们可以用其他方式来模拟。
一、如果简单的使用char、int、long变量来表示0/1,则太浪费空间了。
二、这里介绍一种巧妙的方式实现bool,高空间利用率。
#define true 1 #define false 0 //--------------------------------------------联合体(共用体) 定义 typedef union { //使用位域 struct { unsigned b0 : 1; unsigned b1 : 1; unsigned b2 : 1; unsigned b3 : 1; unsigned b4 : 1; unsigned b5 : 1; unsigned b6 : 1; unsigned b7 : 1; }bit_type; unsigned char byte; }FLAG; FLAG FLAG0; //结构变量声明 //--------------------------------------------结构类型变量位域宏定义 #define flag_0 FLAG0.bit_type.b0 #define flag_1 FLAG0.bit_type.b1 #define flag_2 FLAG0.bit_type.b2 #define flag_3 FLAG0.
本文参考自:https://blog.csdn.net/jklinux/article/details/72367829
安装包可以从这里下载https://download.csdn.net/download/yinsui1839/10433905
没有积分的同学可以在评论区发邮箱给我
先安装yasm:
解压yasm-1.3.0.tar.gz
cd yasm-1.3.0/ ./configure make && make install 安装x264
解压last_x264.tar.bz2
cd x264-snapshot-20180305-2245/ ./configure make && make install安装libfdk-aac: 解压fdk-aac-0.1.6.tar.gz
cd fdk-aac-0.1.6/ ./configure make && make install安装cmake yum install cmake* cmake --version 如果大于3.5则不需安装cmake-3.5 安装ffmpeg
解压ffmpeg-3.4.2.tar.gz
cd ffmpeg-3.4.2/ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ ./configure --disable-debug --enable-libx264 --enable-gpl --enable-shared --enable-libfdk-aac --enable-nonfree 查看输出信息 Enabled encoders:是否有 libfdk_aac libx264 有 make && make install cp /usr/local/lib/libx* /lib64/ cp /usr/local/lib/libfdk* /lib64/ cp /usr/local/lib/libav* /lib64/ cp /usr/local/lib/libsw* /lib64/ cp /usr/local/lib/libpostproc* /lib64/
直接的方法:
打开【运行】->输入【C:\Windows\SysWOW64\mmc.exe /32 C:\Windows\SysWOW64\SQLServerManager10.msc】即可。
安装时请在路由器里设置dns参数如下:
dns服务器 主 114.114.114.114 dns服务器 备 8.8.8.8 设置方法
tp-link 旧 网络参数-wan口设置-高级设置-勾选手动设置dns服务器
tplink 新 如上图
腾达路由 新 高级设置-左侧dns设置
腾达路由 旧 如上图
水星
以下我们来看看别人说的PHP的发展前景:
钟胜辉:三门语言其中,无疑php是最流行的。而Python和Ruby在近期几年也有着不错的发展趋势。
我个人觉得,Ruby的流行很多其它地源于Ruby on Rails,这个框架的流行程度甚至超过了Ruby语言本身。也引发了其它语言平台上对框架的研究。
而Python在近来的被关注度和发展速度要超过Ruby,被一些喜欢创新的项目採用,这可能要很多其它地归功于google。
这三种语言都是相当优秀的脚本语言,为什么PHP能大行其道,杀入排行榜的三甲呢?从表面上来看,这是就业环境使然。越来越多的新公司或者新项目使用PHP,这使得PHP相关社区越来越活跃,而这又反过来影响到非常多项目或公司的选择,形成一个良性的循环。就我眼下了解到的情况,PHP是国内大部分web项目的首选。并且有非常多公司从其他语言(如ASP,JAVA)转到了PHP。合适的就是最好的。PHP的高速。开发成本低,周期短,后期维护费用低,开源产品丰富(这点能够影响到非常多项目的决策),这些都是另外两种语言无法比拟的。另外。在非常多大项目中。Python很多其他地是做为一种“粘合剂语言”出现。似乎正在走向与PHP不同的发展方向,让我们拭目以待。 51CTO记者:PHP开发框架的盛行是由RoR的火爆所引起的。而PHP框架的发展也从模仿Rails到逐渐有了自己的风格。只是仍然有非常多入行较早的PHP开发人员至今仍觉得PHP这样的快捷的语言不须要框架,甚至觉得仅仅要有优秀的架构,框架根本不是必需。您觉得PHP框架对PHP而言是必要的么?您对于PHP开发工具的现状惬意么?
钟胜辉:这是一个见仁见智的问题,我个人觉得。一个优秀的框架能在非常大程度上提高工作效率。尤其是对大中型项目。当然假设对项目有足够的把控能力。框架也并不是是必须的,毕竟PHP的框架跟ROR的情况有所不同。多而混乱,而学习一个框架是须要时间的。像你的问题中提到的,非常多老的PHP程序猿对框架不屑一顾。觉得自己对项目有足够的把控能力,不须要框架这么累赘的东西。然而从长远来看,一个优秀的框架能够延长一个项目的寿命,减少维护和二次开发的成本。我们眼下正在开发中的CMSTOP。是一个产品型项目,在这种项目中,没有一个优秀的框架是非常难想象的。在研究对照了眼下主流的PHP框架之后,我们发现没有哪个框架能全然适合一个CMS的项目,于是我们决定自己开发一个框架。
眼下这个框架极大地提高了我们的工作效率。并且。我们会在适当的时候将这个框架开源。 51CTO记者:PHP的面向对象设计的并非非常好。非常多在Java一类语言里面可以非常好应用的面向对象写法在PHP里面实现起来却非常繁琐。您觉得面向对象对于PHP这种Web开发语言来说重要么?PHP的面向对象是否还可以改进呢?
钟胜辉:PHP的面向对象属于历史遗留问题,并且,说其不好,慢慢也会成为历史问题。
从PHP5相对PHP4的进步,我们有理由去期待PHP6给我们带来很多其它的惊喜。不论对什么样的语言,面向对象很多其它的是一种思考问题的方法,没有必要为了面向对象而去面向对象。
PHP最初的面向对象。能够简单地看作是函数的升级,以前被非常多其它语言的开发人员取笑。但PHP5的面向对象已经足以满足大部分WEB项目了。
一门语言要想生存下去,就得去适应技术发展的潮流,并不断做出调整,在这方面,PHP的团队充满了活力。 51CTO记者:PHP站点的安全是个非经常见的问题。有关PHP站点漏洞的消息是非常多的。
您觉得这当中的原因和PHP语言本身的特点有关么(相对于如PHP站点数量、PHP代码编写习惯等其它因素)?PHP的安全有改善的空间么?
钟胜辉:站点的安全是一个比較系统的问题。它跟server安全以及代码的质量是直接相关的,我们并不能说PHP这门语言不安全。
眼下PHP有非常多优秀的开源产品。比如discuz,phpcms等,即使在开源的情况下。这些产品也保证了足够的安全性。
PHP的门槛非常低,一两周的时间就能够入门,而这些“高速入门”的程序猿,往往easy忽略代码安全问题。安全问题的改善。取决于越来越多的PHP程序猿对这个问题的重视程度。
51CTO记者:如今在不少大型项目中。PHP全然充当了脚本的功能,而逻辑性比較强的业务处理则由还有一门功能丰富的语言(比如Java)来实现。您觉得这样在复杂度、开发快捷度、开发周期以及成本等方面有着如何的影响?
钟胜辉:这样的情况确实存在,但我觉得之所以出现这样的情况,并非由于PHP“做不了”。而是非常多项目负责人对PHP的偏见以及对JAVA等语言的迷信造成了这样的现状。当然,我们不是否能认,有非常多问题确实是PHP做不了的,做为一种解释型的脚本语言,PHP本身就不适合做大型的数据运算。它也不可能成为一门“万能语言”。在大型项目中。多种语言配合工作是一件非常正常的事情。比如说。PHP负责收集数据,提供界面,C负责处理分析数据。Python来做粘剂。各种语言各司其职,协同合作,仅仅是分工的不同而没有高低贵之分,就像假设用C来做数据展示一样会非常痛苦。
我不觉得PHP往复杂计算方面发展是一件好事。并且我相信PHP的开发团队也会把握好这个度。
没有哪种语言能够做到“万能”。java有这样的野心,但我们能够看到java如今的境遇似乎并不如PHP那么红火。假设PHP也追求“万能”,那将是一场灾难。
在windows环境下安装完node,其目录结构下会有一个node.exe文件,运行该工具就相当于在cmd中执行node命令,即进入node开发模式。
但不能在这里执行npm命令,因为npm作为一个独立的模块,其实是另外一个工具。如果此时执行npm install安装命令,node就会抛出 npm should be run outside of the node repl, in your normal shell. 异常。这其实意味着不能在node开发模式中运行npm等命令,而在cmd中可直接运行,比如使用npm全局安装express:
C:\Users\Administrator>npm install -g express
安装完成了npm后,你就可以安装其他想要的nodejs模块了,比如安装express命令行输入:
npm install express -g 其中-g是指全局安装的意思,你可以不要,这样会安装在当前文件夹下,当前工程下而已。全局安装完成后,会在nodejs安装目录下的模块文件夹中有npm
可以使用npm命令安装express了, npm install express
可参考菜鸟教程链接:
http://www.runoob.com/nodejs/nodejs-npm.html
土地调查法规条例综合知识 1.根据我国《宪法》第九条,国家自然资源,由国家所有,即全民所有;由法律规定属于集体所有的森林和山岭、草原荒地、滩涂除外。
《土地管理法》第八条规定,城市市区的土地由国家所有,农村和城市郊区的土地由集体所有,法律规定的属于国家所有的土地除外。宅基地、自留地、自留山属于集体所有。
《物权法》
第四十六条:矿藏、水流、海域属于国家所有。
第四十八条:森林、山岭、草原、荒地、滩涂等自然资源,属于国家所有,但法律规定属于集体所有的除外。
土地管理法与物权法有冲突法院会按哪个法律判?
这主要看是什么样的冲突,如果是一般的物权冲突按照法律效力来说应按《物权法》判,因为《物权法》是新法,新法的效力优于旧法;但如果是特殊规定,则适用特别法优于一般法的原则处理,《物权法》是一般法,土地管理法是特别法,所以应按土地管理法判才对。
县级人民政府土地行政主管部门会同同级有关部门进行土地调查,有关部门包括那些?
个人博客请访问 http://www.x0100.top 1、只注册 如果有两个镜像环境,两个注册中心,有一个服务只在其中一个注册中心有部署,另一个注册中心还没来得及部署,而两个注册中心的其它应用都需要依赖此服务。这个时候,可以让服务提供者方只注册服务到另一注册中心,而不从另一注册中心订阅服务。
禁用订阅配置
<dubbo:registryid="hzRegistry" address="10.20.153.10:9090" /> <dubbo:registryid="qdRegistry" address="10.20.141.150:9090"subscribe="false" />
或者
<dubbo:registryid="hzRegistry" address="10.20.153.10:9090" /> <dubbo:registryid="qdRegistry" address="10.20.141.150:9090?subscribe=false"/>
2、静态服务 有时候希望人工管理服务提供者的上线和下线,此时需将注册中心标识为非动态管理模式。
<dubbo:registryaddress="10.20.141.150:9090" dynamic="false" />
或者
<dubbo:registryaddress="10.20.141.150:9090?dynamic=false" />
服务提供者初次注册时为禁用状态,需人工启用。断线时,将不会被自动删除,需人工禁用。
如果是一个第三方独立提供者,比如 memcached,可以直接向注册中心写入提供者地址信息,消费者正常使用(通常由脚本监控中心页面等调用):
RegistryFactory registryFactory =ExtensionLoader.getExtensionLoader(RegistryFactory.c lass).getAdaptiveExtension(); Registry registry=registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); registry.register(URL.valueOf("memcached://10.20.153.11/com.foo.BarService?category=pr oviders&dynamic=false&application=foo"));
3、多协议 Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议。
3.1、不同服务不同协议
不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议。
<?xml version="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http: //code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:applicationname="world" /> <dubbo:registryid="registry" address="10.20.141.150:9090"username="admin" passwo rd="hello1234" /> <!-- 多协议配置--> <dubbo:protocolname="dubbo" port="20880" /> <dubbo:protocolname="rmi" port="1099" /> <!-- 使用dubbo协议暴露服务--> <dubbo:serviceinterface="com.alibaba.hello.api.HelloService"version="1.0.0" ref= "
1.spring依赖 <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </dependency> 个人测试过会有找不到org.springframework.mail.javamail.JavaMailSenderImpl的问题
2.springboot依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
sys.path(环境变量) 介绍 1. path[0]2. 标准库3. 第三方库 修改path 方法一:函数添加方法二:添加.pth文件方法三:修改环境变量 sys.path与init.py更多阅读参考 sys.path(环境变量) 介绍 指定模块的搜索路径的字符串列表。
sys模块包含了与python解释器和它的环境有关的函数, 里面有个 sys.path属性。它是一个list.默然情况下python导入文件或者模块的话,他会先在sys.path里找模块的路径。如果没有的话,程序就会报错。 1. path[0] 此列表的第一项,path[0],在程序启动时初始化,是包含用来调用Python解释器的脚本的目录。如果脚本目录不可用(例如,如果解释器被交互式地调用,或者脚本是从标准输入读取的),path[0]是空字符串,它引导Python首先在当前目录中搜索模块。 比如在C:User\chenxi3\Destop\Simplify中有一个testSysPath. py
import sys print("\n".join(sys.path)) 输出是:
C:\Users\chenxi3\Desktop\Simplify C:\Python27\DLLs C:\Python27\lib C:\Python27\lib\plat-win C:\Python27\lib\lib-tk C:\Python27 C:\Python27\lib\site-packages path[0]是C:\Users\chenxi3\Desktop\Simplify,调用python解释器的脚本所在的目录。 如果在命令行中
>>> import sys >>> print("\n".join(sys.path) path[0]为空,因为没有脚本文件,也就找不到脚本文件所在目录。 2. 标准库 lib目录下(home目录\pythonXX\lib)
3. 第三方库 在lib目录下的site-package目录下(home目录\pythonXX\lib\site-packages)
修改path 一个程序可以根据它自己的目的自由地修改path列表。 场景:在实际开发中,默认包含了当前目录为搜索路径,所以,当前目录下的模块和子模块均可以正常访问。
但是若一个模块需要import平级的不同目录的模块,或者上级目录里面的模块,就可以通过修改path来实现。
修改path常用两种方法: 方法一:函数添加 这是即时生效的方法,就是在模块里面修改sys.path值,这种方法修改的sys.path作用域只是当前进程,进程结束后就失效了。 个人比较推荐这种方法,比较干净, 避免一些冲突问题。
比如现在的代码目录结构:
/src/configs/config.py /src/common/Database.py
假如Database.py期望导入config. py,则可以增加上级目录到sys.path列表里面:
parent_path = os.path.dirname(sys.path[0]) if parent_path not in sys.path: sys.path.append(parent_path) import configs.
开篇
人工智能、大数据快速发展的今天,对于 TB 甚至 PB 级大数据的快速检索已然成为刚需。Elasticsearch 作为开源领域的后起之秀,从2010年至今得到飞跃式的发展。 Elasticsearch 以其开源、分布式、RESTFul API 三大优势,已经成为当下风口中“会飞的猪”。
阿里云2018年2月5日已开价50-200W年薪招聘技术人员参与 Elasticsearch、Lucene 内核优化、改进。如果说,你错过了 Hadoop,错过了 Spark 的红利,难道 Elasticsearch 的机会你还要错过吗?
在学习 Elasticsearch 的过程中,你是不是多多少少有以下困惑:
面对 Elasticsearch1.X,2.X,5.X,6.X 的不同版本,你无从下手?
面对 ElasticStack(Elasticsearch、Logstash、Kibana、Beat),你不知道从何学起?
面对各种技术文档(官方的及非官方的),你是否感到非常困惑?
面对 Elasticsearch 出现的各种异常、Bug,好不容易找到一个技术群或提问,又没人解答?
市面上的书籍分两种:老外的原理透彻,但版本过时;国内的版本稍新、但不透彻,你是不是很迷茫……
本文
不谈搜索引擎的原理;
不谈倒排索引的原理;
不谈乐观锁、悲观锁的机制;
……
只谈
从产品开发、项目实战的角度,如何让一个 Java 程序员甚至 C/C++ 的程序员快速上手。
海量的版本中,告诉你明确的选择。
ELKStack 技术体系,你的学习优先级。
ELK 技术体系架构。
ELK 技术栈的应用场景。
有了传统关系型数据库(MySQL、Oracle)、非关系型数据库(Mongo),如何快速的导入 Elasticsearch,实现全文检索。
Elasticsearch 实战中遇到问题,如何高效解决。
Elasticsearch 集群部署。
Elasticsearch 集群调优清单。
Elasticsearch 高效进阶方法论。
……
横扫你学习 Elasticsearch 的诸多疑惑,让你少走半年弯路!
ELK Stack 认知
考虑到有初学的朋友,先对 ELK Stack 的认知咱们达成共识。
【日期】2018-05-03 【问题】在ie中 × 被转化为 x ,而在谷歌中不会 【原因】 × 是转义字符,谷歌应该比较智能不报错 【发现过程】open新页面ie和谷歌地址栏显示不一样 【修复】不能把 & 改写为 & ,这样ie不报错了谷歌却会报错,要把 times 参数名改成没有转义歧义的参数名称 【是否我导致】是 【解决Bug的时间】1小时 【教训】url拼接参数是参数名定义不要过简单,可能与转义字符冲突
TCP(Transmission Control Protocol)传输控制协议
TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:
位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)Sequence number(顺序号码) Acknowledge number(确认号码)
第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;
第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包;
第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。
FTP协议及时基于此协议。
很多人都看代码都喜欢标准化的格式化的,那么hbuilder能不能格式化代码呢?当然能。
下面,我来操作一波。
1、打开工具—>选项
2、选择HBuilder—>整理代码格式设置
3、新建一个配置,名字自己取
系统给我们的是默认配置。我们需要更改配置,则可以往下走。
4、点击右上角的修改,即可进入编辑页面
配置名称随便取,然后缩进策略选择space only,大小随便设置。然后确定。
全选要格式化的代码,假如快捷键ctrl+shift+f失效,则可以选择右键整理代码格式即可。
首先介绍一下TCP:(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。相比而言UDP,就是开放式、无连接、不可靠的传输层通信协议。 下面,我一次进行客户端和服务器端的QT实现。我的开发环境是:QT Creator 5.7。 先看下效果图: 一:客户端编程
QT提供了QTcpSocket类,可以直接实例化一个客户端,可在help中索引如下:
The QTcpSocket class provides a TCP socket. More... Header #include <QTcpSocket> qmake QT += network Inherits: QAbstractSocket Inherited By: QSslSocket 从这里,我们可以看到,必须要在.pro文件中添加QT += network才可以进行网络编程,否则是访问不到<QTcpSocket>头文件的。 客户端读写相对简单,我们看一下代码头文件: #ifndef MYTCPCLIENT_H #define MYTCPCLIENT_H #include <QMainWindow> #include <QTcpSocket> #include <QHostAddress> #include <QMessageBox> namespace Ui { class MyTcpClient; } class MyTcpClient : public QMainWindow { Q_OBJECT public: explicit MyTcpClient(QWidget *parent = 0); ~MyTcpClient(); private: Ui::MyTcpClient *ui; QTcpSocket *tcpClient; private slots: //客户端槽函数 void ReadData(); void ReadError(QAbstractSocket::SocketError); void on_btnConnect_clicked(); void on_btnSend_clicked(); void on_pushButton_clicked(); }; #endif // MYTCPCLIENT_H 我们在窗口类中,定义了一个私有成员QTcpSoket *tcpClient。 1) 初始化QTcpSocket 在构造函数中,我们需要先对其进行实例化,并连接信号与槽函数:
agent.SetDestination(transform.position);
Stop函数,ResetPath函数。都不能使得 NavMeshAgent停止移动。
那就设置当前 角色的 position位置坐标,就可以立即停止移动
要传输的数据是m位,冗余位r应该是多少,才能纠正1位错来呢?
设一个系统中,编码后的码字位数是n,则n=m+r。因为要传输的数据位是m位,该系统需要传输的正确的码字个数应该是2^m,全部码字的个数是2^n,而n位码字每一位都可能发生跳变,且跳变之后不能变成另一个正确的码字,所以每个码字至少需要n+1个码字来表示它(别忘了还有它本身)
由上可以得到公式
海明纠错码
每一个码字从左到右编号,最左边为第1位第1,2,4,8,16……为校验位,其它为数据位校验规则可以为偶校验/奇校验对于编号为4的校验位,设p表示其它位的编号,它所检测的是所有满足p&4不为0的位置 例子(其中的特殊符号为异或):
那么海明码如何纠错呢?
假如接收方收到一个码字:"100110001100",请问这个码字对还是错?如果错,正确的码字应该是什么
可以得出m = 8,r = 4计算P1 = 0,P2 = 1,P3 = 1,P4 = 0其中P1位和P2位不对应,所以发生错误的是第 1+2=3 位正确的应该是码字和原始码字(数据位)分别是:"101110001100"和"11001100" 一个机智的方法应对突发错误:
假设突发错误导致连续的k为全出错,那么只需要将数据排成一个长度为k的矩阵,然后每1列作为一个码字,这样一共有k个码字,并且每个码字最多只会有一个错误
git pull 的时候出现如下错误
error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errfno 10054 fatal: The remote end hung up unexpectedly fatal: early EOF fatal: unpack-objects failed 进行如下设置后再次执行pull命令即可
git config http.postBuffer 524288000 这里命令设置了通信缓存大小,之前发生错误是同步数据过大导致。
这里config的参数可以在文件目录中的config文件中看到
[core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true symlinks = false ignorecase = true [remote "origin"] url = https://github.com/....... fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master [gui] wmstate = normal geometry = 841x483+111+65 321 218 [http] postBuffer = 524288000
创建对象后,Python解释器默认调用__init__()方法。当删除一个对象时,Python解释器也会默认调用一个方法,这个方法为__del__()方法。在Python中,对于开发者来说很少会直接销毁对象(如果需要,应该使用del关键字销毁)。Python的内存管理机制能够很好的胜任这份工作。也就是说,不管是手动调用del还是由Python自动回收都会触发__del__方法执行。 1. 创建多个对象的时候触发__del__方法 Python解释器释放实例对象的时候,调用该对象的__del__方法
各个对象被被Python解释器释放对象的时候调用__del__方法
class Person(object): def __init__(self,name): self.name = name def __del__(self): print("实例对象:%s"%self.name,id(self)) print("python解释器开始回收%s对象了" % self.name) print("类对象",id(Person)) zhangsan = Person("张三") print("实例对象张三:",id(zhangsan)) print("------------") lisi = Person("李四") print("实例对象李四:",id(lisi)) 执行效果
2. 使用del删除引用时的调用情况 当使用del 把内存的所有应用删除,立刻调用__del__方法
执行效果
创建对象后,Python解释器默认调用__init__()方法;
当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法
3. 创建多个实例对象并且删除 import time class Animal(object): # 初始化方法 # 创建完对象后会自动被调用 def __init__(self, name): print('__init__方法被调用') self.__name = name # 析构方法 # 当对象被删除时,会自动被调用 def __del__(self): print("__del__方法被调用") print("%s对象马上被干掉了..."%self.__name) # 创建对象 dog = Animal("哈皮狗") # 删除对象 del dog cat = Animal("
一、说明
smalot 版的datetimepicker控件是对原有的bootstrap-datetimepicker 项目 改进增强。
原项目对于选择年份、选择月份没做处理。
Git源代码地址:https://github.com/smalot/bootstrap-datetimepicker
CSDN地址:http://www.bootcdn.cn/smalot-bootstrap-datetimepicker/
官网:https://www.malot.fr/bootstrap-datetimepicker/
中文网:http://www.bootcss.com/p/bootstrap-datetimepicker/index.htm
引用如下:
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/smalot-bootstrap-datetimepicker/2.4.4/css/bootstrap-datetimepicker.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/smalot-bootstrap-datetimepicker/2.4.4/js/bootstrap-datetimepicker.min.js"></script> <script src="https://cdn.bootcss.com/smalot-bootstrap-datetimepicker/2.3.1/js/locales/bootstrap-datetimepicker.zh-CN.js"></script> 二、使用示例:
1.选择到时间
<div class="row"> <div class="col-sm-6"> <div class="form-group"> <label for="">选择日期 到时间:</label> <div class="input-group date"> <input type="text" id='date1' class="form-control"> <span class="input-group-addon"> <i class="glyphicon glyphicon-calendar"></i> </span> </div> </div> </div> </div> $(function () { //选择到分钟 $('#date1').datetimepicker({ format: 'yyyy-mm-dd hh:ii', //格式设置 language: 'zh-CN', //日期 }).on('changeDate', function (ev) { console.
今天开发需要微信分享网页链接自定义图片和文字描述,于是网上各种查找资料和各种看手册,遇到了好多坑,不过啃了半天以后终于把问题解决了,以防以后忘记,今天记录一下; 首先,由于微信已经发布了想要分享链接必须调用认证了的公众号的JSSDK接口,所以,像以前的在html页面中的head中放入图片,我试过已经不管用了,当然不是绝对的,但是我这个方法试了多好次,不能用,所以没有办法只好调接口来做这个功能了; 废话不多说, 首先第准备工作: 需要有一个认证了的公众号; 然后开始了我们的代码操作: 一: 在html中引入js文件 <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> 二: 在控制器中加入以下代码并且引入jssdk.php文件,我放在extend文件夹下面,这个不是强制要求,大家随意,只要文件引入正确即可;(jssdk压缩包在官网就可以找得到,下载下来引入即可) //获取apptoken include EXTEND_PATH . "\jssdk\jssdk.php"; $jssdk = new \JSSDK('你的appid','你的APPSecret');//这里填写自己的appid 和secret $signPackage = $jssdk->GetSignPackage(); 三: 回到html中,将发送来的数据放在head中;这个好处就是,数据不需要写死,以防以后出现问题; <script> wx.config({ debug: false, appId: '{$signPackage["appId"]}', timestamp: '{$signPackage["timestamp"]}', nonceStr: '{$signPackage["nonceStr"]}', signature: '{$signPackage["signature"]}', jsApiList: [ //我只调用了两个分享接口,分别是朋友圈和个人,大家有其它需要可以去文档中查找接口 'onMenuShareTimeline', 'onMenuShareAppMessage' ] }); wx.ready(function () { var shareData = { title: '标题', // 标题 desc: '描述', // 描述 link: '链接', // 分享的URL,必须和当前打开的网页的URL是一样的 imgUrl: '缩略图完整路径' // 缩略图地址 }; wx.
之前遇到这个问题,找了很多方法试了都不行,偶然间发现了这个,解决了问题,很感谢呢
1.下载附件ensp_patch_500.rar,并解压; 链接:https://pan.baidu.com/s/1c0MFSU 密码:r6bb 2.拷贝解压后的data和ensp_patch_500.exe文件至ensp安装目录\eNSP\vboxserver文件夹中
原文链接:https://blog.csdn.net/sdut_ICS_Hacker/article/details/78681194
1.使用windbg打开dump文件,同时设置symbols。
如果之前下载过windows的symbols就直接设置symbols path: (windows和程序的pdb)
例如:C:\Symbols;E:\work\技术分享\dump分析\1115服务器无响应dump\gsss\gssssvr
如果之前没有下载过windows的symbos则设置
C:\Symbols; SRV*e:\mylocalsymbols*http://msdl.microsoft.com/download/symbols;E:\work\技术分享\dump分析\1115服务器无响应dump\gsss\gssssvr
2.输入指令 ~*kv 输出所有的线程
3.找到异常的线程,例如下面的死锁(发现大部分函数都在等待临界区,死锁可能行非常大):
4.使用命令查看临界区信息: RtlEnterCriticalSection的第三个地址是045ab944(临界区地址), !cs Address 指定要显示的临界区地址。 : !cs 045ab944
5.切换到0x00004d0线程: ~~[0x00004d0] 执行 ~56s 切换到56号线程
6.输入kv,查看线程堆栈
7.标识对函数调用的线程 Kernel32! UnhandledExceptionFilter 。 它类似于以下
8.在第一个参数的指定位置显示内存内容 Kernel32! UnhandledExceptionFilter 通过 添加 第一个参数 。 此指向 EXCEPTION_POINTERS 结构
9.第一个 DWORD 代表异常记录。 若要获取有关异常的类型信息,请请在命令提示符处运行以下:.exr first DWORD from step 6
10.第二个 DWORD 是上下文记录。 若要获取上下文的信息,请在命令提示符处运行以下:.cxr second DWORD from step 6
11.运行 kv 命令获得实际的异常的调用堆栈
可以看到是json出现了问题,抛出了异常,但锁没有释放。
其他:
1.查看函数入参变量值
想要看到崩溃堆栈需要切换到上下文当中,用:.ecxr命令,然后在kp一下(kp表示打印堆栈并附带参数信息):
0:002> .ecxr eax=00000000 ebx=00000000 ecx=61476f67 edx=ffffffff esi=61476f67 edi=7ffffffe eip=7438d951 esp=001cc89c ebp=001ccd30 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 msvcr120!
此密码是连接终端控制台的密码。 1.随便输入一个密码,点击确定, 2.密码错误后网页右侧顶端出现1个修改远程连接密码的按钮,点击进去修改密码就OK了 QQ交流群:162136059
1.检查手机和pc是否在同一个网段(必须在同一个网段)
2.windows 一定要关闭防火墙!!!
3.检查端口手机和PC的端口是否一致(必须一致)
本文Demo传送门 RunloopDemo
前言 OSX / iOS 系统中,提供了两个这样的对象:NSRunLoop 和 CFRunLoopRef。
CFRunLoopRef 是在 CoreFoundation 框架内的,它提供了纯 C 函数的 API,所有这些 API 都是线程安全的。
NSRunLoop 是基于 CFRunLoopRef 的封装,提供了面向对象的 API,但是这些 API 不是线程安全的。
1. 如何查看RunLoop源代码 1.1 NSRunLoop源代码 NSRunLoop是Foundation框架里面的一个类,它的头文件可以在工程里面这样查看:
至于它的实现文件,暂时没有找到公开的资料。
1.2 CFRunLoopRef源代码 CFRunLoopRef 的代码是开源的,你可以在这里 opensource.apple.com/tarballs/CF… 下载到整个 CoreFoundation 的源码。为了方便跟踪和查看,你可以新建一个 Xcode 工程,把这堆源码拖进去看。
更多苹果源代码下载 苹果公开的源代码在这里可以下载,opensource.apple.com/tarballs/
例如,其中,有两个比较常见需要学习源码的下载地址:
runtime的源代码在opensource.apple.com/tarballs/ob…runloop(其实是整个 CoreFoundation)的源代码在opensource.apple.com/tarballs/CF… 当然,如果你想在github上在线查看源代码,可以点这里:runtime,runloop
2. 简析RunLoop源代码 2.1 Foundation相关Runloop的源码 NSRunLoop @interface NSRunLoop : NSObject { @private id _rl; id _dperf; id _perft; id _info; id _ports; void *_reserved[6]; } @property (class, readonly, strong) NSRunLoop *currentRunLoop; @property (class, readonly, strong) NSRunLoop *mainRunLoop API_AVAILABLE(macos(10.
总结的部分python数据类型,希望对你有所帮助
举个例子:
地址0000A000H 到 0000BFFFH 共有多少个存储单元:
16进制中转成10进制: A-10 B-11 C-12 D-13 E-14 F-15 0-0 1-1 则 0000BFFFH 即 BFFF的 为 B*16^3+F*16^2+F*16^1+F*16^0 =11*16^3+15*16^2+15*16+15*1=49151
0000A000H 即 A000 的为 A*16^3+0*16^2+0*16^1+0*16^0=10*16^3=40960
则有存储单元 (49151-40960+1)/1024 =8K 个
注:每个地址编号为一个储存单元(容量为1个字节,即1B(BYTE)) 1K=1024B 还有个简单的计算方式:
0000BFFFH + 1 这个会等于 0000C000H,即:
B*16^3+F*16^2+F*16^1+F*16^0 + 1
=11*16^3+15*16^2+15*16+15*1 +1 =11*16^3+15*16^2+15*16+16
=11*16^3+15*16^2+16*16
=11*16^3+16*16^2
=12 * 16^3 = C * 16^3 (能理解吗?)
所以地址0000A000H 到 0000BFFFH 就是:
0000BFFFH - 0000A000H + 1
= 0000BFFFH + 1 - 0000A000H
背景 jQuery提供了JS未能提供的动画效果,利用jQuery的动画效果,可以极大的简化JS动画部分的逻辑
滑入滑出动画 滑入动画
定义:以下拉方式动画效果将html内容显示出来
使用方式:
( s e l e c t o r ) . s l i d e D o w n ( t i m e , f u n c t i o n ) ∗ ∗ ∗ ∗ (selector).slideDown(time,function)** ** (selector).slideDown(time,function)∗∗∗∗(selector).slideDown(2000)
( s e l e c t o r ) . s l i d e D o w n ( ) ∗ ∗ ∗ ∗ (selector).
Linux安装Docker 今天项目需要部署到Docker上去,那么就亲自来部署一把Docker咯。 Docker有两个版本:
社区版(CE)企业版(EE) Docker Community Edition(CE)非常适合希望开始使用Docker并尝试使用基于容器的应用的个人开发人员和小团队。 Docker企业版(EE)专为企业开发和IT团队而设计,他们可以在生产规模上构建,发布和运行关键业务应用程序。
一、比较以下Docker的社区版和企业版的区别 我们今天就只用社区版的咯
二、Docker的安装 请先访问Docker的官网获取相关的安装信息 docker官网 三、下面以Ubuntu系统为例,准备机器卸载旧Docker 3.1 系统要求 为了安装Docker,你需要以下的系统配置。
Artful 17.10 (Docker CE 17.11 Edge and higher only)Xenial 16.04 (LTS)Trusty 14.04 (LTS)Docker CE is supported on Ubuntu on x86_64, armhf, s390x (IBM Z), and ppc64le (IBM Power) architectures.ppc64le and s390x limitations: Packages for IBM Z and Power architectures are only available on Ubuntu Xenial and above. 3.2 准备一台Ubuntu机器 root@iZbp162mb58mqtz72o389nZ:~# lsb_release -a LSB Version: core-9.
首先我们先看源代码:
import lime import sklearn import numpy as np import sklearn import sklearn.ensemble import sklearn.metrics from __future__ import print_function from sklearn.datasets import fetch_20newsgroups categories = ['alt.atheism', 'soc.religion.christian'] newsgroups_train = fetch_20newsgroups(subset='train', categories=categories) newsgroups_test = fetch_20newsgroups(subset='test', categories=categories) class_names = ['atheism', 'christian'] # 两种标签,一种基督教,一种无神论 vectorizer = sklearn.feature_extraction.text.TfidfVectorizer(lowercase=False) ##使用TF-IDF对文本进行编码 train_vectors = vectorizer.fit_transform(newsgroups_train.data) test_vectors = vectorizer.transform(newsgroups_test.data) # 使用RF模型 rf = sklearn.ensemble.RandomForestClassifier(n_estimators=500) rf.fit(train_vectors, newsgroups_train.target) # RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini', # max_depth=None, max_features='auto', max_leaf_nodes=None, # min_samples_leaf=1, min_samples_split=2, # min_weight_fraction_leaf=0.
1.后台数据加载到table
实现的功能为通过axios获得后台(webapi)数据,在通过vue.js渲染到table中。 1.代码直接上代码,分为引用,js和html部分。 1.1添加引用
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="~/Scripts/vue.min.js"></script> <script src="~/Scripts/jquery-1.10.2.min.js"></script> axios的引用使用的是镜像,也可以引入本地文件。
1.2javascript
javascript部分分为以下几部分:
创建实例(详细了解参考链接):
var vm = new Vue({}) 创建数据对象:
data: {}在这里我们的数据对象为空的数组list:[]。 创建时执行方法:
mounted() {} 通过axios的get方法对数据对象赋值:
axios.get("~/api/projects/get?id=1") .then(response => { console.log(response); var obj = JSON.parse(response.data); //this.list = obj; this.list = [obj]; //this.list.push(response.data); console.log(this.list); })这里面需要注意的两个点是mounted的生命周期和mounted在整个实例中只执行一次。 var vm = new Vue({ el: '#appproject', data: { list: [], MenuBody: '这里是菜单的内容' }, mounted() { axios.get("~/api/projects/get?id=1") .then(response => { console.log(response); var obj = JSON.parse(response.data); //this.
PROPAGATION_REQUIRED-- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 ServiceA { void methodA() { ServiceB.methodB(); } } ServiceB { void methodB() { } } PROPAGATION_REQUIRED 假如当前正要执行的事务不在另外一个事务里,那么就起一个新的事务 比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候 1、如果ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA的事务内部,就不再起新的事务。这时只有外部事务并且他们是共用的,所以这时ServiceA.methodA或者ServiceB.methodB无论哪个发生异常methodA和methodB作为一个整体都将一起回滚。 2、如果ServiceA.methodA没有事务,ServiceB.methodB就会为自己分配一个事务。这样,在ServiceA.methodA中是没有事务控制的。只是在ServiceB.methodB内的任何地方出现异常,ServiceB.methodB将会被回滚,不会引起ServiceA.methodA的回滚 -----------------以上为重点内容----------------以下为引用全文------------ 事务的嵌套概念 所谓事务的嵌套就是两个事务方法之间相互调用。spring事务开启 ,或者是基于接口的或者是基于类的代理被创建( 注意一定要是代理,不能手动new 一个对象,并且此类(有无接口都行)一定要被代理——spring中的bean只要纳入了IOC管理都是被代理的 )。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的。 ### Spring默认情况下会对运行期例外(RunTimeException),即uncheck异常,进行事务回滚。
如果遇到checked异常就不回滚。
如何改变默认规则:
1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)
2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)
上面三种方式也可在xml配置 spring事务传播属性 在 spring的 TransactionDefinition接口中一共定义了六种事务传播属性: PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。 PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。 它要求事务管理器或者使用JDBC 3.
【日期】2018-05-15 【问题】爬虫爬取外链之后链接溯源父页面找不到 【原因】对应网站页面被随机篡改,每次爬取的告警外链都是源于网站不同页面 【发现过程】打印日志确认爬取时的页面内容跟后面手动打开的页面内容部分不一致,且每次爬取出相同的外链但父页面却不相同 【修复】无 【是否我导致】否 【解决Bug的时间】1天
函数指针的由来 一个函数在编译时被分配一个入口地址,这个入口地址就称为函数的指针。
函数名代表函数的入口地址,这一点和数组一样。我们可以用一个指针变量来存放这个入口地址,然后通过该指针变量调用函数。如:假设有一个求两者较大的函数如下:
int max(int x, int y); 当我们调用这个函数时可以这样:
int c; c max(a,b); 这是通常调用方法,其实我们还可以定义一个函数指针,通过指针来调用,如:
int (*p)(a,b); 有些朋友可能对(*p)()不大理解,其实它的意思就是定义一个指向函数的指针变量p,p不是固定指向哪个函数的,而是专门用来存放函数入口地址的变量。在程序中把哪个函数入口地址赋给它,它就指向哪个函数。但是注意,p不能像指向变量的指针变量一样进行p++p--等无意义的操作。
既然p是一个指针变量,那么久可以作为函数的参数进行传递。其实函数的指针变量最常用的用途之一就是作为函数参数传递到其它函数。这也是c语言中应用的比较深入的部分了。
函数指针的定义 函数指针就是指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如上所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。
函数指针有两个用途:调用函数和做函数的参数。
函数指针的用法 第一种用法(1.c)
#include <stdio.h> #include <stdlib.h> void (*pfun)(int data); void myfun(int data) { printf("get data:%d\n",data); } int main(int argc,char *argv[]) { pfun = myfun; (*pfun)(100); return 0; } 从这个例子可以看到,我们首先定义了一个函数指针 pfun ,这个函数指针的返回值为void型,然后我们给函数指针赋值,赋值为 myfun,也就是myfun函数的首地址,在C99中myfun函数名就是myfun函数的首地址,此时 pfun 获得了 myfun 的地址,pfun的地址等于myfun的地址,所以最终调用 pfun();也就相当于调用了 myfun();
第二种用法 (2.c)
#include <stdio.h> #include <stdlib.h> typedef void (*pfun)(int data); /*typedef的功能是定义新的类型。第一句就是定义了一种 pfun 的类型,并定义这种类型为指向某种函数的指针,这种函数以一个 int 为参数并返回 void 类型。*/ void myfun(int data) { printf("
项目预览 实现代码 ①/day_0514_06/src/com/qst/util/DBUtil.java
package com.qst.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class DBUtil { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; /** * 得到数据库连接 */ public Connection getConnection() { // 通过Config获取数据库配置信息 String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://39.105.54.45:3306/zhuxueliang?useUnicod=true&characterEncoding=utf-8"; String user ="root"; String pwd = "123"; try { // 指定驱动程序 Class.forName(driver); // 建立数据库连结 conn = DriverManager.getConnection(url, user, pwd); } catch (Exception e) { // 如果连接过程出现异常,抛出异常信息 //throw new SQLException("
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style type="text/css"> *{ padding: 0%; margin: 0%; } body{ background: url(bg.png); background-size: cover; } #result{ text-align: center; margin:200px auto; width:500px; height:350px; background: rgba(0,0,0,.5); padding: 10px 30px; font-family: 'Times New Roman', Times, serif; color: white; position: relative; box-shadow:0px 20px 35px rgba(0,0,0,.75); border:1px solid rgba(255,255,255,.3); border-radius: 12px; } #result img{ width: 150px; position: absolute; left: 35%; top: 12%; } #result #city{ font-size: 30px; padding-top: 210px; } #result #temp{ font-size: 30px; padding-top:10px; } #loading{ font-size: 32px; text-align: center; /*设置成相对定位就不会占用图片和文字部分了,可以重叠*/ position: absolute; left: 40%; top: 45%; transition:opacity 1s; } #loading.
Apache Tomcat爆出安全绕过漏洞 ,CVE编号CVE-2018-1305,Apache Tomcat 7、8、9多个版本受到影响。攻击者可以利用这个问题,绕过某些安全限制来执行未经授权的操作,这可能有助于进一步攻击。
漏洞概述 在 Apache Tomcat 9.0.0.M1 to 9.0.4, 8.5.0 to 8.5.27, 8.0.0.RC1 to 8.0.49 and 7.0.0 to 7.0.84 中,Apache Tomcat servlet 注释定义的安全约束,只在servlet加载后才应用一次。由于以这种方式定义的安全约束,应用于URL模式及该点下任何URL,很可能取决于servlet加载的次序-对于某些不应用的安全约束,这可能会将资源暴露给未经授权访问它们的用户。
漏洞危害 访问未授权的资源
影响版本 Apache Tomcat 9.0.0.M1 to 9.0.4 Apache Tomcat 8.5.0 to 8.5.27 Apache Tomcat 8.0.0.RC1 to 8.0.49 Apache Tomcat 7.0.0 to 7.0.84
修复建议 升级到以下版本:
Apache Tomcat 9.0.5 Apache Tomcat 8.5.28 Apache Tomcat 8.0.50
Apache Tomcat 7.0.85
QQ交流群:162136059
项目开发中需要将file转化为MultipartFile,网上百度发现使用org.springframework.mock.web.MockMultipartFile可以
File file3 = new File(fileMap.get("file").toString()); FileInputStream in_file = new FileInputStream(file3); // 转 MultipartFile MultipartFile multi = new MockMultipartFile(file3.getName(), in_file); 发现本地环境是可以的 原因是因为有spring-test这个包。
然而项目发布后发现项目启动不了一直报错找不到MockMultipartFile,原因是发布正式版时、根本不会打测试包。所以找不到。
还有就是MockMultipartFile这个东西是单元测试使用的,尽量不要使用这个。
有喜欢的朋友可以关注下头条号《老徐聊技术》
大规模的容器技术运用从来不是一项独立工程,而是一个汇集虚拟化技术、容器编排、任务调度、操作系统、容器仓库、跨节点网络、分布式存储、动态扩缩、负载均衡、日志监控、故障自恢复等系统性难题的复杂有机体。随着Docker的诞生和Google等互联网公司的推波助澜,这个领域出现了一大批优秀的开源项目,它们在简化容器技术使用成本的同时,也经常使得刚刚接触容器时间不太长的开发者和企业用户感到不知所措。
将知识分类是梳理零散信息的一种有效方式。对于容器技术的生态圈来说,其中涉及领域众多,有的项目横跨多个细分领域,有的项目则是针对特定场景需求定制的,难以对其功能类型做精确定义。不过,若仅考虑通用领域里的相关产品和工具,大致来说可以划分成14种主要类别。
以下将围绕容器生态,分别举例介绍这些类别中的典型开源项目,以及部分虽未开源但比较常用的100个周边产品。
容器引擎 容器引擎是容器集群生态圈的核心部分,它是与内核Namespace和CGroup等功能直接交互,并提供相应API使得外部能够与之集成的工具或服务。Docker无疑是目前为止最成功、广泛最使用的容器引擎之一。实际上从1.12版本以后,Docker的容器化功能已经由独立的项目RunC来实现,但Docker仍作为一个开源产品为用户提供完整的容器化解决方案。此外,社区中还有许多容器引擎项目,例如:
Docker:https://www.docker.com
Rkt:https://coreos.com/rkt
Systemd-nspawn:https://www.freedesktop.org/wiki/Software/systemd
Hyper:https://hyper.sh
Garden:https://github.com/cloudfoundry/garden
LXC:https://linuxcontainers.org
Photon:https://github.com/vmware/photon
Vagga:https://github.com/tailhook/vagga
gVisor:https://github.com/google/gvisor
Pouch:https://github.com/alibaba/pouch
这些项目只是众多支持不同平台和具有不同特性的容器引擎的冰山一角。例如Google曾经主导的lmctfy(http://lmctfy.io/)项目也是个十分优秀的容器引擎,然而该项目自2015年以后就不再被维护了。而最近Google刚刚开源的gVisor则是该领域中的新秀。另外值得一说的是,Hyper采用虚拟机的方式对环境进行隔离,并不是一种基于容器的隔离方案,但它能很好地与Docker或Kubernetes等容器集群技术相结合,取代其环境隔离的功能,因此也归属此列。
监控和数据收集 由于容器基于内核的特殊隔离方式,对容器性能和状态的监控与虚拟机存在一些差别。传统的虚拟机监控工具,例如Nagios和Zabbix等,对容器监控的原生支持并不十分易用。而一些新起的开源项目对这种场景具有更友好的体验,例如:
cAdvisor:https://github.com/google/cadvisor
Sysdig:http://sysdig.org
Prometheus:https://prometheus.io
TICK-Stack:https://influxdata.com
Docker-Alertd:https://github.com/deltaskelta/docker-alertd
Grafana:https://grafana.com
其中的TICK-Stack指的是Influxdata推出的Telegraf、InfluxDB、Chronograf、Kapacitor四款开源工具,不过从1.0以后,这些工具在开源版基础上提供了企业版本,后者提供了例如高可用、云端存储等企业级功能。
容器管理和界面工具 可视化是用户友好性十分重要的一部分,Shipyard和Decking是Docker早期时十分受欢迎的可视化工具,之后Docker也收购了Kitematic作为官方的容器管理UI。但随着容器应用集群化,早期的UI工具不再流行,一些针对特定集群平台定制的新型管理UI开始出现。例如Kubernetes官方推出了Dashboard项目用于可视化的管理集群,Cockpit则是红帽公司推出的Kubernetes集群管理界面。以下是其中一些开源的容器管理UI项目:
Kitematic:https://kitematic.com
DockerUI:https://github.com/crosbymichael/dockerui
Panamax:http://panamax.io
Rapid Dashboard:https://github.com/ozlerhakan/rapid
Cockpit:http://cockpit-project.org
Portainer:https://www.portainer.io
Shipyard:http://shipyard-project.com
Seagull:https://github.com/tobegit3hub/seagull
Dockeron:https://github.com/dockeron/dockeron
DockStation:https://dockstation.io
基础设施集成 容器集群的实施是需要以硬件基础设施作为依托的,有些辅助工具能够简化这个过程。这些项目往往与具体的底层平台相关,例如:
Nova-docker:https://github.com/stackforge/nova-docker
Magnum:https://github.com/openstack/magnum
Machine:https://docs.docker.com/machine
Boot2Docker:https://github.com/boot2docker/boot2docker
Clocker:https://github.com/brooklyncentral/clocker
MaestroNG:https://github.com/signalfuse/maestro-ng
Nova-docker和Magnum都是在OpenStack集成容器集群的项目,不过目前OpenStack官方正在尝试通过让Kubernetes直接创建虚拟机的方式来统一它在IaaS层和CaaS层的差异,其中的Nova-docker已经被废弃了。Machine是Docker公司推出的基础设施管理工具,Boot2Docker曾经是在Windows和Mac上使用Docker的官方方案,但随着Docker 1.12版本发布了多种操作系统的发行版后,已经不再被推荐使用了。
编排和调度 编排和调度是容器集群的基本功能,因此选择编排和调度工具实际上就是在选择容器集群的方案。以下是一些开源的容器任务编排调度工具:
SwarmKit:https://github.com/docker/swarmkit
Kubernetes:http://kubernetes.io
Marathon:https://github.com/mesosphere/marathon
Rancher:http://www.rancher.io
Nomad:https://github.com/hashicorp/nomad
OpenShift:https://www.openshift.com
Crane:https://github.com/michaelsauter/crane
Nebula:https://github.com/nebula-orchestrator
GearD:http://openshift.github.io/geard
其中的OpenShift主要是指其3.0之后的发行版,它是红帽公司基于Kubernetes二次开发的集持续集成和交付于一体的容器集群方案,具有开源和商业两个版本。
容器镜像仓库 镜像仓库是基于容器的在软件发布流程中必要的组成部分,Docker开源了其镜像仓库的最小实现,但对于企业级应用来说,它缺少了高可用、权限控制、管理界面等必要功能。Docker Hub和国内的许多容器云平台都提供了公有云的企业级仓库服务,社区中也有一些容器仓库的开源或免费的实现,例如:
Repository:https://github.com/docker/distribution
Nexus:http://www.sonatype.org/nexus
Habor:http://vmware.github.io/harbor
Portus:https://github.com/SUSE/Portus
Docker Registry UI:https://github.
python3.5 openpyxl2.5可以用这个文件解决 文件名为:fix_border.py,代码见下面的代码片
在你写代码的那个文件里导入该文件
from fix_border import patch_worksheet
然后在load文件前加上patch_worksheet()
全部代码为
ws = opx.load_workbook(filename1) fix_border.patch_worksheet() ws.save(filename2) fix_border.py代码为
# -*- coding:utf-8 -*- from itertools import product import types import openpyxl from openpyxl.utils import get_column_letter from openpyxl import worksheet from openpyxl.utils import range_boundaries from itertools import product import regex as re def patch_worksheet(): """This monkeypatches Worksheet.merge_cells to remove cell deletion bug https://bitbucket.org/openpyxl/openpyxl/issues/365/styling-merged-cells-isnt-working Thank you to Sergey Pikhovkin for the fix """ def merge_cells(self, range_string=None, start_row=None, start_column=None, end_row=None, end_column=None): "
转载链接:https://blog.csdn.net/husipeng86/article/details/52123465
三种GPIO的介绍 学了zynq一段时间,一上来的时候就被zynq的GPIO唬住了,实在没搞清楚zynq的GPIO怎么回事,一会这样,一会那样,最后才慢慢发现zynq至少有3种GPIO可以调用。难怪我觉得每篇介绍GPIO的博客说的有一些不一样呢。
我们先看有哪三种GPIO:MIO、EMIO、AXI_GPIO。其中MIO和EMIO是直接挂在PS上的GPIO。而AXI_GPIO是通过AXI总线挂在PS上的GPIO上。
我们先看一下MIO和EMIO:下图EMIO和MIO的结构。其中MIO分布在BANK0,BANK1,而EMIO则分布在BANK2、BANK3。注意一下几项:
首先、MIO在zynq上的管脚是固定的,而EMIO,是通过PL部分扩展的,所以使用EMIO时候需要在约束文件中分配管脚,所以设计EMIO的程序时,
需要生成PL部分的bit文件,烧写到FPGA中。
其次、由下图可以看出MIO共占54bit,而EMIO占64bit。其中MIO占用IO号为0-53。而EMIO占用IO号为54-117。
再者、无论是EMIO还是MIO都属于PS上的IO,直接由PS操作。在调用头文件,只调用#include "xgpiops.h"即可,而在调用AXI_GPIO时,则需要#include "xgpio.h"。
最后、在设计好bd文件后、系统会自动在路径:..\standalone_bsp_0\ps7_cortexa9_0\include生成 xparameters.h文件.我们可以在
xparameters.h文件中查看我们在bd设计时添加的外设ID。例如我们添加了EMIO,可以查到到该IO的地址和ID号。
[cpp] view plain copy #define XPAR_PS7_GPIO_0_DEVICE_ID 0 #define XPAR_PS7_GPIO_0_BASEADDR 0xE000A000 #define XPAR_PS7_GPIO_0_HIGHADDR 0xE000AFFF 再举例添加了两个AXI_GPIO,例化为BTNS_4BIT和SW_4BIT [cpp] view plain copy /* Definitions for driver GPIO */ #define XPAR_XGPIO_NUM_INSTANCES 2 /* Definitions for peripheral BTNS_4BIT */ #define XPAR_BTNS_4BIT_BASEADDR 0x41210000 #define XPAR_BTNS_4BIT_HIGHADDR 0x4121FFFF #define XPAR_BTNS_4BIT_DEVICE_ID 0 #define XPAR_BTNS_4BIT_INTERRUPT_PRESENT 0 #define XPAR_BTNS_4BIT_IS_DUAL 0 /* Definitions for peripheral SW_4BIT */ #define XPAR_SW_4BIT_BASEADDR 0x41200000 #define XPAR_SW_4BIT_HIGHADDR 0x4120FFFF #define XPAR_SW_4BIT_DEVICE_ID 1 #define XPAR_SW_4BIT_INTERRUPT_PRESENT 0 #define XPAR_SW_4BIT_IS_DUAL 0 再来看一下,AXI_GPIO相当于GPIO的IP核,我们调用时是占用相应AXI总线地址空间,如下图,占用地址为0x41200000和0x41210000
利用 #region,可以指定在使用 Visual Studio Code 编辑器的大纲功能时可展开或折叠的代码块。 在较长的代码文件中,能够折叠或隐藏一个或多个区域会十分便利,这样,可将精力集中于当前处理的文件部分。
#region 分页列表展示 public ActionResult Index() { int pageIndex = Request["pageIndex"] != null ? Convert.ToInt32(Request["pageIndex"]) : 1; int pageSize = 5; int pageCount = NewInfoService.GetPageCount(pageSize); pageIndex = pageIndex < 1 ? 1 : pageIndex; pageIndex = pageIndex > pageCount ? pageCount : pageIndex; List<T_New>list=NewInfoService.GetPageEntityList(pageIndex, pageSize); ViewData["newInfoList"] = list; ViewData["pageIndex"] = pageIndex; ViewData["pageCount"] = pageCount; return View(); } #endregion 优点:清晰明了,方便后期修改。
添加步骤:
选中需要添加的代码段——右键——片段——外侧代码。
备注 #region 块必须通过 #endregion 指令终止。 #region 块不能与 #if 块重叠。 但是,可以将 #region 块嵌套在 #if 块内,或将 #if 块嵌套在 #region 块内。
今天安装了navicat 和 mysql,结果最后在navicat中连接mysql时,出现了如下错误提示:
Client does not support authentication protocol requested by server; consider upgrading MySQL client 网上找了如下方法:
其一: mysql> SET PASSWORD FOR -> 'some_user'@'some_host' = OLD_PASSWORD('newpwd'); 其二: mysql> UPDATE mysql.user SET Password = OLD_PASSWORD('newpwd') -> WHERE Host = 'some_host' AND User = 'some_user'; mysql> FLUSH PRIVILEGES; 上面some_user、some_host、newpwd按自己实际情况修改
但是自己尝试了之后依旧有错误提示,最后尝试了如下方法恢复正常:
USE mysql; ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '831015'; FLUSH PRIVILEGES; root是用户名,localhost是ip地址127.0.0.1都是特指本机,mysql_native_password是旧的密码验证机制,831015是密码,最后别忘了分号;
最后问题解决:
感谢贴吧17楼大神:http://tieba.baidu.com/p/5658058140
主要利用了Java反射,导出时不需要在关注单元格、单元格对应的描述、以及单元格的值之间的对应关系。 util方法如下:
/** * 导出发票信息到excel * * @param dataList 发票信息list * @param response * @param title 工作表标题 * @param columns 单元格标题 >> columnName:columnProperty */ public static void exportTradeInvoiceExcel(List<? extends Object> dataList, HttpServletResponse response, String title, String[] columns) throws PayPlatformException { try { // 创建工作簿对象 HSSFWorkbook workbook = new HSSFWorkbook(); // 创建工作表 HSSFSheet sheet = workbook.createSheet(title); // 产生表格标题行 HSSFRow rowColumn = sheet.createRow(0); HSSFCell cellTitle = rowColumn.createCell(0); //设置标题和单元格样式 //获取列头样式对象 HSSFCellStyle columnTopStyle = createColumnTopCellStyle(workbook); //合并单元格 sheet.