一分钟看懂数据湖架构

一分钟看懂数据湖架构 数据湖和数据仓库两者都广泛应用于大数据存储,但两者之间概念不可互换。数据湖是存储原始数据的池,目的仍没有明确。数据仓库存储结构化的、已过滤、处理的数据,用于特定分析目的。 两种数据存储架构经常被混淆,起始两者之间差异大于共性。事实上,唯一共性都为了存储海量数据。 了解两者区别很重要,因为它们服务于不同的目的,需要使用不同的视角进行理解。虽然数据湖适用于一家公司,但数据仓库应该更适合一家公司。 四个方面差异分析 两者有几个方面的差异:数据结构、用户群、处理方法以及数据的应用目的。 数据湖 数据仓库 数据结构 原始数据 处理过的数据 应用目的 仍未确定 当前正使用 用户群 数据科学家 商务人士 数据访问 高可访问性和快速更新 修改更复杂、成本高 数据结构:原始数据 vs. 已处理数据 原始数据是仍没有为特定目的处理过的数据。两者最大的差异是多样的原始结构和已处理的数据。数据湖主要存储原始的、未处理的数据,而数据仓库存储处理、提炼过的数据。 因此,数据湖较数据仓库一般需要更大的存储能力。另外,原始的、未处理数据适用性更强,可以服务与任何目的应用,尤其是机器学习。但有时数据湖收集所有原始数据的分险是变成数据沼泽,因为没有相应的数据治理和数据质量措施。 数据仓库仅存储处理过的数据。节约存储空间,并不维护可能永不使用的数据。另外,处理过的数据对大多数人来说比较容易理解。 目的:未确定 vs. 正在使用 数据湖中单个数据块的目的并不确定。原始数据流入数据湖,有时是为未来特定目的,有时仅为了手边有这样数据。这意味着数据湖的数据组织、过滤相较于数据仓库更少。 已处理的数据是针对特定目的来处理原始数据。因为数据仓库仅存储已处理的数据,所有在存储仓库中的数据用于特定目标而组织的。因此存储空间不会浪费。 用户群:数据科学家 vs. 商务人士 数据湖对不熟悉的人通常很难浏览未处理的数据,原始的、非结构化数据一般需要数据科学家使用特定工具为特定目的进行理解、翻译、分析。同时越来越多的数据湖信息自助访问工具也正在涌现。 可访问性:灵活性 vs. 安全性 可访问性和易用性是指整个数据存储库的使用,而不是其中的数据。数据湖数据没有结构,比较容易访问、改变。而且,任何对数据的改变能快速完成,因为数据湖几乎没有限制。 数据仓库是被设计的,更加结构化。数据仓库的主要优势为正在处理的结构化数据更容易描述,结构的限制使得数据仓库维护成本更高。 我该如何选择 一般组织两者都需要。数据湖诞生于利用大数据的需要,机器学习从原始、更细粒度结构和非结构化数据中受益,但仍然需要创建数据仓库供业务用户分析使用。

旧版 Android 系统为目标平台的应用的警告

1.问题呈现: 在Android10.0中运行应用会提示“此应用专为旧版Android打造,可能无法正常运行,请尝试更新或与开发者联系”。 具体截图如下: 为什么在Android10.0会出现这个提示,而在低版本中却没有呐? 2.问题分析 我们可以在官方网站中的Android10.0版本中的影响应用的行为变更中找到答案。 可以看出是项目中配置targetSdkVersion的影响。那么什么是targetSdkVersion。 3.targetSdkVersion介绍 一个用于指定应用的目标 API 级别的整数。如果未设置,其默认值与为 minSdkVersion 指定的值相等。 该属性用于通知系统,您已针对目标版本进行测试,并且系统不应通过启用任何兼容性行为,以保持您的应用与目标版本的向前兼容性。应用仍可在较低版本上运行(最低版本为 minSdkVersion)。 Android 会随新版本的推出而逐渐发展,在此过程中,某些行为乃至外观可能会发生变化。不过,如果平台的 API 级别高于应用 targetSdkVersion 所声明的版本,系统便可通过启用兼容性行为,确保应用继续以您所期望的方式工作。您可以将 targetSdkVersion 指定为符合应用所运行平台的 API 级别,从而停用此类兼容性行为。例如,如果将该值设置为“11”或更高,系统便可在应用运行在 Android 3.0 或更高版本的平台上时对其应用新的默认主题 (Holo),还可在应用运行在更大屏幕上时停用屏幕兼容性模式(因为对 API 级别 11 的支持隐含了对更大屏幕的支持)。 系统可根据您为该属性设置的值启用许多兼容性行为。Build.VERSION_CODES 参考资料中的相应平台版本介绍了其中几种行为。 如要让应用与各 Android 版本保持同步,您应增加该属性的值,使其与最新 API 级别一致,然后在相应平台版本上对应用进行全面测试。 4.源码分析 AppWarnings.java,在onStartActivity会检测targetSdkVersion,如果小于系统的支持最小的目标版本,则弹出提示框。代码块如下: /** * Shows the "deprecated target sdk" warning, if necessary. * * @param r activity record for which the warning may be displayed */ public void showDeprecatedTargetDialogIfNeeded(ActivityRecord r) { if (r.

mysql数据库日志查询

Mysql数据库日志 日志分类 MySql日志类型 解析说明 错误日志(error log) 当数据库启动、运行、停止时产生该日志 普通查询日志(general query log) 客户端连接数据库执行语句时产生该日志 二进制日志(binary log) 当数据库内容发生改变时产生该日志,也被用来实现主从复制功能 中继日志(relay log) 从库上收到主库的数据更新时产生该日志 慢查询日志(show query log) SQL语句在数据库查询超过指定时间时产生该日志 DDL日志(metadata log) 执行DDL语句操作元数据时产生该日志 一、错误日志 错误日志说明 Mysql的错误日志用于记录mysql服务进程mysqld在启动、关闭或运行过程中遇到的错误信息。 通常由mysqld或mydql_safe程序产生。 错误日志的配置 配置方法: 1、在my.cnf配置文件的[mysql_safe]模块下配置 [mysql_safe] log-error=/application/mysql-5.6.36/data/mysql-2.err ​ 2、在启动mysql服务的命令中添加错误日志的参数**** mysqld_safe --log-error=/application/mysql-5.6.36/data/mysql-2.err & ​ 查看日志结果: [root@mysql-2 ~]# tail -n 4 /application/mysql-5.6.36/data/mysql-2.err 2019-06-15 03:08:26 28735 [Note] Server socket created on IP: ‘::’. 2019-06-15 03:08:26 28735 [Note] Event Scheduler: Loaded 0 events 2019-06-15 03:08:26 28735 [Note] /application/mysql-5.

pytorch继承nn.Module类定义模型

在pytorch中,最常用于定义模型的方法是继承nn.Module类后重载__init__()和forward函数。部分疑问记录: 1.为什么重载forward函数后可以直接使用net(x)调用? 2.哪些网络模块要预先写在__init__中? 3.如果一个网络模块有多个重复的网络层。哪些可以在__init__只定义一次。哪些要定义多次。 一 forward函数 1.python的__init__,__new__,__call__函数 __new__,__init__参考这篇博客 (1)__new__类构造函数 1)类级别的方法,需要至少传递一个参数cls。 2)必须有返回值,返回实例化出来的实例self。 (2)__init__类初始化函数 1)实例级别方法,需要至少传递一个参数self,self指的是__new__构造方法构造的实例。 2)必须不能有返回值,否则会报错 python实例先使用类的__new__方法构造出实例,再通过__init__方法初始化该实例。进行以下测试。 class A(): def __init__(self): """对象初始化,此时对象已存在,通过new方法创建,对创建好的对象进行初始化""" super(A,self).__init__() print("__init__") print(self) #return self def __new__(cls, *args, **kwargs): """新建对象。并返回self""" print("__new__") #print(cls) self = super(A,cls).__new__(cls) print(self) return self def __call__(self): """可调用对象,实现了__call__方法的类的对象是可调用对象。可调用对象可使用()进行调用""" print("run call") return "test" a = A() 运行结果: __new__ <__main__.A object at 0x7f5df0f8e550> __init__ <__main__.A object at 0x7f5df0f8e550> (3)__call__函数 Python中实现了__call__方法的实例就是可调用对象。可以像调用函数一样调用实例。 如在上面的例子中,直接调用该实例,会看到以下输出。 t = a() print(t) 输出: run call test 同时,__call__可以接受参数,也可以有返回值。现在我们知道要在__init__中进行初始化,可以利用__call__对象像函数一样被调用。下面模拟一下网络层的大致流程。

话题:你们都用计算机解决过哪些生活中的问题?

常说学以致用, 说说,你们都用过哪些计算机技能解决生活中的问题? 爱claxy磕瓜子: 抢……抢月饼? 有种病毒叫姚老板木马: 因为我是学计算机的,领导让我把电脑从二楼搬到3楼 DreamCatcher-GIS: 大一的时候上测量实践课,嫌误差计算公式太麻烦,于是在手机里写了一个C程序,实现了计算流程。大二亲戚问我高考学校报考问题,嫌弃网络上没有好用的查询系统,于是自己用爬虫爬了历年的高考分数信息,做了一个基于百分比和线查的学校查询系统。 丶恩哼o: 去妹子家修电脑 匹配一句好慢: 帮朋友重装系统,帮朋友清灰,帮朋友…,帮朋友的朋友… 这个技能不能随便暴露~ MR666qu: 自己写个网站,里面全是自己喜欢的内容,再无广告 隐形人_北极鹅: 帮同学开班会,开元旦晚会;帮同学做了一个表白软件,还尼玛成功了;批处理班级文件……我的天 马Tian贺贺贺: 作为一个程序员,他们认为我就是个修电脑装系统的。 我只有半颗糖: 大学三年所有的知识点总结。为全班不挂科而奋斗,打字! 高尔斯基不搞基: 跪键盘 belivar: 帮体育老师做参赛网站,之后的最怕的体育测试不用去直接高分过 王王其倾: 我悄悄地来说一句,搞定了期末的思政考试 茨烩饼的敖丙就爱叨逼叨: 用随机函数决定谁拿外卖 白菜杜: 我是程序员.但是问题是我真的会修电脑 流血的手指: 上下班打卡 奇思妙想的香菜: 前女友就是从重装系统开始的 那你呢?在下方留言分享你的经历吧!

各类距离度量定义及公式【转载】

转载自:https://blog.csdn.net/weixin_42715356/article/details/82845376 总结各类距离度量方法。 1、欧氏距离 最常见的两点之间或多点之间的距离表示法,又称之为欧几里得度量,它定义于欧几里得空间中,如点 x = (x1,…,xn) 和 y = (y1,…,yn) 之间的距离为: (1)二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离: (2)三维空间两点a(x1,y1,z1)与b(x2,y2,z2)间的欧氏距离: (3)两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的欧氏距离: 也可以用表示成向量运算的形式: 2、曼哈顿距离 我们可以定义曼哈顿距离的正式意义为L1-距离或城市区块距离,也就是在欧几里得空间的固定直角坐标系上两点所形成的线段对轴产生的投影的距离总和。例如在平面上,坐标(x1, y1)的点P1与坐标(x2, y2)的点P2的曼哈顿距离为:|x1-x2|+|y1-y2|,要注意的是,曼哈顿距离依赖座标系统的转度,而非系统在座标轴上的平移或映射。 通俗来讲,想象你在曼哈顿要从一个十字路口开车到另外一个十字路口,驾驶距离是两点间的直线距离吗?显然不是,除非你能穿越大楼。而实际驾驶距离就是这个“曼哈顿距离”,此即曼哈顿距离名称的来源, 同时,曼哈顿距离也称为城市街区距离(City Block distance)。 (1)二维平面两点a(x1,y1)与b(x2,y2)间的曼哈顿距离: Dist=|x1-x2|+|y1-y2| (2)两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的曼哈顿距离: 3、夹角余弦(Cosine) 几何中夹角余弦可用来衡量两个向量方向的差异,机器学习中借用这一概念来衡量样本向量之间的差异。 (1)在二维空间中向量A(x1,y1)与向量B(x2,y2)的夹角余弦公式: (2) 两个n维样本点a(x11,x12,…,x1n)和b(x21,x22,…,x2n)的夹角余弦 类似的,对于两个n维样本点a(x11,x12,…,x1n)和b(x21,x22,…,x2n),可以使用类似于夹角余弦的概念来衡量它们间的相似程度,即: 夹角余弦取值范围为[-1,1]。夹角余弦越大表示两个向量的夹角越小,夹角余弦越小表示两向量的夹角越大。当两个向量的方向重合时夹角余弦取最大值1,当两个向量的方向完全相反夹角余弦取最小值-1。 4. 杰卡德相似系数(Jaccard similarity coefficient) (1) 杰卡德相似系数 两个集合A和B的交集元素在A,B的并集中所占的比例,称为两个集合的杰卡德相似系数,用符号J(A,B)表示。 杰卡德相似系数是衡量两个集合的相似度一种指标。 (2) 杰卡德距离 与杰卡德相似系数相反的概念是杰卡德距离(Jaccard distance)。 杰卡德距离可用如下公式表示: 杰卡德距离用两个集合中不同元素占所有元素的比例来衡量两个集合的区分度。 (3) 杰卡德相似系数与杰卡德距离的应用 可将杰卡德相似系数用在衡量样本的相似度上。 举例:样本A与样本B是两个n维向量,而且所有维度的取值都是0或1,例如:A(0111)和B(1011)。我们将样本看成是一个集合,1表示集合包含该元素,0表示集合不包含该元素。 M11 :样本A与B都是1的维度的个数 M01:样本A是0,样本B是1的维度的个数 M10:样本A是1,样本B是0 的维度的个数 M00:样本A与B都是0的维度的个数 依据上文给的杰卡德相似系数及杰卡德距离的相关定义,样本A与B的杰卡德相似系数J可以表示为: 这里M11+M01+M10可理解为A与B的并集的元素个数,而M11是A与B的交集的元素个数。而样本A与B的杰卡德距离表示为J’: 5、皮尔逊系数(Pearson Correlation Coefficient)(两向量的夹角余弦值) 在具体阐述皮尔逊相关系数之前,有必要解释下什么是相关系数 ( Correlation coefficient )与相关距离(Correlation distance)。

深度学习教程-入门

深度学习入门教程 简单易懂的深度学习入门教程: 附百度网盘地址: 链接: https://pan.baidu.com/s/1DcqYXcaB5zGlsqcXqKZGEw 提取码: yk5f

卷积运算和运算后特征图大小计算2

every blog every motto: Stay hungry, stay foolish. 0. 前言 主要讲下实际卷积运算中关于padding=same和padding=valid的输出特征图的大小,以及池化后特征图的大小。 1. 正文 1. 卷积运算 特别说明:卷积(除不尽)向下取整!!!! 特别说明:卷积(除不尽)向下取整!!!! 特别说明:卷积(除不尽)向下取整!!!! 关于卷积的基本运算参照卷积运算和运算后特征图大小计算1 参数定义: 输入大小:intputH 卷积核大小:K 步长:S 填充:P 输出图像大小:outputH 1.1 padding=valid 不进行填充,P=0,输入特征图大小为: o u t p u t H = i n t p u t H − K + 2 ∗ 0 S + 1 outputH = \frac{intputH-K+2*0}{S}+1 outputH=SintputH−K+2∗0​+1 即: o u t p u t H = i n t p u t H − K S + 1 outputH = \frac{intputH-K}{S}+1 outputH=SintputH−K​+1

linux基本指令

linux学习 1. Linux 系统目录结构 对这些目录的解释: /bin:bin是Binary的缩写, 这个目录存放着最经常使用的命令。/boot: 这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。/dev : dev是Device(设备)的缩写, 存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。/etc: 这个目录用来存放所有的系统管理所需要的配置文件和子目录。/home:用户的主目录,在Linux中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。/lib:这个目录里存放着系统最基本的动态连接共享库,其作用类似于Windows里的DLL文件。/lost+found:这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。/media:linux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。/mnt:系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目录就可以查看光驱里的内容了。/opt:这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。/proc:这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。/root:该目录为系统管理员,也称作超级权限者的用户主目录。/sbin:s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。/srv:该目录存放一些服务启动之后需要提取的数据。/sys:这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs 。/tmp:这个目录是用来存放一些临时文件的。/usr:这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的program files目录。/usr/bin: 系统用户使用的应用程序。/usr/sbin: 超级用户使用的比较高级的管理程序和系统守护程序。/usr/src: 内核源代码默认的放置目录。/var:这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。/run:是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。 2. 基本指令 命令格式: command [-options] [parameter] 说明: command:命令[-options]:选项[parameter]:参数 command --help #查看帮助 (1) cd 切换文件夹 cd [相对路径或绝对路径] cd /home #绝对路径,以根目录开头 cd admin #相对路径,不以根目录开头 cd .. #返回上级目录 cd / #回到根目录 cd ~ #回自己家 cd - #回看 pwd #查看当前目录 (2) ls 查看目录内容 ls ls -l #显示详细列表,包含文件的属性与权限等等数据 ls -lh #把文件大小以人性化的方式显示,即以M为单位 ls -a #显示所有的文件,包括隐藏文件(以.开头的文件) ll #等价于ls -l ls *txt #查看当前目录下所有以txt结尾的文件 ls / #查看根目录内容,ls后面可以加任意指定目录 #参数可以组合使用 (3) mkdir 创建文件夹 mkdir [-mp] 目录名称 #新建文件夹 mkdir tupian #在当前目录下创建tupian文件夹 mkdir /root/tupian #以绝对路径创建tupian文件夹 mkdir -p aaa/bbb/ccc #加上这个 -p 的选项,创建多层目录! mkdir a b #在当前目录创建多个文件夹 mkdir a/{c,d} #在指定目录下创建多个文件夹 mkdir .

帆软内置数据集实现决策报表联动

1 场景 现在有生产产量(柱状图)和月产量(饼图),需要点击生产产量中的某月中的某类型的柱子,查询该月、该类型下的所有信息,展示在月产量(饼图)中。 传递的参数是月份(1-12月)、类型(铸轧生产产量、冷轧生产产量)。 要求:使用帆软内置数据集实现该决策报表的点击联动。 2 问题 1)传参数通常是采用mysql的sql语句传递参数,但这里没有使用mysql; 2)帆软还有一种传参数方式是.cpt文件中单元格数据过滤,但这里没有使用.cpt文件; 3 解决办法和操作流程 1)建立内置数据集 2)建立柱状图——生产产量 柱状图,建立传递参数 3)建立中间表report1——用于传递参数 注意参数名称,一定要对应。 4)建立饼图——月产量 获取中间表过滤后的数据,用于饼图展示。 饼图的数据来源于数据库表的单元格: 系列名选择F(x),输入 report1~C1(合金分类) 值选择F(x),输入 report1~D1(分类数量)

计算机视觉——基础矩阵

文章目录 一、外极几何原理八点估算法 二、实验分析1、左右拍摄,极点位于图像平面上2、像平面接近平行,极点位于无穷远3、图像拍摄位置位于前后4、结果分析 三、实验中遇到的问题 一、外极几何原理 为了解释基础矩阵,我们要先了解一下外极几何的相关知识。 提到对极几何,一定是对二幅图像而言,对极几何实际上是“两幅图像之间的对极几何”,它是图像平面与以基线为轴的平面束的交的几何(这里的基线是指连接摄像机中心的直线),以下图为例:对极几何描述的是左右两幅图像(点x和x’对应的图像)与以CC’为轴的平面束的交的几何! 八点估算法 基本矩阵是由该方程定义的 X ′ T F x = 0 X'^TFx = 0 X′TFx=0 其中x↔x′是两幅图像的任意一对匹配点。由于每一组点的匹配提供了计算F系数的一个线性方程,当给定至少7个点(3×3的齐次矩阵减去一个尺度,以及一个秩为2的约束),方程就可以计算出未知的F。我们记点的坐标为x=(x,y,1)T,x′=(x′,y′,1)T 又F为: 则: 即相应方程式为 求解上面的方程组就可以得到基础矩阵各个元素了。当然这只是理想中的情况,由于噪声、数值的舍入误差和错误的匹配点的影响,仅仅求解上面的线性方程组得到的基础矩阵非常的不稳定,在实际计算中,可以直接用ATA的分解来求解参数。也可以用非线性优化,通过搜索f使得||Af||最小化,同时满足||f||=1的约束,上述求解后的F不一定能满足秩为2的约束,因此还要在F基础上加以约束。 通过SVD分解可以解决,令F=UΣVT,又因为要秩为2,所以这里取最后一个元素设置为0,则 二、实验分析 实验源码: # coding: utf-8 from PIL import Image from numpy import * from pylab import * import numpy as np from PCV.geometry import homography, camera, sfm from PCV.localdescriptors import sift camera = reload(camera) homography = reload(homography) sfm = reload(sfm) sift = reload(sift) # 提取特征 im1 = array(Image.

js的内存机制

前言 像C语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()用于分配内存和释放内存。 而对于JavaScript来说,会在创建变量(对象,字符串等)时分配内存,并且在不再使用它们时“自动”释放内存,这个自动释放内存的过程称为垃圾回收。 因为自动垃圾回收机制的存在,让大多Javascript开发者感觉他们可以不关心内存管理,所以会在一些情况下导致内存泄漏。 内存模型 JS内存空间分为栈(stack)和堆(heap),其中栈存放变量,堆存放复杂对象。 JS中五种基本的数据类型Undefined、Null、Boolean、Number、String,是按值访问,数据在栈内存中的存储。 JS的引用数据类型,比如数组Array,它们值的大小是不固定的,引用数据类型的真实对象是保存在堆内存中的。 变量声明的本质是变量名与栈内存地址进行绑定,不直接与堆内存进行绑定。 声明的基本数据类型会将值存储在栈内存中,声明的复杂数据类型会将值存储在堆内存中并将其在堆中的内存地址作为值存到栈内存中。 例子: 基本数据类型 let index = 23 为变量(index)创建一个唯一标识符。 为变量分配一个内存地址(运行时)。 在分配的地址中存储一个值(23)。 基础数据类型直接将值存储在栈内存中,变量绑定到值在栈中对应的地址。 let _index = index 声明另一个变量_index并赋值为index,其实是将_index和index变量绑定到index指向的内存地址。 index = 45 修改变量index的值为基本数据类型,其实是在栈内存中分配内存存储值然后将得到的内存地址绑定到变量index。 复杂数据类型 let students = [] 为变量(students)创建一个唯一标识符。 在栈中给变量分配一个地址a(运行时)。 在堆中分配一个地址b,用来存储值 [](运行时)。 地址a所存储的值为地址b。 复杂数据类型在声明时是在堆内存上分配内存空间存储其值,将分配的堆内存空间地址作为值存储在栈内存上,变量直接绑定的是栈上内存地址。 通过引用来修改复杂数据: let _students = students _students.push({ name: '小明' }) _status = students 赋值语句只是将两个变量指向同一个栈内存地址,push()语句将在堆内存中分配新空间存储新的数组并将其在堆内存的地址存储到栈中 let obj = { name: '小明' } let arr = [] arr = [ obj ] obj = null 内存模型示意图如下:

warning Delete `␍` prettier/prettier(eslint配置的一些问题)

配置eslint后运行项目有如下警告(换行格式问题): 执行以下命令(可以自动修复这些问题): npm run lint --fix 参考:eslint-plugin-prettier/issues/114 原因 在window系统中,clone代码下来,会自动把换行符LF(linefeed character) 转换成回车符CRLF(carriage-return character)。这时候我们本地的代码都是回车符。 如果没有加eslint,提交代码的时候,项目的仓库默认是Linux环境下提交的代码,就会提示将会覆盖换行符为LF。 如下图: 使用了eslint并有进行规则配置或者prettier的.prettierrc有进行配置结尾换行符,那么就会直接在开发环境中进行验证。就会提示上述错误(警告)。 我们可以配置.prettierrc文件不进行检查每一行换行的格式,但是这就违背了我们使用eslint的初衷: "endOfLine": "auto", 所以最好是把这个格式统一一下,在window系统(老旧的mac可能跟windows一样)可以使用git执行以下命令关掉自动转化(git默认是打开的): git config --global core.autocrlf false

UmiJS常用配置

简介 配置文件允许在 .umirc.js 或 config/config.js (二选一,.umirc.js 优先)中进行配置 // config/config.js示例 export default { base: '/web/', //部署到非根目录时才需配置 publicPath: '/web/', //部署到非根目录和base一起使用 targets: { //配置浏览器最低版本,比如兼容ie11 ie: 11 }, hash: true, //开启打包文件的hash值后缀 treeShaking: true, //去除那些引用的但却没有使用的代码 plugins: [ [ 'umi-plugin-react', { antd: true, //启用后自动配置 babel-plugin-import,实现antd按需加载 dynamicImport: { //实现路由级的动态加载 webpackChunkName: true //实现有意义的异步文件名 }, dva: { dynamicImport: true, //是否启用按需加载 hmr: true //是否启用 dva 的 热更新 }, //通过 webpack 的 dll 插件预打包一份 dll 文件来达到二次启动提速的目的 dll: { exclude: [], include: ['dva', 'dva/router', 'dva/saga', 'dva/fetch', 'antd/es'] }, //约定式路由时才需引用,用于忽略指定文件夹中自动生成的路由 routes: { exclude: [ /components\//, /model\.

van-picker级联选择(自定义字段显示)

前言 Vant之van-picker级联选择 将自定义平铺结构转化为层级结构数据动态$set()给每一条数据对象添加text属性用于展示 数据处理 原始数据 [ {id: 'node1',pid: 'root',content: 'test'}, {id: 'node2',pid: 'root',content: 'test'}, {id: 'node3',pid: 'node1',content: 'test'}, {id: 'node4',pid: 'node2',content: 'test'}, {id: 'node5',pid: 'node3',content: 'test'}, {id: 'node6',pid: 'node1',content: 'test'} ] 转化后数据 [ { id: 'node1', pid: 'root', content: 'test', children: [ { id: 'node3', pid: 'node1', ccontent: 'test', children: [ {id: 'node5',pid: 'node3',content: 'test'} ] }, {id: 'node6',pid: 'node1',content: 'test'} ] }, { id: 'node2', pid: 'root', content: 'test', children: [ {id: 'node4',pid: 'node2',content: 'test'} ] }, ] 转化函数tile2nest // 平铺结构转嵌套结构 tile2nest(array, key, pKey, childrenKey) { if (!

知识点七:Java中深克隆和浅克隆的区别以及实现方式

使用克隆可以为我们快速地构建出一个已有对象的副本,它属于 Java 基础的一部分,也是重要的知识点之一。 那么什么是浅克隆和深克隆?如何实现克隆? 浅克隆(Shadow Clone)是把原型对象中成员变量为值类型的属性都复制给克隆对象,把原型对象中成员变量为引用类型的引用地址也复制给克隆对象,也就是原型对象中如果有成员变量为引用对象,则此引用对象的地址是共享给原型对象和克隆对象的。 简单来说就是浅克隆只会复制原型对象,但不会复制它所引用的对象,如下图所示: 深克隆(Deep Clone)是将原型对象中的所有类型,无论是值类型还是引用类型,都复制一份给克隆对象,也就是说深克隆会把原型对象和原型对象所引用的对象,都复制一份给克隆对象,如下图所示: 在 Java 语言中要实现克隆则需要实现 Cloneable 接口,并重写 Object 类中的 clone() 方法,实现代码如下: public class CloneExample { public static void main(String[] args) throws CloneNotSupportedException { // 创建被赋值对象 People p1 = new People(); p1.setId(1); p1.setName("Java"); // 克隆 p1 对象 People p2 = (People) p1.clone(); // 打印名称 System.out.println("p2:" + p2.getName()); } static class People implements Cloneable { // 属性 private Integer id; private String name; /** * 重写 clone 方法 * @throws CloneNotSupportedException */ @Override protected Object clone() throws CloneNotSupportedException { return super.

saber软件安装常见问题

saber软件安装破解常见问题 saber是一款电路仿真软件。但是相信大部分人安装过程遇到了很多问题。接下来我将说明一些常见问题的解决办法。 (一)安装位置 1.安装位置与安装包位置全英文,CDE盘都可以。 2.破解的时候破解文件和安装位置要放在同一个盘,同一个盘就可以了 (二)saber安装完成不能打开 saber能不能打开与你是否破解没有关系。 按照道理来说,软件装完不要着急去破解,你的问题可能不是出在破解上,装完后打开软件看看是不是有提示没有许可权限这些才开始破解。 saber什么目录没有写权限 如果你的用户名是英文的那可能不会遇到这个问题,如果不是,嘿嘿!你的麻烦就来了。 比如我遇到不能打开的错误提示是:saber什么目录没有写权限,问题不在与破解,在于安装,浪费了很多时间。 ”saber什么目录没有写权限“的解决办法: 1.检查用户名: 2.这个问题只能通过建立新用户来解决,你在控制面板建立一个新用户,然后把新用户设置为管理员,把原来的用户保留文件删除,重启! 破解 来这里的我相信破解文件都有了。破解步骤一步一步来没有什么大问题。 不过我要提醒的是: 破解软件听起来很炫酷,不过你要做好听几个小时的准备,哈哈! 下图中,如果你的HOSTID有一长串的话是不对的。要禁用无线网卡。 但也要注意如果你的HOSTID为:00000000(我也不知几个0)也是不对的,只是禁用无线网卡就行了。 选择了其D,E盘安装,DOS打开D,E盘命令 cd \ //先回到根目录 C:\Users\yonghuming>cd 2.cd d: //打开D盘 C:>d: D:> 其他问题 其他的倒是没有什么注意的都是复制粘贴,运行运行DOS,加加变量. 祝你好运!

kali2020 pip3 安装

很多东西都没有。。。 用网上的wget方法wget https://bootstrap.pypa.io/get-pip.py 再python3 get-pip.py 竟然还报错SyntaxError: EOF while scanning triple-quoted string literal 什么鬼????? 最后用curl的方法下载 + python3 get-pip.py。又成功安好了?????? 我:????? C:\root\Desktop> curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1764k 100 1764k 0 0 60224 0 0:00:30 0:00:30 --:--:-- 146k C:\root\Desktop> pip3 --version pip 20.0.2 from /usr/local/lib/python3.7/dist-packages/pip (python 3.7)

C++路线_01C语言基础_01Linux_10删除空目录(rmdir)

rmdir命令 rmdir,remove empty directories 的缩写,用于删除空目录,命令基本格式为: 注意:只用于删除空目录,一旦非空会报错 [localhost.zhubin@localhost ~]$ rmdir [-p] 目录名 -p 选项用于递归删除空目录 【例如】 删除一个空目录 [localhost.zhubin@localhost ~]$ mkdir day02 [localhost.zhubin@localhost ~]$ ls 公共 模板 视频 图片 文档 下载 音乐 桌面 day01 day02 [localhost.zhubin@localhost ~]$ rmdir day02 [localhost.zhubin@localhost ~]$ ls 公共 模板 视频 图片 文档 下载 音乐 桌面 day01 【-p删除】 之前已经演示过rmdir -p 的作用了,所以这里直接进行演示rmdir -p的作用,可以看到day02/day0202(空目录)直接被删除了。 注意,这里删除目录的时候是从最低一级目录,也就是从day0202开始判断是否为空然后删除,再逐层删除上级目录 就日常使用来说,我们还是使用rm使用的多一些,rmdir毕竟还是有限制的,还要去判断是否为空目录,如果目录较多,这多出来的一步是要人命的

C-最长非公共子序列

链接:https://ac.nowcoder.com/acm/contest/5278/C 来源:牛客网 题目描述 Lemon 丢给你两个字母序列 s1和 s2 ,并无情地交给了你一个奇怪的任务——求最长非公共子序列。 序列 a 是 b 的子序列,当且仅当从 b 中删除一些元素(可以是零个或所有)能得到 a。 例如: 我们可以通过从 “abcde” 中删除 “b” 和 “d” 得到 “ace”,因此 “ace” 是 “abcde” 的子序列。 同理 “abcde”,“e” 和 空串 都是 “abcde” 的子序列; 但 “abdc” 不是 “abcde” 的子序列。 序列 c 是 s1和 s2的非公共子序列当且仅当它满足以下条件中的任何一个: c 是 s1的子序列但不是 s2 的子序列; c 是 s2的子序列但不是 s1 的子序列。 s1和 s2 的非公共子序列可能有很多,你只需要求出其中长度最长的非公共子序列的长度。 输入描述: 第一行包含一个字符串 s1,第二行包含一个字符串 s2。 输入保证 s1和 s2均只包含小写字母。 输出描述: 在一行输出一个整数,表示最长非公共子序列的长度。 特别地,如果不存在非公共子序列,输出 -1 。

Flutter dio XMLHttpRequest error

Flutter dio XMLHttpRequest error 原文:https://blog.csdn.net/weixin_44259356/article/details/105601933 dio网络请求app端请求接口没有问题,换成web端请求报错XMLHttpRequest error 这是浏览器限制跨域问题,通常解决方案如下: 服务端添加Access-Control-Allow-Origin 或者 请求通过网关代理

Springboot2 session设置超时时间无效

问题: 今天项目中遇到了一个设置时间超时的问题,按SpringBoot2的application.properties更改一直不生效。 解决方案: server.*属性用于控制Spring Boot使用的嵌入式容器 。 Spring Boot将使用ServletWebServerFactory实例之一创建servlet容器的实例。 这些类使用server.*属性来配置受控的servlet容器(tomcat,jetty等)。当应用程序作为war文件部署到Tomcat实例时, server.*属性不适用。 它们不适用,因为可以使用预先配置的servlet容器(因为它是远程运行的服务)。 因此,部署到远程Tomcat将使server.*属性无用。 1. 按照网上给的帖子更改配置文件(如果是Jar启动生效) ,如下图: server: servlet: session: timeout: PT1H # 1小时过期 cookie: max-age: PT1H # 1小时过期 说明:PT1H 意思是设置session失效的时间是1小时。 扩展:Duration 通过查看springboot源码发现setTimeouot方法,这里要求传入Duration的实例 public void setTimeout(Duration timeout) { this.timeout = timeout; } Duration是在Java8中新增的,主要用来计算日期差值,Duration是被final声明的,并且是线程安全的。 如果转换字符串方式,类似于 SimpleDateFormat 的格式化日期方式 Duration 字符串类似数字有正负之分:默认为正,负以'-'开头,下面紧接着'PT', 下面时间字母: 'D' – 天 'H' – 小时 'M' – 分钟 'S' – 秒 每个单位都必须由数字开始,且时分秒顺序不能乱,比如:PT2H3M2S 等于 -PT-2H-3M-2S。 2. 设置tomcat的session超时 1)在tomcat的conf目录下,更改servler.xml: <Context path="/abtest" docBase="/abtest" defaultSessionTimeOut="3600" isWARExpanded="

Java实现字符串表达式求值

需求说明 最近在用java写一个计算器,遇到了一个问题,获取用户输入的需要计算的表达式,因为是字符串的形式所以无法进行直接计算,所以需要写一些算法来对字符串表达式进行求值。 实现 JS实现 相信大家应该都知道JavaScript,JavaScript里面有个函数eval()可以计算某个字符串,并执行其中的JavaScript代码。虽然JavaScript名字里面有个Java,但是JavaScript和Java没什么联系的,那我上面说的这些有什么用呢? 在JDK1.6中,我们可以使用内置的JavaScript引擎,意味着我们可以使用JavavScript里面的eval()函数。 import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class OperationJS { public static void main(String[] args) throws ScriptException { ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName("JavaScript"); String foo = "(40+2)*2"; System.out.println(engine.eval(foo)); } } 使用这个要注意一个安全问题,执行的JavaScript可以访问所有Java类,因此可以无限制地劫持您的应用程序。 例如下面这句代码,将通过JavaScript将文件写入(默认情况下)程序的当前目录 engine.eval("var f = new java.io.FileWriter('hello.txt'); f.write('hello!'); f.close();"); 发现这个有点方便。秉着学习的原则,出现了实现二,用算法来解决。 栈实现 基本分析 表达式主要有括号和加减乘除四种基本运算。表达式可以看成是由一个个二元运算组成,前一个二元运算可以作为后一个二元运算的输入。 例如:“1+2+3”,可以看成是两个二元运算组成(1+2)+3,前一个二元运算过后就变成3+3,这又是一个二元运算,最后结果为6。既然都是二元运算计算,我们就可以用同一段程序来解决,递归或循环。但是我们要注意加减乘除有优先级之分。加减乘除四种运算符是有优先级的,乘法或除法同级,且比加法或减法优先级高。优先级的出现对程序的设计影响很大,例如:”1+2+3-4“=“3+3-4”=“6-4”=2,如果整个表达式都是同级的我们就可以直接从头一直运算到尾。但是因为有优先级的出现我们就不可以这样做,例如:“1+2*3-4”=“1+6-4”=“3”,我们需要先算在表达式中间的”2*3“,而不能从头的"1+2"开始算。优先级的出现让程序变的复杂了起来。括号的处理,括号就相当于在表达式里面嵌套了一个子表达式,而子表达式的优先级比括号外的其他运算优先级高。 分析可得,表达式有两个基本元素,操作数和运算符。 算法思想 操作数栈:解析表达式,采用逐个读取字符的形式,如果是操作数就入操作数栈,需要注意的是,我们是逐个读取字符,也就意味着数字"123"将分3次读取(“1”,“2”,“3”),所以需要一个追加器将字符缓存起来,当完整的读取了整个数值时在入操作数栈。运算符栈:如果是运算符就进行比较,优先级同级或低于栈顶运算符时,将触发一次二元运算,进行二元运算的为运算符栈的栈顶元素和操作数栈顶的两个元素,再把运算得到的结果入操作数栈。如果运算栈还有元素,这是一个递归操作,直到运算栈没有元素或者运算符的优先级高于栈顶元素,那么把运算符入运算符栈。继续读取表达式的下一个元素。 例如:”1+2*3-4“。 如下图所示,(6)在读取"-“时,优先级低于栈顶运算符”",触发二元运算,取出操作数栈顶元素"3"和"2"与运算符栈顶元素"“进行一次二元运算"2*3”=“6”,得到结果"6",把运算出来的结果"6"入操作数栈(6.1所示)。栈顶还有元素,继续比较,栈顶元素”+“和"-“同级,再触发二元运算,取出操作数栈顶元素"6"和"1"与运算符栈顶元素”+“进行一次二元运算"1+6”=“7”,得到结果"7",把运算出来的结果"7"入操作数栈(6.2所示)。此时运算符栈没有元素,运算符"-“入运算符栈(6.3所示)。读取下一个字符"4”,表达式已读取完毕,此时进行二元运算,直到运算符栈没有运算符,此时操作栈唯一的元素就是最后表达式计算的结果"3"(8所示)。 括号运算:相当于子表达式运算,当读取表达式字符时,读取到"(“左括号,将左括号入运算符栈,当读取到”)"右括号时,将一直运算整个子表达式的二元运算,直到遇到左括号时停止,此时把子表达式的结果入操作数栈。加减乘除左括号右括号中左括号的优先级最低,右括号的优先级最高。 例如:“1+2*(3+4)” 代码实现 import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; import java.

DPDK技术介绍(一)

DPDK是INTEL公司开发的一款高性能的网络驱动组件,旨在为数据面应用程序提供一个简单方便的,完整的,快速的数据包处理解决方案,主要技术有用户态、轮询取代中断、零拷贝、网卡RSS、访存DirectIO等。 一、主要特点 1、UIO(Linux Userspace I/O) 提供应用空间下驱动程序的支持,也就是说网卡驱动是运行在用户空间的,减下了报文在用户空间和应用空间的多次拷贝。如图:DPDK绕过了Linux内核的网络驱动模块,直接从网络硬件到达用户空间,不需要进行频繁的内存拷贝和系统调用。根据官方给出的数据,DPDK裸包反弹每个包需要80个时钟周期,而传统Linux内核协议栈每包需要2k~4k个时钟周期。DPDK能显著提升虚拟化网络设备的数据采集效率。 下图为UIO技术的工作原理图 UIO技术将设备驱动分为用户空间驱动和内核空间驱动两部分,内核空间驱动主要负责设备资源分配、UIO设备注册以及小部分中断响应函数,驱动的大部分工作在用户空间的驱动程序下完成。通过UIO框架提供的API接口将UIO的驱动注册到内核,注册完成后将生成存有设备物理地址等信息的map文件,用户态进程访问该文件将设备对应的内存空间地址映射到用户空间,即可直接操作设备的内存空间,UIO技术使得应用程序可以通过用户空间驱动直接操作设备的内存空间,避免了数据在内核缓冲区和应用程序缓冲区的多次拷贝,提供数据处理效率。 简单地说,DPDK使高速数据包网络应用程序的开发变得更快,这意味着它允许构建能够更快地处理数据包的应用程序,这多亏了内核的绕过。实际上,它使用了快速路径,而不是正常的网络层路径和上下文切换路径。包被直接传递到用户空间(作为原始包)。如下图为linux内核包处理和dpdk包处理的区别。 linux内核处理包: dpdk处理包: 下图为slow路径和fast路径比较: 2、用户空间轮询模式(PMD) 传统中断模式: 传统Linux系统中,当网络设备检测到数据帧过来的时候,会使用DMA(直接内存访问)将帧发送到预先分配好的内核缓冲区里面,然后更新相应的接收描述符环,之后产生中断通知有数据帧过来。Linux系统会进行相应的响应,然后更新相应的描述符环,再将接收到的数据帧交给内核中的网络堆栈进行处理,网络堆栈处理完之后会将相应的数据拷贝到相应的套接字,从而数据就被复制到了用户空间,应用程序就可以使用这些数据了,数据帧的接收过程如图: 在发送的时候,一旦用户程序处理完了数据,会通过一个系统调用将数据写入到套接字,将数据从用户空间拷贝到内核空间的缓冲区,交由网络堆栈进行处理,网络堆栈根据需要对数据进行封装并调用网卡设备的驱动程序,网卡设备驱动程序会更新传输描述符环,然后向网卡设备告知有数据帧需要传输。网卡设备会将数据帧从内核中的缓冲区拷贝到自己的缓冲区中并发送到网络链路上,传送到链路上之后,网卡设备会通过一个中断告知成功发送,然后内核会释放相应的缓冲区。数据的发送如图: 由于linux系统是通过中断的方式告知CPU有数据包过来的,当网络的流量越来越大,linux系统会浪费越来越多的时间去处理中断,当流量速率达到10G的时候,linux系统可能会被中断淹没,浪费很多CPU资源。 DPDK用户空间的轮询模式驱动:用户空间驱动使得应用程序不需要经过linux内核就可以访问网络设备卡。网卡设备可以通过DMA方式将数据包传输到事先分配好的缓冲区,这个缓冲区位于用户空间,应用程序通过不断轮询的方式可以读取数据包并在原地址上直接处理,不需要中断,而且也省去了内核到应用层的数据包拷贝过程。 因此相对于linux系统传统中断方式,Intel DPDK避免了中断处理、上下文切换、系统调用、数据复制带来的性能上的消耗,大大提升了数据包的处理性能。同时由于Intel DPDK在用户空间就可以开发驱动,与传统的在内核中开发驱动相比,安全系数大大降低。因为内核层权限比较高,操作相对比较危险,可能因为小的代码bug就会导致系统崩溃,需要仔细的开发和广泛的测试。而在应用层则相反,比较安全,且在应用层调试代码要方便的多。 3、大页内存 Linux操作系统通过查找TLB来实现快速的虚拟地址到物理地址的转化。由于TLB是一块高速缓冲cache,容量比较小,容易发生没有命中。当没有命中的时候,会触发一个中断,然后会访问内存来刷新页表,这样会造成比较大的时延,降低性能。Linux操作系统的页大小只有4K,所以当应用程序占用的内存比较大的时候,会需要较多的页表,开销比较大,而且容易造成未命中。相比于linux系统的4KB页,Intel DPDK缓冲区管理库提供了Hugepage大页内存,大小有2MB和1GB页面两种,可以得到明显性能的提升,因为采用大页内存的话,可以需要更少的页,从而需要更少的TLB,这样就减少了虚拟页地址到物理页地址的转换时间。‘ DPDK中的内存管理如图,最下面是连续的物理内存,这些物理内存是由2MB的大页组成,连续的物理内存上面是内存段,内存段之上则是内存区,我们分配的基本单元对象是在内存区中分配的,内存区包含了ring队列,内存池、LPM路由表还有其他一些高性能的关键结构。 4、CPU亲和性 CPU的亲和性(CPU affinity),它是多核CPU发展的结果。随着核心的数量越来越多,为了提高程序工作的效率必须使用多线程。但是随着CPU的核心的数目的增长,Linux的核心间的调度和共享内存争用会严重影响性能。利用Intel DPDK的CPU affinity可以将各个线程绑定到不同的cpu,可以省去来回反复调度带来的性能上的消耗。 在一个多核处理器的机器上,每个CPU核心本身都存在自己的缓存,缓冲区里存放着线程使用的信息。如果线程没有绑定CPU核,那么线程可能被Linux系统调度到其他的CPU上,这样的话,CPU的cache命中率就降低了。利用CPU的affinity技术,一旦线程绑定到某个CPU后,线程就会一直在指定的CPU上运行,操作系统不会将其调度到其他的CPU上,节省了调度的性能消耗,从而提升了程序执行的效率。 多核轮询模式:多核轮询模式有两种,分别是IO独占式和流水线式。IO独占式是指每个核独立完成数据包的接收、处理和发送过程,核之间相互独立,其优点是其中一个核出现问题时不影响其他核的数据收发。流水线式则采用多核合作的方式处理数据包,数据包的接收、处理和发送由不同的核完成。流水线式适合面向流的数据处理,其优点是可对数据包按照接收的顺序有序进行处理,缺点是当某个环境(例如接收)所涉及的核出现阻塞,则会造成收发中断。 IO独占式多核轮询模式中每个网卡只分配给一个逻辑核进行处理。每个逻辑核给所接管的网卡分别分配一个发送队列和一个接收队列,并且独立完成数据包的接收、处理和发送的过程,核与核之间相互独立。系统数据包的处理由多个逻辑核同时进行,每个网卡的收发包队列只能由一个逻辑核提供。当数据包进入网卡的硬件缓存区,用户空间提供的网卡驱动通过轮询得知网卡收到数据包,从硬件缓冲区中取出数据包,并将数据包存入逻辑核提供的收包队列中,逻辑核取出收包队列中的数据包进行处理,处理完毕后将数据包存入逻辑核提供的发包队列,然后由网卡驱动取出发往网卡,最终发送到网络中。 IO独占式多核轮询模式架构图: 5、内存池和无锁环形缓存管理 此外Intel DPDK将库和API优化成了无锁,比如无锁队列,可以防止多线程程序发生死锁。然后对缓冲区等数据结构进行了cache对齐。如果没有cache对齐,则可能在内存访问的时候多读写一次内存和cache。 内存池缓存区的申请和释放采用的是生产者-消费者模式无锁缓存队列进行管理,避免队列中锁的开销,在缓存区的使用过程中提高了缓冲区申请释放的效率。 无锁环形队列生产过程: 无锁环形队列消费过程: 如图所示,生产者往队列里存放内容的方向和消费者从队列里取内容的方向一致,均以顺时针方向进行。当缓存区向内存池申请内存块,或者应用程序进行内存块的释放时,缓存区的无锁环形队列的生产者指针顺时针移动,往队列中存入内存块地址信息,进行缓存队列的生产过程。当应用程序需要向缓冲区申请内存块使用时,缓冲区的无锁环形队列的消费者指针以顺时针的方向取出队列的内存块地址,分配给应用程序使用,该过程为缓存队列的消费过程。 生产n个对象过程:首先生产者头指针往顺时针方向移n个位置获得新的头指针,然后从生产者尾指针指的区域开始逐个存入n个对象,最后生产者尾指针顺时针移动n个位置获得新的生产者尾指针 消费n个对象过程:首先消费者头指针顺时针移动n个位置获得新的消费者头指针,然后从消费者尾指针处开始逐个读取n个对象,最后消费者尾指针顺时针移动n个位置获得新的消费者尾指针。 6、网络存储优化 二、架构与核心组件 1、 DPDK总体架构 2、核心组件 DPDK主要有六个核心组件 1、 环境抽象层(EAL):为DPDK其他组件和应用程序提供一个屏蔽具体平台特性的统一接口,环境抽象层提供的功能主要有:DPDK加载和启动;支持多核和多线程执行类型;CPU核亲和性处理;原子操作和锁操作接口;时钟参考;PCI总线访问接口;跟踪和调试接口;CPU特性采集接口;中断和告警接口等。 2、 堆内存管理组件(Malloc lib):堆内存管理组件为应用程序提供从大页内存分配对内存的接口。当需要分配大量内存小块时,使用这些接口可以减少TLB缺页。 3、 环缓冲区管理组件(Ring lib):环缓冲区管理组件为应用程序和其他组件提供一个无锁的多生产者多消费者FIFO队列API:Ring。Ring是借鉴了Linux内核kfifo无锁队列,可以无锁出入对,支持多消费/生产者同时出入队。 4、 内存池管理组件(Mem pool lib):为应用程序和其他组件提供分配内存池的接口,内存池是一个由固定大小的多个内存块组成的内存容器,可用于存储相同对象实体,如报文缓存块等。内存池由内存池的名称来唯一标识,它由一个环缓冲区和一组核本地缓存队列组成,每个核从自己的缓存队列分配内存块,当本地缓存队列减少到一定程度时,从内存缓冲区中申请内存块来补充本地队列。 5、 网络报文缓存块管理组件(Mbuf lib):提供应用程序创建和释放用于存储报文信息的缓存块的接口,这些MBUF存储在内存池中。提供两种类型的MBUF,一种用于存储一般信息,一种用于存储报文信息。 6、 定时器组件(Timer lib):提供一些异步周期执行的接口(也可以只执行一次),可以指定某个函数在规定的时间异步的执行,就像LIBC中的timer定时器,但是这里的定时器需要应用程序在主循环中周期调用rte_timer_manage来使定时器得到执行。定时器组件的时间参考来自EAL层提供的时间接口。 除了以上六个核心组件外,DPDK还提供以下功能: 1) 以太网轮询模式驱动(PMD)架构:把以太网驱动从内核移到应用层,采用同步轮询机制而不是内核态的异步中断机制来提高报文的接收和发送效率。

HIVE使用时的问题记录

hive的字段名约束 HIVE默认是不能使用保留字(如:date)以及含有一些特殊符号(比如以_开头)作为表 的字段名的,但有时候因为特殊需求无法对字段名进行校验或更名的情况可以在建表时, 可以将某个字段用``(tab上面那个键)符号进行转义,HIVE会将所有被这种符号包裹的 字段仅作为字面量进行识别,从而避免了无法使用特殊名称的问题。 insert和load的区别 insert和load操作都可以将数据导入到hive表中,但load操作仅能从文件 系统中导入数据,是简单的copy/move操作,不涉及到任何数据格式转换,如果待导入的 文件格式与导入的HIVE表格式不一致,则会失败。其语法格式为: LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] insert操作可以将某个查询语句的查询结果作为导入数据导入到某张HIVE表中,如果 数据格式不一致,HIVE会尝试执行转换,常用的语法格式为: INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement; 如果想实现将HDFS中的文本数据(txt)导入到HIVE表中,并采用其它格式存储来提升存储 效率和查询性能,比如:parquet,可以采用如下步骤: 建立一张临时表t_temp存储格式使用TEXTFILE(STORED AS TEXTFILE);使用load操作将原始文件导入到该临时表中;建立正式的存储表t_data采用parquet存储格式(STORED AS parquet)使用insert语法将临时表数据导入正式表: INSERT INTO TABLE t_data select * from t_temp; hive的超时时间 如果采用JDBC的方式连接hive,一般会采用长连接的形式,但hive内部默认了每个连接 的不活动session的超时失效时间,一旦session失效后还想尝试使用,会发生:HiveSQLException: Invalid SessionHandle错误。 Hive的Session的超时时间主要受以下三个参数的影响(): hive.server2.session.check.interval #检查session超时的间隔时间 hive.server2.idle.operation.timeout #session中某个操作最长的空闲时间,比如执行一个SQL,单位毫秒 hive.server2.idle.session.timeout #session最长的空闲时间,超过将被关闭,单位毫秒 一般来讲如果想让session永不超时,只需设置hive.server2.idle.session.timeout=0即可。

阿里云Code(code.aliyun)提交代码时报错fatal: Authentication failed for‘https://code.aliyun.com/...‘身份验证失败

阿里云Code(code.aliyun)提交代码时报错fatal: Authentication failed for’https://code.aliyun.com/…'身份验证失败,是因为阿里云登录的用户名、密码和code.aliyun的用户名、密码不是同一个。 用户名: 链接:https://code.aliyun.com/profile 如果以前没有设置过code.aliyun的密码,那密码就是空的,点击“忘记私人令牌”重新设置密码即可。 链接:https://code.aliyun.com/profile/password/edit

springboot项目application配置

启动配置 要加"m"说明是MB,否则就是KB了 -Xms:初始值 -Xmx:最大值 -Xmn:最小值 java -Xms10m -Xmx80m -jar mod.jar & 时区设置 java -jar -Duser.timezone=GMT+08 mod.jar & springboot启动项目配置文件加载顺序 /config, / , classpath:/config,classpath: 找到后不再继续查找 2.核心属性 2.1 BANNER banner.charset = UTF -8#横幅文件编码。 banner.location = classpath :banner.txt#横幅文件位置。 2.2 LOGGING logging.config =#日志记录配置文件的位置。例如对于Logback的“classpath:logback.xml” logging.exception-conversion-word =%wEx#记录异常时使用的转换字。 logging.file =#日志文件名。例如myapp.log logging.level。* =#日志级别严重性映射。例如logging.level.org.springframework = DEBUG logging.path =#日志文件的位置。例如/ var / log logging.pattern.console =#输出到控制台的Appender模式。仅支持默认logback设置。 logging.pattern.file =#输出到文件的Appender模式。仅支持默认logback设置。 logging.pattern.level =#日志级别的Appender模式(默认为%5p)。仅支持默认logback设置。 logging.register-shutdown-hook = false #在初始化时为日志系统注册一个关闭挂接。 2.3 AOP spring.aop.auto = true #添加@EnableAspectJAutoProxy。 spring.aop.proxy-target-class = false #是否要创建基于子类(CGLIB)的代理(true),而不是基于标准Java接口的代理(false)。

UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "

最近用AndroidStudio运行第三方的程序时,报错如下: UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/???-QUG_RcfyVOxgMrAQFCb10g==/base.apk"],nativeLibraryDirectories=[/data/app/???-QUG_RcfyVOxgMrAQFCb10g==/lib/arm64, /system/lib64, /system/product/lib64, /hw_product/lib64, /system/product/lib64]]] couldn't find "libBarcode.so" 解决方法: 在build.gradle中加入: android { splits { abi { enable true reset() include 'x86', 'x86_64', 'armeabi-v7a', 'armeabi' universalApk false } } }

基于STM32CubeMX移植freeModbusRTU(从站)

困惑了将近一年多的ModbusRTU在我昨天穷极无聊给自己定目标的情况下搞出来了,以前移植不出来主要原因就是基本功不扎实,没有进一步理解串口和定时器配置的原理,一通操作,移植完之后就Timeout,接下来就分享一下我是怎么从0开始移植这个协议的。 项目已上传码云,文章底部有链接! 1.需要的材料 STM32开发板一块,不限型号freeModbus包可进入后方链接下载(Modbus官方源码包)STM32CubeMX 2.操作步骤 操作之前先讲两个主要问题 1.串口设置问题 MoubusRTU移植到stm32平台通信是通过串口进行通信,主要是需要串口进行收发,所以发送中断时必须的,在波特率设置问题上是和定时器相关联,在mbrtu.c文件的eMBRTUInit函数里具体说明了串口波特率和定时器设置的关系 eMBErrorCode eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) { eMBErrorCode eStatus = MB_ENOERR; ULONG usTimerT35_50us; ( void )ucSlaveAddress; ENTER_CRITICAL_SECTION( ); /* Modbus RTU uses 8 Databits. */ if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE ) { eStatus = MB_EPORTERR; } else { /* If baudrate > 19200 then we should use the fixed timer values * t35 = 1750us.

linux基础教程-黑马程序员汇总PDF

linux基础教程-黑马程序员汇总PDF 目标 明确基础班课程内容 课程清单 序号 内容 目标 01 Linux 基础 让大家对 Ubuntu 的使用从很 陌生 达到 灵活操作 02 Python 基础 涵盖 Python 基础知识,让大家掌握基础的编程能力 03 Python 面向对象 介绍 Python 的面相对象开发, 为开发大型项目做好铺垫和准备 04 项目实战 应用基础班学习过的知识,编程实战,完成第一个 Python 项目 分享 Python 基础课程安排 目标 了解操作系统及作用 操作系统(Operation System,OS) 1.1 操作系统的作用 操作系统(科普章节) 操作系统作为接口的示意图 没有安装操作系统的计算机,通常被称为 裸机 如果想在 裸机 上运行自己所编写的程序,就必须用机器语言书写程序 如果计算机上安装了操作系统,就可以在操作系统上安装支持的高级语言 环境,用高级语言开发程序 是现代计算机系统中 最基本和最重要 的系统软件 是 配置在计算机硬件上的第一层软件,是对硬件系统的首次扩展 主要作用是管理好硬件设备,并为用户和应用程序提供一个简单的接口,以便于使用 而其他的诸如编译程序、数据库管理系统,以及大量的应用软件,都直接依赖于操作系统的 支持 1.2 不同应用领域的主流操作系统 桌面操作系统 服务器操作系统 嵌入式操作系统 移动设备操作系统 1> 桌面操作系统 Windows 系列

Node js 四种异步处理方法

//node.js里面的非阻塞IO 和阻塞IO //异步处理 //事件驱动 //其他的后端语言会使用多线程进行多线程处理 //nodejs 是单线程,优势是非阻塞io 一个服务员同时满足多个客户的需求 //一个简单的例子 //多个文件读取 //异步处理 //1 使用回调函数处理 let http = require('http'); let fs = require('fs'); let events = require('events');//引入事件驱动模块 //创建事件驱动对象 let eventEmit = new events.EventEmitter();//new 完对象之后就可以使用emit(发布订阅)(后发布) on(监听订阅)(先监听) http.createServer((req, res) => { if (req.url == "/") { res.writeHead(200, "Content-Type:text/html;charset=utf-8;"); //使用异步代码 //fs.readFileSync('stu.txt')//同步代码 阻塞io //非阻塞 //使用回调函数处理异步 function getData(callback) { fs.readFile('stu.txt', (err, data) => { if (err) { throw err; } callback(data.toString()); }); } //在外边获取读取的数据 getData((result) => { console.

BigDecimal去掉小数点后无用的0

如题:BigDecimal去掉小数点后无用的0 比如:数据库存储的是Decimal(5,2)类型保留两位数。 如果展示数据5.00,5.10等字样感觉很不爽,如何做呢? 只战术5和5.1 解决:BigDecimal,有方法解决stripTrailingZeros() 看源码: /** * Returns a string representation of this {@code BigDecimal} * without an exponent field. For values with a positive scale, * the number of digits to the right of the decimal point is used * to indicate scale. For values with a zero or negative scale, * the resulting string is generated as if the value were * converted to a numerically equal value with zero scale and as * if all the trailing zeros of the zero scale value were present * in the result.

用Python画中国地图,实现各省份数据可视化!可视化简直了!

第一步:安装pyecharts pyecharts是一款将python与echarts结合的强大的数据可视化工具,本文使用了0.1.9.4版本 pip install pyecharts==0.1.9.4 第二步:读取数据 我的数据是在Excel表格里,如下图: Execel数据 使用xlrd(没有就通过pip install xlrd安装)读取Excel表格中的数据 # 第一种方式,使用xlrd读取Execel表格中数据 data = xlrd.open_workbook('data.xlsx') table = data.sheet_by_name('Sheet1') province = table.col_values(0)[1:] num = table.col_values(1)[1:] 如果各位没有相应的Execel文件,也不想新建一个,那就干脆自己定义一个字典,其中键是省份,值是对应的数量,然后再把对应的值取出来 # 第二种方式,直接自己写一个字典,然后取出相应数据 province_distribution = {'四川': 239.0, '浙江': 231.0, '福建': 203.0, '江苏': 185.0, '湖南': 152.0, '山东': 131.0, '安徽': 100.0, '广东': 89.0, '河北': 87.0, '湖北': 84.0, '吉林': 75.0, '上海': 70.0, '江西': 64.0, '广西': 64.0, '贵州': 64.0, '北京': 63.0, '云南': 53.0, '重庆': 49.0, '河南': 48.0, '陕西': 38.

mybatis xml if 判断为空

1.判断集合是否为空 @Ognl@isNotEmpty可以用来判断集合,字符串是否为空 <if test="partAttributeList != null and partAttributeList.size > 0"> 或者<if test="@Ognl@isNotEmpty(partAttributeList)"> 2.判断字符串是否为空 <if test="attributeValueId != null and attributeValueId != '' "> 或者 <if test="@Ognl@isNotEmpty(attributeValueId)"> boolean 类型的判断 -- hasRelated是boolean类型 -- 方案一 <if test="hasRelated != null and 'true'.toString() == hasRelated.toString()"> --方案二 即使是包装类型Boolean,也不需要判断null的问题 <if test="hasRelated"> 模糊查询连接 name like concat('%', #{name}, '%'); 自定义Ognl类: import java.lang.reflect.Array; import java.util.Collection; import java.util.Map; public class Ognl { public Ognl() { } public static boolean isEmpty(Object o) throws IllegalArgumentException { if (o == null) { return true; } else { if (o instanceof String) { if (((String) o).

Maven如何手动添加依赖的jar文件到本地Maven仓库

大家肯定遇到过想在pom文件中加入自己开发的依赖包,这些包肯定是不是在Maven仓库(http://repo1.maven.org/maven2/)的。那我们怎么将那些不存在Maven仓库中的包加入到本地的Maven库中呢?很简单。这里以IKAnalyzer.jar包为例进行讲解。 第一步:将IKAnalyzer.jar包存放在一个文件夹中,比如mylib文件夹 第二步:建一个IKAnalyzer.jar包相关的pom.xml文件,需要在pom.xml中定义其maven坐标及其相应的依赖代码即可,同样将pom文件存放在上述jar文件同一文件夹下,IKAnalyzer.jar坐标及依赖代码的pom.xml文件内容如下: <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>org.wltea.ik-analyzer</groupId> <artifactId>ik-analyzer</artifactId> <version>3.2.8</version> <name>IK Analyzer 3</name> <description>A dictionary and grammar-based Chinese segmenter</description> <dependencies> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>3.0.3</version> <optional>true</optional> </dependency> <dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-core</artifactId> <version>1.4.1</version> <optional>true</optional> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-analyzers</artifactId> <version>3.0.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-smartcn</artifactId> <version>3.0.3</version> <scope>test</scope> </dependency> </dependencies> </project> 第三步:打开CMD,进入到mylib文件夹,运行下面命令(不要换行,用空格) mvn install:install-file -Dfile=IKAnalyzer3.2.8.jar -DgroupId=org.wltea.ik-analyzer -DartifactId=ik-analyzer -Dversion=3.2.8 -Dpackaging=jar 这样你就可以将IKAnalyzer3.2.8.jar安装到您Maven本地的库文件夹相应目录中。你可以根据你需要安装包的实际情况修改上面的几个参数的设定值即可。之后你可以在pom.xml文件中通过以下依赖在项目中引入上述的包,如下: 当然你也可以不将IKAnalyzer3.2.8.jar发布到您本地的Maven库中,而是通过下面配置引入,效果和上面的差不多: org.wltea IKAnalyzer 3.2.8 C:\Users\yangping\Desktop\a\IKAnalyzer3.2.8.jar 不要依赖的jar加入本地仓库示例:

sys标准输出sys.stdout

sys.stdout输出重定向 一般用于QT或想输出写入文件 class EmittingStr(QObject): textWritten = pyqtSignal(str) # 定义一个发送str的信号 def write(self, text): self.textWritten.emit(str(text)) sys.stdout = EmittingStr(textWritten=self.outputWritten_ip_c) sys.stderr = EmittingStr(textWritten=self.outputWritten_ip_c) def outputWritten_ip_c(self, text): cursor = self.textEdit_ip_c2.textCursor() cursor.movePosition(QtGui.QTextCursor.End) cursor.insertText(text) self.textEdit_ip_c2.setTextCursor(cursor) self.textEdit_ip_c2.ensureCursorVisible() importlib.reload(sys) reload的作用,重新加载sys,清空缓存区,避免重复输出

Visual Studio 2015安装使用方法

Visual Studio 2015 安装步骤装载镜像安装过程 开发环境启动注册项目创建程序运行 安装步骤 装载镜像 下载之后的文件是.iso格式的镜像,Windows 8/10都能够双击装载镜像,而Windows 7不能直接装载,可以使用解压软件对.iso文件进行解压。 以双击方式装载,会直接进入镜像文件夹。也可以右击镜像,在右键菜单中选择装载,之后调出文件资源管理器,找到装载之后的虚拟盘,双击虚拟盘,进入文件夹。如果是解压.iso文件,进入解压之后的文件夹。 若不知如何打开文件资源管理器,请参看另一篇博文: https://blog.csdn.net/xucongyoushan/article/details/86018253 安装过程 双击执行setup.exe安装程序,弹出如下图所示的准备界面: 之后出现如下图所示的初始化安装界面: 如果你的计算机配置不恰当,VS2015安装程序会给出如下图所示的警告。 这里出现该警告是由于电脑没有安装IE10。可以忽略该警告,点击继续。 选择安装位置以及安装类型。这里已经把VS2015的安装位置选择为D:\Programe Files\Microsoft Visual Studio 2015。 可以使用默认路径,安装在C盘,也可以安装到指定位置。 安装类型选择自定义,不选择默认值,默认值并没有包含C/C++相关组件。如下图所示: 无论Visual Studio的安装位置修改与否,其核心组件都会装在C盘。 选择安装组件。若只是用于编写C/C++程序,只需勾选编程语言的Visual C++。其它组件根据个人需要选择安装,把用不着的组件取消勾选,之后点击下一步。如下图所示: 弹出如下图所示的确认对话框,点击安装按钮开始安装。 进入如下图所示的安装过程界面,正在获取和应用组件。这个过程根据计算机配置和系统状态,安装所用时间不同,快则只用10分钟左右,慢则需要1小时左右。 安装完毕之后,弹出如下图所示的安装完成界面,点击启动按钮,首次运行VS2015。 这时或许会提示重新启动系统,点击立即重新启动按钮,若没有提示,忽略此步骤。 开发环境 启动 Visual Studio安装之后,不会自动在桌面创建快捷方式。其启动方式,在不同版本的Windows平台上,展示形式略微有些差别。 调出开始菜单,在所有程序中寻找Visual Studio 2015,找到之后点击即可启动VS2015开发环境。 若不知如何调出开始菜单,请参看另一篇博文: https://blog.csdn.net/xucongyoushan/article/details/86020424 首次使用VS2015还需要进行简单配置。出现如下图所示的欢迎界面,如果有微软账号,可以直接登录,也可以点击以后再说,跳过登录步骤。 接着选择环境配置,主要包括开发环境和主题风格。若使用VS2015进行C/C++程序开发,选择Visual C++。至于颜色主题,用户可根据自己的喜好选择。之后点击启动Visual Studio,如下图所示: 第一次启动会进行准备过程,需要等待一段时间,如下图所示: 出现如下图所示的主界面,打开VS2015开发环境成功。有关此集成平台相关菜单项、功能及其它使用等,请参见官方提供的帮助文档。 虽然Visual Studio没有自动创建桌面快捷方式,但是可以在其第一次启动后,右击任务栏的Visual Studio图标,弹出右键菜单,选择将此程序固定到任务栏。这样,下一次直接点击任务栏上的图标即可打开Visual Studio。 注册 Visual Studio需要注册激活,否则有试用期限限制。 VS2015与VS2013注册步骤相似,详情参看Visual Studio 2013,在其目录中,点击注册。 项目创建 VS2015与VS2013项目创建的步骤相似,详情参看Visual Studio 2013,在其目录中,点击项目创建。 程序运行 VS2015与VS2017编译和运行程序的方法一样,详情参看Visual Studio 2017,在其目录中,点击程序运行。

小程序 返回顶部

<!-- 固定按钮 --> <image class="fixd-top {{showtop?'showtoppic':''}}" src="../../images/icon/top.png" bindtap="goTop"></image> .fixd-top { width: 88rpx; height: 88rpx; display: block; position: fixed; bottom: 60rpx; opacity: 0; right: -600rpx; transition: all 0.8s ease-in-out; z-index: 22; } .showtoppic { opacity: 1; right: 54rpx; transition: all 0.6s ease-in-out; } data:{ showtop: false, //返回顶部 } // 页面滚动 onPageScroll(e) { if (e.scrollTop >= 110) { this.setData({ showtop: true }) } else { this.setData({ showtop: false }) } },

大数据技术原理与应用——NoSQL数据库

大数据技术原理与应用——NoSQL数据库 5.1 NoSQL 简介 特点 1.灵活的可扩展性 传统的关系型数据库由于自身设计机理的原因,通常很难实现“横向扩展”,在面对数据库负载大规模增加时,往往需要通过升级硬件来实现“纵向扩展”。但是,当前的计算机硬件制造工艺已经达到一个限度,性能提升的速度开始趋缓,已经远远赶不上数据库系统负载的增加速度,而且配置高端的高性能服务器价格不菲,因此寄希望于通过“纵向扩展”满足实际业务需求,已经变得越来越不现实。相反,“横向扩展”仅需要非常普通廉价的标准化刀片服务器,不仅具有较高的性价比,也提供了理论上近乎无限的扩展空间。NoSQL 数据库在设计之初就是为了满足“横向扩展”的需求,因此天生具备良好的水平扩展能力。 2.灵活的数据模型 关系模型是关系数据库的基石,它以完备的关系代数理论为基础,具有规范的定义,遵守各种严格的约束条件。这种做法虽然保证了业务系统对数据一致性的需求,但是过于死板的数据模型,也意味着无法满足各种新兴的业务需求。相反,NoSQL 数据库天生就旨在摆脱关系数据库的各种束缚条件,摈弃了流行多年的关系数据模型,转而采用键/值、列族等非关系模型,允许在一个数据元素里存储不同类型的数据。 3.与云计算紧密融合 云计算具有很好的水平扩展能力,可以根据资源使用情况进行自由伸缩,各种资源可以动态加入或退出,NoSQL 数据库可以凭借自身良好的横向扩展能力,充分自由利用云计算基础设施,很好地融入到云计算环境中,构建基于 NoSQL 的云数据库服务。 5.2 NoSQL 兴起的原因 5.2.1 关系数据库无法满足 Web 2.0 的需求 传统的关系数据库性能上缺陷 无法满足海量数据的管理需求 到了 Web 2.0 时代以后,数据的产生速度非常快 无法满足高并发的需求 在 Web 1.0 时代,通常采用动态页面静态化的技术,事先访问数据库生成静态页面供浏览者访问,从而保证在大规模用户访问时,也能够获得较好的实时响应性能。但是,在 Web 2.0 时代,各种用户都在不断地发生更新,购物记录、搜索记录、微博粉丝数等信息都需要实时更新,动态页面静态化技术基本没有用武之地,所有信息都需要动态实时生成,这就会导致高并发的数据库访问,可能产生每秒上万次的读写请求,对于很多关系数据库而言,这都是“难以承受之重”。 无法满足高扩展性和高可用性的需求 在 Web 2.0 时代,不知名的网站可能一夜爆红,用户迅速增加,已经广为人知的网站也可能因为发布了热门吸引眼球的信息,引来大量用户在短时间内围绕该信息大量交流互动,这些都会导致对数据库读写负荷的急剧增加,需要数据库能够在短时间内迅速提升性能应对突发需求。但是,遗憾的是,关系数据库通常是难以水平扩展的,没有办法像网页服务器和应用服务器那样简单地通过添加更多的硬件和服务节点来扩展性能和负载能力。 5.2.2 关系数据库的关键特性在 Web 2.0 时代成为“鸡肋” 5.3 NoSQL 与关系数据库的比较 一、在数据库原理方面 二、在数据规模方面 三、在数据库模式方面 四、在查询效率方面 五、在事务一致性方面 六、在数据完整性方面 七、在可扩展性方面 八、在可用性方面 九、在标准化方面 十、在技术支持方面 十一、在可维护方面 关系数据库的优势 1.具有非常完备的关系代数理论作为基础 2.有严格的标准 3.支持事务一致性 4.可以借助索引机制实现非常高效的查询 关系数据库的劣势 1.可扩展性非常差

小程序 自定义switch 按钮上文字显示

<view class="switch" > <view class="switchNums {{_num == 0?'currentNum':''}}" bindtap="switchChange" data-index="0">{{selectOpen[0]}} </view> <view class="switchNums {{_num == 1?'currentNum':''}}" bindtap="switchChange" data-index="1">{{selectOpen[1]}} </view> </view> data:{ selectOpen:["展开","收起"], _num:0, } js switchChange(_ref) { var currentTarget = _ref.currentTarget; var tab = currentTarget.dataset.index; if (tab == "0") { this.setData({ _num:0, }) } else { this.setData({ _num:1, }) } }, css .switch { display: flex; align-items: center; justify-content: flex-end; height: 54rpx; border-radius: 54rpx; background: #f7f7fb; } .switchNums {

linux下在线安装mysql

找了好多文章,都是表里不一,我想打人。。。啊哈哈哈 我是安装了mysql 5.6版,详细操作如下: 第一步:需要卸载mariadb,否则安装mysql会出现冲突。 首先执行命令rpm -qa | grep mariadb命令,列出所有被安装的mariadb rpm 包,然后执行命令rpm -e --nodeps mariadb-libs-5.5.56-2.el7.x86_64,最后就能删除。 第二步:添加官方的yum源,并编辑mysql-community.repo文件 首先自行:vi /etc/yum.repos.d/mysql-community.repo #若没有文件,该命令会自动新建文件 然后黏贴如下内容: [mysql56-community] name=MySQL 5.6 Community Server baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/7/$basearch/ enabled=1 gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql 注意:如果需要安装mysql5.7 只需要将baseurl修改即可,如: baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/ 接下来直接安装mysql数据库: 执行:sudo yum install mysql-community-server 启动mysql数据库: 执行:sudo service mysqld start 最后,修改mysql默认的root用户密码: 执行:mysqladmin -u root -p password ,回车后输入新密码以及再次确认密码,这时候就完成了,注:mysql5.7的初始密码是随机生成的,放在了 /var/log/mysqld.log使用命令 grep ‘temporary password’ /var/log/mysqld.log 读出来即可。 远程登录时,执行mysql –u root –p,回车后输入自己设置的新密码登录即可。

Java项目和Web项目的区别

Java Web项目是基于Java EE类的;而Java项目是基于Java应用程序的。 Java项目主要面向桌面程序的应用,主要是awt、swing这类的编码,不包括JSP等前台页面的代码,大部分是CS架构的工程和一些jar包。 JavaWeb项目是BS架构的系统,是网页的编码,像Jsp、Servlet、Struts这类的, JavaWeb项目部署到服务器上,任何用户都可以通过浏览器来访问。 JavaWeb项目中的Java文件是tomcat服务器来触发的,脱离了web服务器就无法启动。而Java项目是由main()方法来开始的,直接依赖JVM就能被编译执行。 Java Web项目需要服务器;而Java项目不需要服务器。 在eclipse中Java Web项目可以转换为Java项目,进而可以转回到Java Web项目。 Java项目多数应用请求响应通过按钮的事件驱动来发起(Web项目也有)。JavaWeb项目衍生了很多框架应用。多数请求响应应用超链接URL来发起(Java项目也有)。 如果说Java项目代码多半在本地,Web项目的代码基本是在远程服务端。当你是Web应用时,比如要建个网站,需要发布到服务器时,应为JavaWeb项目。当你做分布式系统时,也就是你做的只是一个服务,对外发布也只是一个服务的时候,需要建立Web Services Project(不理解可以先研究下webservices)。当你仅仅是需要JDK来运行一些本地代码的时候,只需要建Java Project就可以了。

菜鸟学Linux命令:ssh命令

转载自品略图书馆 http://www.pinlue.com/article/2020/04/1003/1210139769049.html 1、查看SSH客户端版本 有的时候需要确认一下SSH客户端及其相应的版本号。使用ssh -V命令可以得到版本号。需要注意的是,Linux一般自带的是OpenSSH: 下面的例子即表明该系统正在使用OpenSSH: 1 2 $ ssh -V OpenSSH_3.9p1, OpenSSL 0.9.7a Feb 19 2003 下面的例子表明该系统正在使用SSH2: 1 2 $ ssh -V ssh: SSH Secure Shell 3.2.9.1 (non-commercial version) on i686-pc-linux-gnu 2、连接到远程主机: 命令格式 : 1 2 ssh name@remoteserver #或者 ssh remoteserver -l name 说明:以上两种方式都可以远程登录到远程主机,server代表远程主机,name为登录远程主机的用户名。 3、连接到远程主机指定的端口: 命令格式: 1 2 ssh name@remoteserver -p 2222 #或者 ssh remoteserver -l name -p 2222 说明:p 参数指定端口号,通常在路由里做端口映射时,我们不会把22端口直接映射出去,而是转换成其他端口号,这时就需要使用-p端口号命令格式。 4、通过远程主机1跳到远程主机2: 命令格式: 1 ssh -t remoteserver1 ssh remoteserver2

python3.7 安装dlib和face_recognition

最近想做一个有关人脸识别的项目,想先用face_recognition试试手,毕竟是号称最简单的人脸识别库了,但是在安装的时候会有各种报错,间断性的忙活了两天,终于搞定了,记一篇笔记以供后来者。 首先说一下我的环境,目前我使用的是Anaconda3和pycharm。 主要参考了这篇博文: python-----windows下安装face_recognition库 一、安装visual Studio 首先安装一个VisualStudio,后期编译dlib什么的需要这个环境。 可以通过这个链接直达官网 VIsualStudio官网 在官网点击安装,下下来一个VisualStudio Installer。我这里已经安装好了,选的是Community版本。 选择了python开发和C++的桌面开发两个工作负载。好像C++桌面开发里面已经包含有Cmake了呢 我这边的下载是到达98%以后速度就会很慢,几乎停止,但是慢慢等总会下好的。 二、安装boost 进入下面的链接,可以到达boost下载官网 boost官网 点击蓝色框内链接,下载安装包。 打开cmd,通过cd命令进入到boost文件夹中, 输入bootstrap.bat 如果一切正常,原文件夹中会多出一个.exe的文件 而后在cmd中输入.\b2 回车 一番等待以后,(网上说法十几分钟到半小时不等)(作者本人是摆着让它自己编译然后睡觉去了,并不知道编译了多久) 出现以下提示,即证明boost已经安装好了 三、通过pip安装cmake,dlib和face_recognition 根据普通的教程,此时应该去Cmake官网安装Cmake,安装过程和boost类似。但是我发现在安装visual时已经有顺便安装了Cmake,于是就胆大心细直接打开cmd,输入pip install dlib 居然直接安装dlib成功,图中因为我已经安装好,所以没有显示安装过程。 如果dlib安装不成功,建议还是再单独下一个Cmake,链接如下 https://cmake.org/download/ 安装好dlib后,直接pip install face_recognition 即可安装好face_recognition。 参考文章: https://www.cnblogs.com/xiaodai0/p/10703803.html 另外,在网上有看到说法说是dlib只支持python3.6,所以python3.7可能不可以直接pip安装,我这里没什么问题(也可能是之前瞎捣鼓的时候凑巧弄好了) 这里附上一篇把Anaconda环境里python3.7虚拟为python3.6的解决方法: https://blog.csdn.net/fu6543210/article/details/87878142

requests的代理的设置

在爬虫运行的时候,有时候会出现403 Forbidden的情况,也就是我们的访问次数超过了目标网站设置的阈值,这样它就会直接拒绝服务,返回一些错误信息,也就是所谓的封IP。 接下来我们尝试基于requests的代理的设置: requests 的代理设置比 urllib 简单很多,它只需要构造代理字典,然后通过 proxies 参数即可,而不需要重新构建 Opener。 代码如下: import requests proxy = '113.194.28.190:9999' proxies = { 'http': 'http://' + proxy, 'https': 'https://' + proxy } try: response = requests.get('http://httpbin.org/get', proxies=proxies) print(response.text) except requests.exceptions.ConnectionError as e: print('Error', e.args) Output: 我们可以看到运行结果的 origin 是代理的IP,这证明代理已经设置成功。 如果代理需要认证,在代理的前面加上用户名和密码即可,即代理的写法变成如下所示: proxy = 'username:password@113.194.28.190:9999' 参考资料:《Python3网络爬虫开发实战》——崔庆才

批量实现多个文件夹中的文件合并

批量实现多个文件夹中的文件合并 在多数情况下,大家可能会遇到代码文件太多,存放混乱,那么改如何整理呢?小编这里想到利用python来实现文件合并。 例如,将如下两个文件夹中所有的文件整理到一个新的文件夹中 点开第一个文件夹,如下图 那么这里附上源代码。 #导入shutil库用做移动文件 import shutil import os path= r"D:\下载" #因路径很长,将一部分路径定义成变量 #获得要整合目标文件夹目录 files_document=os.listdir(path) print(files_document) #循环目标文件夹目录 for i in files_document: #提取目标文件夹中的图像文件夹 document = os.listdir(path+'/'+i) #设置新地址 path_document = path+'/'+i for j in document: image = os.listdir(path_document+'/'+j) #设置创建移动的目标文件夹路径 pathm = path+'\\'+ i + document[1]#‘\\’后面为创建的文件夹名称,可自行修改 if not os.path.exists(pathm): #创建文件夹 os.mkdir(pathm) print('已创建目标文件夹') # else: # print('目标文件夹已存在') for s in image: shutil.move(path_document+'/'+j+'/'+s,pathm)#移动文件到指定目录 # os.rmdir(path_document) #删除空的文件夹 # os.remove(path_document)#删除文件 shutil.rmtree(path_document,True)#删除目录中的所有文件夹 最后,整合后得到的结果为 点开第一个文件夹 里面就只剩下文件了。

Vant picker 选择器 多级联动小白教程

虽然 Vant picker选择器网上有很多文章,但都是前端js写死的数据,并没有写道后端过来的数据如何处理、如何与选择器绑定, 今天我就来记录一下我的写法: 1.后台返回数据格式: { "success": 1, "data": [ { "children": [ { "id": "11111111", "text": "123" } ], "id": "22222222", "text": "药房2" }, { "children": "", "id": "33333333", "text": "药房a" }, { "children": "", "id": "44444444", "text": "中药房2" } ], "code": "", "message": "" } 解释: "text": 组件会默认text为选择器显示的内容 ”id“:id 2.wxml: <van-cell-group> <van-cell title-class="hwms-cell-title" title-width="225rpx" value-class="hwms-cell-content" title="仓库-库位" value="{{warehouseContent}}" bind:click="warehouse" /> </van-cell-group> <van-popup show="{{show}}" position="bottom" bind:close="hideBottom"> <van-picker bind:change="onChange3" columns="{{ columns }}"

【Linux系统移植】NXP 官方开发板 kernel内核 编译与烧录

1、下载 NXP 官方 I.MX6ULL EVK 开发板的kernel :linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2 2、使用 FileZilla Client 将 uboot拷贝到ubuntu 3、解压 tar -xjvf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2 解压出来的文件: 4、安装 库 (1)安装 lzop 库,否则内核编译会失败! sudo apt-get install lzop (2)uboot 或 Linux 内核可以通过输入“make menuconfig”来打开图形化配置界面,menuconfig 是一套图形化的配置工具,需要 ncurses 库支持,使用以下命令安装 ncurses 库: sudo apt-get install build-essential sudo apt-get install libncurses5-dev 5、编译kernel (1)新建mx6ull_iot_emmc.sh 的 shell 脚本文件 vim mx6ull_iot_emmc.sh (2)写入以下内容。shell 脚本要求第一行必须是“#!/bin/bash”或者“#!/bin/sh”。 #!/bin/sh make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_mfg_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j12 (2)给脚本文件可执行权限

Qt用QCustomplot类编译一堆error:undefined reference to `_imp___ZN8QPrinterC1ENS_11PrinterModeE'—工程设置可能有问题

引用qcustomplot,在编译的时候报了一堆这样的错误:undefined reference to `_imp___ZN8QPrinter C1ENS_11PrinterModeE', undefined reference to `_imp___ZN8QPrinter17setOutputFileNameERK7QString' ... 解决方法:更改工程配置 修改 / 添加.pro文件相关行如下: greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport QCustomplot 这个功能很强 画曲线图折线图柱状图动态静态 放大缩小 都很好用 10w条数据量无压力 秒画出来 一点也不卡 使用 qcustomplot.h 和 qcustomplot.cpp!!!pro 文件里面 一定写入 QT+= printsupport!!! 参考链接 https://blog.csdn.net/weixin_42837024/article/details/88669351