小程序text文字不分行、空格、换行、行距小结

text文字不分行 记个笔记,雅俗共享。 一开始只是单行,没截图,为了让大家看到不分行的样式,重新回滚的效果。 小程序样式,说实话相对于习惯了xml布局的我,还是有点不适应的;不废话了,先分析下为啥会出现上面的情况: 理论上。布局本身会对手机屏幕宽度做识别,自动换行,小程序中父布局或者自身布局宽度width: 100%;里面的布局里的view就有点傻傻分不清,还是会认为自己的宽度是屏幕的宽度,即使我布局里有个图片占据了一些位置。 解决办法(我是以自己的demo为例,自行斟酌): .about_acesmart_content{ padding-top:10px; padding-right: 8rem; //设置同等右边图片的width padding-left: 0.5rem; font-size: 13px; color: #666666; line-height: 1.4; display: flex; //display设置为flex;flex-wrap设置为wrap flex-wrap: wrap; } 小注:如果不设置右间距,仅仅只是设置上面的属性依旧不行。最后效果: text 文字空格、换行 换行简单,几乎通用的\n; 空格\t效果可以忽略,其他方法稍微记下(亲测有效): 在text中添加这两个属性,切记:space=“ensp” decode="{{true}}" 空格根据字体设置 <view> <text space="nbsp" decode="{{true}}">&nbsp;类别&nbsp;&nbsp;&nbsp;一</text> </view> 空格是中文字符一半大小 <view> <text space="ensp" decode="{{true}}">&ensp;类别&ensp;&ensp;&ensp;二</text> </view> 空格是中文字符大小 <view> <text space="emsp" decode="{{true}}">&emsp;类别&emsp;&emsp;&emsp;三</text> </view> 行距 直接在css里设置或者直接在wxml中style="" .text { color: #aaa; font-size: 16px; margin: 20px; line-height:1.5em; //行距 } 在此感谢:https://blog.csdn.net/qq_25252769/article/details/76049846 让我了解空格诠释

8255并行接口实验

实验目的: 1.学习并掌握8255的工作方式及其应用。 2.掌握8255典型应用电路的接法。 二、实验环境: PC机一台,TD-PITD实验装置一套。 三、实验内容: 基本输入输出实验。编写程序,使8255的A口为输出,B口为输入,完成拨动开关到数据灯的数据传输。要求只要开关拨动,数据灯的显示就发生相应改变。流水灯显示实验。编写程序,使8255的A口和B口均为输出,数据灯D7~ D0由左向右,每次仅亮一个灯,循环显示,D15~D8与D7~D0正相反,由右向左,每次仅点亮一个灯,循环显示。 实验步骤 1. 基本输入输出实验 本实验使8255端口A工作在方式0并作为输出口,端口B工作在方式0并作为输入口。用一组开关信号接入端口B,端口A输出线接至一组数据灯上,然后通过对8255芯片编程来实现输入输出功能。具体实验步骤如下述: 实验接线图如图3-1-4所示,按图连接实验线路图。根据实验内容,编写实验程序,编译、链接。 运行程序,改变拨动开关,同时观察LED灯的显示,验证程序功能。 实验程序清单(T8255-1.ASM) IOY0 EQU 0C000H ;8255的CS引脚连接IOY0对应的端口始地址 MY8255_A EQU IOY0+00H*2 ; ;8255的端口A地址 MY8255_B EQU IOY0+01H*2 ;8255的端口B地址 MY8255_C EQU IOY0+02H*2 ;8255的端口C地址 MY8255_MODE EQU IOY0+03H*2 ;8255的控制寄存器地址 CODE SEGMENT ;定义代码段 ASSUME CS:CODE START: MOV DX,MY8255_MODE ;8255控制端口地址为3006H MOV AL,82H ;设置8255方式控制字,A、B口工作方式0,A口输出,B口输入 OUT DX,AL LOOP1: MOV DX,MY8255_B ;读B口发出的起始数据,B口输入 IN AL,DX MOV DX,MY8255_A ;写A口发出的起始数据,A口输出 OUT DX,AL MOV AH,1 ;判断是否有按键按下 INT 16H JZ LOOP1 ;无按键则跳回继续循环,有则退出 QUIT: MOV AX,4C00H ;结束程序退出 INT 21H CODE ENDS END START 2.

新年到,献给从一线工程师到CTO的实用指南:《2019区块链开发者报告》

新年伊始,我们将继续以“让区块链回归技术和应用的本质”为宗旨,服务开发者,携手迈入2019。 《区块链开发者报告》(2019年第1期,未来将以季度为周期发布)包含技术扫描、公链选择指南,以及公链与应用开发实战3个部分。 技术扫描:归纳了专家对他们正在关注技术的评价结果,为从CTO到一线开发者提供技术选型指南。与区块链相关的各类技术项目被归类为工具与框架、技术、语言、平台四类,如果条目可能出现在多个象限,则选择最贴切的一个。 我们还进一步将这些技术分为采用、验证、评估、暂缓四个阶段,阐明对在项目中应用这些技术的建议。在后续报告中,我们将进一步扩充覆盖技术的数量与范围。 公链选择指南:尽管公链项目排行屡见不鲜,但均未针对开发者的需求而设计。例如,我们通过与上百位区块链开发者深入沟通,了解到他们对于公链项目最关注的角度是与实际开发过程及产品关联更紧密的文档完备、性能优秀等。 因此,本期报告选择了一批具有独立主链,公有节点可自由创建,并且代码开源的公链项目,邀请专家对开发者最关注的10个维度评分,供开发者参考。未来,我们将持续更新并扩充该列表。 公链与应用开发实战:专题内容涵盖从入门到进阶,上手公链开发,通证简史,公链设计与开发实践和经验揭秘,DApp开发者公链选择指南,以及如何打磨易用的区块链产品。 温馨提示:文末附完整清晰PDF版报告下载方式,敬请留意。 公链与应用开发实战专题,包含以下文章: 入门到进阶,上手公链开发(蓝昊翔,公信宝区块链研发总监) 通证简史——安全与灵活的博弈(尚书,Zerohm联合创始人) 公链设计与开发实践和经验(冯英飞,Alabs ADAG主链项目技术负责人) 公链设计与开发细节揭秘(钟文斌,量子链技术负责人) 底层公链设计开发实操指南(强科臻,Aurora极光链 CTO) DApp开发者公链选择指南(刘虔铭,新经济实验室NEL项目总监) 从节点钱包,谈打磨易用的区块链产品(罗鹏,NULS 产品经理) 免费成为会员,获取完整PDF版报告及更多职业服务(编辑审核后,将发送至您的邮箱): https://wj.qq.com/s2/3042173/b6d2/?from=singlemessage&isappinstalled=0 — END — 推荐阅读: 2019年区块链最大悬念:谁将捡起以太坊掉落的王冠 用数据说话:“2018的DApp爆发之年”被打脸了吗? 19位专家年末论深冬:区块链究竟还能否回暖? Python 爬取 6000 篇文章分析 CSDN 是如何进入微信 500 强的 华为狼性文化遭质疑,那我们当个佛系程序员可好? 实现通用人工智能还要多久?Hinton与AlphaGo之父这样回答 云计算科普——入行半年,我这样看云计算 老程序员肺腑忠告:千万别一辈子靠技术生存!

Spring Boot 2.0版本 Jackson全局转化long类型为String,解决jackson序列化时long类型缺失精度问题

说明 在传递long类型到前台时,如果long类型的数值比较长,会出现精度丢失的问题。以下是解决办法。 前提 版本:Spring Boot 2.0及以上序列化工具Jackson 解决办法 import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; /** * Jackson配置 * @author William * */ @Configuration public class JacksonConfig { /** * Jackson全局转化long类型为String,解决jackson序列化时long类型缺失精度问题 * @return Jackson2ObjectMapperBuilderCustomizer 注入的对象 */ @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { Jackson2ObjectMapperBuilderCustomizer cunstomizer = new Jackson2ObjectMapperBuilderCustomizer() { @Override public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) { jacksonObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance); } }; return cunstomizer; } } 其他配置,参考:https://blog.csdn.net/xiaoxiangzi520/article/details/76522242

Ubutun 18.04下安装python 多版本

1.安装依赖包 sudo apt-get update sudo apt-get install build-essential python-dev python-setuptools python-pip python-smbus sudo apt-get install build-essential libncursesw5-dev libgdbm-dev libc6-dev sudo apt-get install zlib1g-dev libsqlite3-dev tk-dev sudo apt-get install libssl-dev openssl sudo apt-get install libffi-dev sudo apt-get install libbz2-dev libreadline-dev libsqlite3-dev 2.安装git sudo apt install git 3.安装pyenv git clone git://github.com/yyuu/pyenv.git ~/.pyenv echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init -)"' >> ~/.bashrc exec $SHELL -l 4.

构建字符树

有如下字符数组:"A","B","AB","AC","ABC","ACD"。需要构建如下字符树 代码如下: package test; import com.alibaba.fastjson.JSON; import org.apache.commons.lang3.StringUtils; import java.util.*; public class TestTree { public static void main(String[] args) { List<String> strList = Arrays.asList("A","B","AB","AC","ABC","ACD"); Collections.shuffle(strList); Node root = new Node(""); for(String str:strList){ Node.insertNode(root,str); } System.out.println(JSON.toJSONString(root)); System.out.println(JSON.toJSONString(Node.getDataByLayer(root))); } static class Node{ //private Node prev; private String val; private List<Node> subNodes; public Node(String val){ this.val = val; } /*public Node getPrev() { return prev; } public void setPrev(Node prev) { this.prev = prev; }*/ public String getVal() { return val; } public void setVal(String val) { this.

机器学习与线代的爱恨情仇

线性代数 内积 [ x 1 x 2 ⋯ x n ] [ y 1 y 2 ⋮ y n ] = ∑ i = 1 n x i y i \left[\begin{matrix} x_1&x_2&\cdots&x_n\end{matrix}\right]\left [\begin{matrix} y_1\\y_2\\\vdots\\y_n\end{matrix}\right]=\sum\limits_{i=1}^nx_iy_i [x1​​x2​​⋯​xn​​]⎣⎢⎢⎢⎡​y1​y2​⋮yn​​⎦⎥⎥⎥⎤​=i=1∑n​xi​yi​ 相似矩阵 两个n阶方阵A和B为相似矩阵,当且仅当存在一个n阶可逆矩阵P使得: P − 1 A P = B P^{-1}AP=B P−1AP=B 方阵P称为A和B之间的相似变换矩阵,方阵A相似B记做:A~B Jordan标准型 对任意一n阶矩阵A,必存在n阶可逆矩阵P,使得: P − 1 A P = [ J 1 J 2 ⋱ J n ] = J P^{-1}AP=\left[\begin{matrix}J_1\\&J_2\\&&\ddots\\&&&J_n \end{matrix}\right]=J P−1AP=⎣⎢⎢⎡​J1​​J2​​⋱​Jn​​⎦⎥⎥⎤​=J,其中每一个对角块都是Jordan块:

aI_Challenger 机器翻译

AI_Challenger 机器翻译 官方提供的脚本有不少错误,python脚本从2迁移到了3。 训练脚本中去掉了batch_size项,改用 --worker_gpu_memory_fraction 可以免去内存溢出风险。经尝试,在base、big模式下训练的模型效果很差,只有hparams_set=transformer_base_single_gpu 时,训练的模型效果好。最近在客户提供的单个服务器上用4块v100 32g transformer_big_single_gpu训练6万次时已经比提交结果时用公司的k40结果强多了。自然语言处理,好设备代表好结果。本次比赛,官方的脚本中有错误、许多地方描述不清、定义新问题根本就没有提。初学者shell命令基础比较差时,很难训练出好的模型,也很难生成可以提交的结果。本项目把整个过程脚本化,可以帮助初学者训练出还算不错的模型。才知道,所谓big模式就是生成的模型比较大,需要5个多G。需要注意的是t2t训练的模型最后很难收敛,遇到比较好的模型要及时备份,t2t只留下最新的10个模型。有使用本项目训练出好的汉译英模型的,希望能上传到网盘,给本人一个链接。 git clone https://github.com/dreamnotover/english_chinese_machine_translation_baseline.git 数据 https://pan.baidu.com/s/1teDqwd3Tbc7cbacpzPpa7A Neural Machine Translation (English-to-Chinese) baseline for AI_Challenger dataset. Requirenments python 3.6TensorFlow 1.12.0tensor2tensorjieba 0.39 1 $mkdir t2t_tmp t2t_data raw_data 、下载数据 解压后放入raw_data,所有官方数据都放入一个文件夹以方便处理 $unzip raw_data.zip -C raw_data 2 定义新问题 参考 https://blog.csdn.net/hpulfc/article/details/81172498 新问题在./ai_data目录 3、语料预处理与向量化 sh ./prepare.sh sh ./data_gen.sh 4、 训练模型 big模式在4台v100机器上训练,效果比base好多了 big 模式 sh train_big.sh base 模式 sh train_base.sh 5、翻译 将t2t_data里面的字典文件拷贝到 ./dict_path (一定要用自己的),然后预测。(因为翻译时只用到字典,也可指定t2t_data目录) big 模式 sh decode_big.sh base 模式 sh decode_base.

图像傅里叶变换(二维离散傅里叶变换)

图像傅里叶变换 二维离散傅里叶变换是将图像从空间域转至频域,在图像增强、图像去噪、图像边缘检测、图像特征提取、图像压缩等等应用中都起着极其重要的作用。理论基础是任意函数都可以表示成正弦函数的线性组合的形式。公式如下 逆变换公式如下 令 R(u,v) 和 I(u,c) 分别表示 F(u,v) 的实部和虚部。 幅度谱为 相位谱为 指数表示 功率谱为 示例演示 首先我们演示下,从一幅图像得到其的幅度谱和相位谱,然后再根据幅度谱和相位谱还原图像。代码如下。 void MainWindow::dftTransform(cv::Mat &image) { image.convertTo(image, CV_32F); std::vector<cv::Mat> channels; split(image, channels); //分离图像的RGB通道, cv::Mat image_B = channels[0]; //OpenCV:BGR //expand input image to optimal size int m1 = cv::getOptimalDFTSize(image_B.rows); //选取最适合做fft的宽和高 int n1 = cv::getOptimalDFTSize(image_B.cols); cv::Mat padded; //填充0 cv::copyMakeBorder(image_B, padded, 0, m1 - image_B.rows, 0, n1 - image_B.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0)); cv::Mat planes[] = { cv::Mat_<float>(padded), cv::Mat::zeros(padded.size(), CV_32F) }; cv::Mat complexI; cv::merge(planes, 2, complexI); //planes[0], planes[1]是实部和虚部 cv::dft(complexI, complexI, cv::DFT_SCALE | cv::DFT_COMPLEX_OUTPUT); cv::split(complexI, planes); //定义幅度谱和相位谱 cv::Mat ph, mag, idft; cv::phase(planes[0], planes[1], ph); cv::magnitude(planes[0], planes[1], mag); //由实部planes[0]和虚部planes[1]得到幅度谱mag和相位谱ph cv::imshow("

360 for linux?惹不起,惹不起,见过流氓,没见过这么流氓的

测试了一把,结果显示360基本对Linux社区规范和安全常识not give a f*ck。 首先,这个deb包就是胡乱打包,依赖关系就没弄好: $ dpkg-deb -I 360safeforlinux-3.0.0.66-stripped.deb [...] Package: 360safeforlinux Version: 3.0.0.66 Architecture: amd64 Maintainer: qihu360 company Installed-Size: 23617 Depends: libc6 (>= 2.14),libglib2.0-0 (>= 2.38),python2.7 (>= 2.7.6),openssl(>= 1.0),curl,libqt4-network(>= 4.8.5),libqt4-sql(>= 4.8.5) Section: gnome Priority: required Essential: yes Description: 360 safe for linux 但是还实际依赖了libpython2.7和libqtgui4两个库没有标明,要我手动修复。 这个打包还通过滥用Essential标记来制造卸载的麻烦。 root@debian-amd64:/home/user# apt-get remove 360safeforlinux[...]The following packages will be REMOVED: 360safeforlinuxWARNING: The following essential packages will be removed.This should NOT be done unless you know exactly what you are doing!

Win10的重置原理和可行性分析

总有人保留着一种想法:win10电脑随便设置,实在不行就重置 这个观点是从win8.*中继承过来的,但是这里要说的是,他们实质上的原理不一样 以上是win8.*相关设置 接下来是win10同样的设置 如果你还看不出区别的话,接下来是文字结论 /****************************************************************调皮的分割线*********************************************************************/ Win8.*的重置的原理是保留一份超高压缩的原始系统映像,无论你对现在的系统做了什么(除非你删除相关映像,流氓软件非常喜欢这么做),只要你还能执行resetsystem命令,系统都会恢复为全新状态 到了win10(准确说是version1507之后)的时候,因为已经找不到映像位置,而且官方文档已经表明win10重置的原理实质是收集现有可用的文件资源,重新组成个可用的系统。 只要能正常开机和联网,剩下的部分交给dism工具就行,打个比方:__家失火了,烧得只剩墙砖,重置就相当于你收集了足够剩下来的砖来盖房子,只要保证不倒就行,等你有了足够的钱(网络),缺什么可以去买,把这个房子恢复如初。重置的最后一步就是检验系统关键组件(砖)的完整性。 所以结论就是:过度破坏的win10系统不可以通过重置功能来回复,不知道是不是巧合,我遇到过不能重置的电脑上都不约而同地装上了流氓软件并且用户手动清理了垃圾

ubuntu部署sentry

2020年12月更新: git clone https://github.com/getsentry/onpremise cd onpremise ./install.sh docker-compose up -d 第一次启动 docker-compose start 启动服务 docker-compose stop 停止服务 访问 http://x.x.x.x:9000即可打开 参考文档:https://github.com/getsentry/onpremise 旧的安装方法如下 环境:ubuntu18 mysql redis 安装依赖包 sudo apt install virtualenv python-setuptools python-dev libxslt1-dev gcc libffi-dev libjpeg-dev libxml2-dev libxslt-dev libyaml-dev libpq-dev libmysqlclient-dev redis-server ibxmlsec1-dev libxmlsec1-openss mysql-serverl新建目录 mkdir -p ~/work/sentry进入目录 cd ~/work/sentry新建虚拟环境 virtualenv venv进入虚拟环境 source venv/bin/activate安装sentry pip install -U sentry初始化配置 sentry init ~/work/sentry登陆mysql,创建sentry数据库 create database if not exists sentry character set utf8mb4 collate utf8mb4_bin; grant all privileges on sentry.

关于为什么要用 if cv2.waitKey(1) & 0xFF == ord('q'): break的解释

在某些系统上,waitKey()可能会返回一个不仅仅编码ASCII密钥的值。 (当OpenCV使用GTK作为其后端GUI时,已知在Linux上发生了一个错误库。)在所有系统上,我们可以通过读取返回值中的最后一个字节来确保我们只提取SCII键代码,如下所示: keycode = cv2.waitKey(1) if keycode != -1: keycode &= 0xFF 或者 if cv2.waitKey(1) & 0xFF == ord('q'): break

2018操作系统期末试题

考试课程:操作系统(A 卷) 时间:2018 年 05 月 25 日下午 12:45~15:05 答卷注意事项: 1.答题前,请先在试题纸和答卷本上写明 A 卷或 B 卷、系别、班级、学号和姓名。 2.在答卷本上答题时, 要写明题号, 不必抄题。 2. 在答卷本上答题时, 要写明题号, 不必抄题。 3.答题时, 要书写清楚和整洁。 4.请注意回答所有试题。本试卷有 29 个题目,共 5 页。 5.考试完毕, 必须将试题纸和答卷本一起交回。 一、对错题(15 分) 注意:回答请用 V 表示正确,用 X 表示错误; [ ] 在多CPU场景下,多个线程通过自旋锁(spinlock)争抢进入临界区执行,第一个成功进入 临界区的线程是第一个执行自旋锁争抢的线程。 答:√。 用TS指令可以实现自旋锁,属于原子操作指令锁,适用于丹处理器或者共享主存的多处理器的任意数量的进程同步。 [ ] 运行在内核态的内核线程共享操作系统内核态中的一个页表。 √。 [ ] 操作系统创建用户进程时需要为此用户进程创建一个内核栈用于执行系统调用服务等。 √。 [ ] 通用操作系统的调度算法的主要目标是低延迟,高吞吐量,公平,负载均衡。 √。 [ ] 单处理器场景下,短剩余时间优先调度算法(SRT)可达到具有最小平均周转时间的效果。 √。短进程优先算法SPN具有最优平均周转时间,而SRT是SPN的可抢占改进版本,应该也是对的。 [ ] 单处理器场景下,无法通过打开和关闭中断的机制来保证内核中临界区代码的互斥性。 ×。可以。 [ ] 信号量可用于解决需要互斥和同步需求的问题。 √。 [ ] 属于管程范围的函数/子程序相互之间具有互斥性。

如何在Linux中安装nasm最新版本

什么是NASM? Nasm是Linux中最受欢迎的汇编程序之一每个Linux Distros的安装过程都是相同的可重定位的动态目标文件格式(RDOFF)Nasm有自己的二进制格式RDOFF。 如何在Linux中安装NASM Assembler 有2种方法可以安装Nasm(nasm 2.14.02) 方法1 cd~ / ffmpeg_sources curl -O -L http://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2 tar xjvf nasm-2.14.04.tar.bz2 cd nasm-2.14.01 ./autogen.sh ./configure --prefix =“$ HOME/ffmpeg_build”--bindir =“$HOME/bin” 使 make install 要安装最新的nasm版本,请遵循此方法 方法2 在其中创建此repo文件及其下方的文本 vim /etc/yum.repos.d/nasm.repo [NASM] name = Netwide Assembler baseURL时= HTTP://www.nasm.us/pub/nasm/stable/linux/ 启用= 1 gpgcheck = 0 [NASM测试] name = Netwide Assembler(发布候选版本) baseURL时= HTTP://www.nasm.us/pub/nasm/testing/linux/ 启用= 0 gpgcheck = 0 [NASM快照] name = Netwide汇编程序(每日快照构建) baseURL时= HTTP://www.nasm.us/pub/nasm/snapshots/latest/linux/ 启用= 0 gpgcheck = 0 现在安装Nasm sudo su yum install nasm 每个 NASM 版本的安装都是相同的。

2018年上海后半年JAVA软件工程师面试真题

查询超过该部门员工大于3个的部门 SELECT deptid FROM table1 GROUP BY deptid HAVING COUNT(deptid) > 3 如果员工名称重复的部门id SELECT deptid FROM table1 GROUP BY deptid HAVING COUNT(empname) > 3 单例模式 package com.day01; public class 单例模式 { private final static 单例模式 INSTANCE = new 单例模式(); private 单例模式(){ } public static 单例模式 getInstance(){ return INSTANCE;}} 1 需要写个类 2 在类里面new 一个自己,private final static 3 私有无参构造 4 static 方法,返回自己 3.冒泡排序 package com.day01; public class 冒泡排序 { public static void main(String[] args) {

音频信息隐藏算法

1、最不重要位法(LSB) 对音频信号进行采样,将采样值最不重要的位(通常为最低位)用代表水印的二进制位代替,以达到在音频信号中嵌入水印数据的目的。 主要特点是:嵌入及提取水印速度快,算法简单,容易实现,音频信号中可编码的数据量大;其缺陷是稳健性差。 2、相位隐藏法。 在相位编码中,隐藏的信息是用相位谱中特定的相位或相对相位来表示的,可将音频信号分段,每段做离散傅里叶变换,信息只隐藏在第1段中,用代表秘密信息的参考相位替换第1段的绝对相位,保证信号间的相对相位不变,所有随后信号的绝对相位也同时改变。 相位水印算法的特点是:当代表水印数据的参考相位急剧变化时,会出现明显的相位离差,会影响水印的隐蔽性以及增加水印解码的难度。当音频信号是较安静的环境时,嵌入数据量较少。 离散傅立叶变换(DFT)算法 主要方法是:先对音频信号进行DFT,然后选择其中频率范围为 2.4-6.4KHz的DFT系数嵌入水印,然后用表示水印序列的频谱分量来并替换相应的DFT系数。其主要特点是:具有定的稳健性,但嵌入量较小。 3、直接扩频隐写原理 直接扩频隐写是将秘密信息经过伪随机序列调制后, 选择合适的嵌入强度迭加到载体音频的整个频谱系数上的技术.传统的变换域包括了 FFT ,DCT , DWT ,随着 MDCT 在 MP3 , AAC 等音频编码中的应用,近年来也提出了基于MDCT 和 MCLT 变换域的直接扩频隐写方法[ 4] . 离散余弦变换(DCT)算法 主要方法是:首先根据伪随机序列重新排列音频采样信号,对序列进行修正离散余弦变换(MDCT,Modified Discrete Cosine Transform),通过对MDCT的系数进行改变以便嵌入水印,然后进行逆变换得到嵌入水印后的音频序列。 DCT 算法的主要特点是:选择变换系数(低频、中频或高频),局部修改某些变换系数,以实现水印的嵌入。其透明性较好,能平滑功率谱密度,稳健性随所选频域嵌入系数而有所不同。 基于DCT谱的频域变换方法,将信息嵌人到音频信号的频谱中去。首先将音频序列分段成一定长度的帧,并用DCT变换计算出该帧的频谱。同时将隐藏信息置乱或交织后串行化为bit流,一个bit的隐藏信息通过改写一个音频帧的频谱,使其符合相应的特征而被嵌入其中,然后对改写了的频谱作IDCT反变换得到复合音频序列。信息提取过程是计算出音频帧的DCT频谱,然后根据其频谱特征决定该帧的隐藏bit是0还是1 离散小波变换(DWT)算法 算法的主要方法是:用Daubechies-4 小波基对原始语音信号进行L级小波分解,对L级的粗糙分量保留不予处理,对L级的精细分量进行处理,以嵌入水印 陈琦[36]等于 2002 年提出了利用小波变换将一枚签章的数字图像作为水印,嵌入到小波变换的第三层的精细分量中,并在信号嵌入时使用了检测同步信号,但检测时需要通过原始音频信号进行比较才能获得水印。其主要特点是:有较好的透明性、较强的鲁棒性 4、基于振幅值修改的 wav 音频隐写算法 算法将秘密音频通过随机数生成器置乱,通过比较原始音频每个采样点分组中振幅值之间的关系,结合待嵌入的秘密信息位进行嵌入修改,嵌入强度依据密钥进行调节。实验结果表明,该算法具有较大的嵌入容量,不可感知性良好,具有一定的抗隐写分析能力,并可实现盲提取。 该算法根据每 3个采样点振幅值之间的关系,动态调整中间采样点的振幅值用于隐藏秘密信息。在增大嵌入容量的同时,能有效控制嵌入信息对音频质量产生的影响,取得了较好的实验效果 5、基于回声的水印算法 回声(Echo Hiding)算法是种经典算法,最初由Gruhl[23]等人于 1996 年提出。其主要方法是通过引入回声来将秘密数据嵌入到载体数据中,利用HAS的滞后掩蔽特性,即弱信号在强信号消失之后变得无法听见,它可以在强信号消失 50-200ms作用而不被人耳觉察。 在回声隐藏的算法中,编码器将载体数据延迟一定的时间并叠加到原始的载体数据上以产生回声。编码器可以用两个不同的延迟时间来嵌入“0”和“1”。在实际的操作中,用代表“0”或“1”的回声内核与载体信号进行卷积来达到添加回声的效果。要想使嵌入后隐秘数据不被怀疑,并且能使接收方以较高的正确率提取数据,关键在于回声内核的选取。每个回声内核具有四个可调整的参数:原始幅值、衰减率、“1”偏移量和“0”偏移量。 回声算法的特点是:透明性好,可盲水印检测;但提取水印的正确率不能令人满意。后来,赵朝[30]、Hyen[31]等学者对其进行改进。

通过点击事件监听 setOnClickListener 彻底理解回调-Android

前言 老司机们对于回调肯定熟悉得不能再熟悉了,但是新司机可能还是一脸懵逼的,我比较笨,当年懵逼了好久,看夏安明的这一篇博客地址,虽然下边的留言都是,写得好!懂了懂了!但是我当时看了三遍还是不懂好吗 - -,现在我站在我的角度,用我理解的方式给大家讲解回调,我这么笨都理解了,聪明的新司机们肯定也是可以的 setOnClickListener 分析 setOnCLickLinstener,只要写过 Android 的同学应该都见过,大家都知道是点击事件监听,但是是怎么实现的呢?对,你没有猜错,就是回调 你在 onClick(View view)中写的方法,就是一个回调方法,你仔细想一想,这个方法是在你传的参数 new View.OnClickListener()中的方法,你再仔细的想一想,为什么你传入了 new View.OnClickListener()这个参数,Android Studio 就会自动补全,让你去实现 onClick(View view)这个方法呢? 一切都在你想象之中,OnClickListener 就是一个接口,new 出一个接口,你就得实现他里边的抽象方法,在 Android 中,大多数回调都是靠接口来进行的 并且,你实现了 onClick(View view)方法后,这个方法并没有在我们的 Activity 或者 Fragment 中调用,那为什么他生效了呢?这就是回调,你实现了他,而他却是在另一个地方调用的 那是在什么地方调用的呢? 我们点进 setOnClickListener 方法中一探虚实 于是我们跳到了 View.java,原来这个方法是写在 View 中的,这时你想到,第一行代码中说了,我们的控件都继承于 View,原来如此 public void setOnClickListener(@Nullable OnClickListener l) { if (!isClickable()) { setClickable(true); } getListenerInfo().mOnClickListener = l; } setOnClickListener 方法就如同我们调用时的那样,传入一个 OnClickListener 对象作为参数,那我们来看一看 OnClickListener 是个啥子 public interface OnClickListener { /** * Called when a view has been clicked.

单点登录SSO+redis(有免费源码,新手使用)

最近在学习单点登录,真的是要被搞疯,想找一个源码使用一下,都是收费的,气的我花了时间自己写了一个。 觉得不妥的下方评论咱们共同讨论。直接在后台操作,不用前台页面。 1.首先说一下我理解的单点登录,在一个大的业务中,有很多个系统,客户在浏览同一家公司的不同系统时,只需要登录一次就够了。 2.思路:进入自己想要访问的页面,系统会检查cookie里面是否存有用户的信息,有的话直接允许通过,cookie中没有信息的话转到登录页面验证用户信息,并且将token放到redis,增加cookie 3.直接准备Coding //登录的处理流程 1、登录页面提交用户名密码。 2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。 3、把用户信息保存到redis。Key就是token,value就是用户信息 4、把token写入cookie中。 7、Cookie需要跨域。例如www.jd.com\sso.jd.com\order.jd.com,可以使用工具类。 8、Cookie的有效期。关闭浏览器失效。 请求的url:/user/login 请求的方法:POST 参数: { “username”:“zs”, “password”:“123” } 返回值:json数据 @PostMapping("login.do") public ServiceResponse Login(@RequestBody User user, HttpServletResponse response) throws Exception { ServiceResponse responseS = new ServiceResponse(); //1.判断用户名和密码是否正确 String username = user.getUsername(); String password = user.getPassword(); if (username == null || password == null) { responseS.setCode("1111"); responseS.setMessage("用户名或者密码不能为空"); return responseS; } User info = userService.LoginInfo(username); if (info == null) { responseS.setCode("1112"); responseS.

VS2019配置OpenCV

一、环境 vs2019社区版、win10 64位操作系统 二、opencv配置步骤(共5步) 1、下载OpenCV4.0.1,官网为opencv.org 2、安装opencv,我的安装目录是 D:\opencv-4.0.1-vc14_vc15 3、添加环境变量,在PATH中添加: D:\opencv-4.0.1-vc14_vc15\opencv\build\x64\vc15\bin 4、将D:\opencv-4.0.1-vc14_vc15\opencv\build\x64\vc15\bin目录下面的 opencv_world401.dll和opencv_world401d.dll文件复制到 C:\Windows\SysWOW64这个文件夹; 另外:以上如果不想copy到C盘,把两个文件添加到工程的引用中应该也是可行的(还没有尝试过); 5、将bin目录里面的opencv_ffmpeg341_64.dll复制到C:\Windows\System32这个文件夹; 三、vs配置步骤(共3步) 1、包含目录中加入 D:\opencv-4.0.1-vc14_vc15\opencv\build\include和D:\opencv-4.0.1-vc14_vc15\opencv\build\include\opencv2 注:上图是自己添加的项目属性表,名称自己随意; 2、库目录中加入 D:\opencv-4.0.1-vc14_vc15\opencv\build\x64\vc15\lib 3、 链接器->输入->附加依赖项中加入opencv_world401d.lib 四、测试代码 可以去参考官网的demo https://docs.opencv.org/4.0.1/d3/d52/tutorial_windows_install.html#tutorial_windows_install_path //建立一个C++控制台程序即可 // opencvDemo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include "pch.h" #include <iostream> #include <opencv2/highgui.hpp> #include <opencv2/core.hpp> #include <opencv2/imgcodecs.hpp> using namespace cv; using namespace std; int main() { Mat image; image = imread("F:\\ShowProject\\source\\you.jpg"); // Read the file if (image.empty()) // Check for invalid input { cout << "

Git解决fatal: unable to connect to github.com

git clone git://github.com/lajos/iFrameExtractor.git 错误信息: bower error status code of git: 128 fatal: unable to connect to github.com: github.com[0: 你的IP]: errno=Operation timed out 原因: 需要用https才能读到数据 解决方法:输入命令 git config --global url."https://".insteadOf git:// 转载自http://blog.csdn.net/greenqingqingws/article/details/11808745

SpringMVC流程架构图

01_SpringMVC流程架构图 【组件说明】 以下组件通常使用框架提供实现: 1.DisPatcherServlet:前端控制器(不需要程序员开发) 用户请求到达前端控制器,它相当于MVC模式中的C(Controller),DispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet的存在降低了组件之间的耦合性。 作用:作为接受请求,相应结果,相当于转发器,中央处理器,减少其他组件之间的耦合度。 2.HandlerMapping:处理器映射器(不需要程序员开发) HandlerMapping负责根据用户请求找到Handler(即:处理器),SpringMVC提供了不同的映射器实现实现不同的映射方式,例如:配置文件方式、实现接口方式、注解方式等。 作用:根据请求的Url 查找Handler 3.HandLer:处理器(需要程序员开发) Handler是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下,Handler对具体的用户请求进行处理。 由于Handler设计到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。 注意:编写Handler时按照HandlerAdpter的要求去做,这样才可以去正确执行Handler。 4.HandlerAdapter:处理器适配器 通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。 作用:按照特定的规则(HandlerAdapter要求的规则)去执行Handler 5.ViewResolver:视图解析器(不需要程序员开发) ViewResolver负责将处理结果生成View视图,ViewResolver首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生 成View视图对象,最后对View进行渲染将处理结果通过页面的展示给用户。SpringMVC框架提供了很多View视图类型,包 括:JSTLView、freemarkerView、pdfView等等. 作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)。 6.View视图 (需要程序员开发 jsp) View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf) 一般情况下需要通过页面标签或者页面模板技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。 【流程图】 【流程图说明】 1.用户发送请求至 前端控制器DispatcherServlet。 2.前端控制器DispatcherServlet收到请求后调用处理器映射器HandlerMapping。 3.处理器映射器HandlerMapping根据请求的Url找到具体的处理器,生成处理器对象Handler及处理器拦截器HandlerIntercepter(如果有则生成)一并返回给前端控制器DispatcherServlet。 4.前端控制器DispatcherServlet通过处理器适配器HandlerAdapter调用处理器Controller。 5.执行处理器(Controller,也叫后端控制器) 6.处理器Controller执行完后返回ModelAnView。 7.处理器映射器HandlerAdapter将处理器Controller执行返回的结果ModelAndView返回给前端控制器DispatcherServlet。 8.前端控制器DispatcherServlet将ModelAnView传给视图解析器ViewResolver。 9.视图解析器ViewResolver解析后返回具体的视图View。 10.前端控制器DispatcherServlet对视图View进行渲染视图(即:将模型数据填充至视图中) 11.前端控制器DispatcherServlet响应用户。 (注意颜色)

C++ 初始化操作由 case 标签跳过

最近在编毕业设计的程序, 中间遇到不少细节问题,随时整理记录下来。 运行环境VS2008 C++ MFC程序 switch(nIDEvent) { case 1: CString strTime ; //系统时间 CTime time = CTime::GetCurrentTime(); strTime = time.Format(_T("%Y-%m-%d,%H:%M:%S")); SetDlgItemText ( IDC_STATIC_time, strTime ); break; case 2: if( led == 0) { led =1 ; } else { led = 0 ; } break; } 当之有case1的时候运行正常, 加入了 case2后 ,出现错误: 错误 2 error C2360: “time”的初始化操作由“case”标签跳过 错误 3 error C2360: “strTime”的初始化操作由“case”标签跳过 经过查找发现,如果要在case里面定义变量,需要用括号括起来{}。 改为 case 1: { CString strTime ; //系统时间

Vue 动态改变title——vue-wechat-title组件(解决app内嵌h5,ios获取不到title的问题)

在app内嵌h5的混合应用中,iOS系统下部分APP的webview中的标题不能通过 document.title = xxx 的方式修改,原因是在IOS webview中网页标题只加载一次,动态改变是无效的。 一. 安装 npm install vue-wechat-title --save 二. 使用 在main.js中引入 import VueWechatTitle from 'vue-wechat-title' Vue.use(VueWechatTitle) 在router>index.js中添加meta对象配置title const router = new Router({ routes: [ ... { path: "/gameDesc", name: 'gameDesc', component: resolve => import('@/pages/Game/gameDesc'), meta:{ title: '游戏说明' } }, { path: "/integralList", name: 'integralList', component: resolve => import('@/pages/Game/integralList'), meta:{ title: '积分收取记录' } } ... ] }); router.afterEach(route => { // 从路由的元信息中获取 title 属性 if (route.meta.title) { document.

easyui中datagrid调用getEditor条件

1、column要有Editor属性 2、要开启编辑行或者编辑格: $(this).datagrid('beginEdit', index); 或者在监听事件onBeginEdit里 3、使用getEditor $(this).datagrid('getEditor', cell)

tkinter导入文件

自学tkinter,针对“文件导入”所走过的坑: 通过在网上查找,很容易找到filedialog为tkinter的文件导入模块,即from tkinter import filedialog,filedialog内置功能源文件写的很简洁就不多说了,这里要提的就是askdirectory,它只能记录到文件所在的文件夹。在此主要介绍askopenfilenames。 import tkinter as tk from tkinter import filedialog from main_program import Road_images window = tk.Tk() 刚开始的写法 def open_file(): filename = filedialog.askopenfilename(title='打开txt文件', filetypes=[('txt', '*.txt')]) return filename button_import = tk.Button(window, text="导入文件",command=open_file) button_impprt.pack() 这样可以直接打开文件,非常方便,但我需要获取文件路径,于是加了一句 filename = open_file() 这样写就会引发一个很蛋疼的问题,就是刚运行程序时就会自动打开选择文件对话框,网上查半天依然找不到解决的办法,后面才想到借用Entry功能,完整代码如下: import tkinter as tk from tkinter import filedialog window = tk.Tk() window.geometry("500x300") def open_file(): filename = filedialog.askopenfilename(title='打开txt文件', filetypes=[('txt', '*.txt')]) entry_filename.insert('insert', filename) # 设置button按钮接受功能 button_import = tk.Button(window, text="导入文件", command=open_file).pack() # 设置entry entry_filename = tk.

七、k8s ingress (http/https)部署与使用

ingress简单来讲,就是一个利用负载均衡的玩意,其主要用来解决使用NodePort暴露Service的端口时Node IP会漂移的问题。同时,若大量使用NodePort暴露主机端口,管理会非常混乱。 好的解决方案就是让外界通过域名去访问Service,而无需关心其Node IP及Port。那为什么不直接使用Nginx?这是因为在K8S集群中,如果每加入一个服务,我们都在Nginx中添加一个配置,其实是一个重复性的体力活,只要是重复性的体力活,我们都应该通过技术将它干掉。 参考文档:https://kubernetes.io/docs/concepts/services-networking/ingress/ 注意线上要部署多副本模式,可以指定机器部署,也可以每台机器放一个ingress服务 Pod与Ingress的关系 通过label-selector相关联 通过Ingress Controller实现Pod的负载均衡 支持TCP/UDP 4层和HTTP 7层 1、部署ingress 部署文档:https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md 下载yaml文件: wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml 注意事项: • 镜像地址修改成国内的:lizhenliang/nginx-ingress-controller:0.20.0 • 使用宿主机网络:hostNetwork: true 创建ingress: [root@master ingress]# kubectl create -f mandatory.yaml 查看ingress服务: [root@master ingress]# kubectl get all -n ingress-nginx NAME READY STATUS RESTARTS AGE pod/nginx-ingress-controller-79888fdc4c-qbpdb 1/1 Running 0 64s NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-ingress-controller 1 1 1 1 66s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-ingress-controller-79888fdc4c 1 1 1 65s 注意如果:

PyTorch 学习笔记(三):transforms的二十二个方法

本文截取自《PyTorch 模型训练实用教程》,获取全文pdf请点击:https://github.com/tensor-yu/PyTorch_Tutorial 文章目录 一、 裁剪——Crop1.随机裁剪:transforms.RandomCrop2.中心裁剪:transforms.CenterCrop3.随机长宽比裁剪 transforms.RandomResizedCrop4.上下左右中心裁剪:transforms.FiveCrop5.上下左右中心裁剪后翻转: transforms.TenCrop 二、翻转和旋转——Flip and Rotation6.依概率p水平翻转transforms.RandomHorizontalFlip7.依概率p垂直翻转transforms.RandomVerticalFlip8.随机旋转:transforms.RandomRotation 三、图像变换9.resize:transforms.Resize10.标准化:transforms.Normalize11.转为tensor:transforms.ToTensor12.填充:transforms.Pad13.修改亮度、对比度和饱和度:transforms.ColorJitter14.转灰度图:transforms.Grayscale15.线性变换:transforms.LinearTransformation()16.仿射变换:transforms.RandomAffine17.依概率p转为灰度图:transforms.RandomGrayscale18.将数据转换为PILImage:transforms.ToPILImage19.transforms.Lambda 四、对transforms操作,使数据增强更灵活20.transforms.RandomChoice(transforms)21.transforms.RandomApply(transforms, p=0.5)22.transforms.RandomOrder 本文对transforms.py中的各个预处理方法进行介绍和总结。主要从官方文档中总结而来,官方文档只是将方法陈列,没有归纳总结,顺序很乱,这里总结一共有四大类,方便大家索引: 裁剪——Crop 中心裁剪:transforms.CenterCrop 随机裁剪:transforms.RandomCrop 随机长宽比裁剪:transforms.RandomResizedCrop 上下左右中心裁剪:transforms.FiveCrop 上下左右中心裁剪后翻转,transforms.TenCrop 翻转和旋转——Flip and Rotation 依概率p水平翻转:transforms.RandomHorizontalFlip(p=0.5) 依概率p垂直翻转:transforms.RandomVerticalFlip(p=0.5) 随机旋转:transforms.RandomRotation 图像变换 resize:transforms.Resize 标准化:transforms.Normalize 转为tensor,并归一化至[0-1]:transforms.ToTensor 填充:transforms.Pad 修改亮度、对比度和饱和度:transforms.ColorJitter 转灰度图:transforms.Grayscale 线性变换:transforms.LinearTransformation() 仿射变换:transforms.RandomAffine 依概率p转为灰度图:transforms.RandomGrayscale 将数据转换为PILImage:transforms.ToPILImage transforms.Lambda:Apply a user-defined lambda as a transform. 对transforms操作,使数据增强更灵活 transforms.RandomChoice(transforms), 从给定的一系列transforms中选一个进行操作 transforms.RandomApply(transforms, p=0.5),给一个transform加上概率,依概率进行操作 transforms.RandomOrder,将transforms中的操作随机打乱 一、 裁剪——Crop 1.随机裁剪:transforms.RandomCrop class torchvision.transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode=‘constant’) 功能:依据给定的size随机裁剪 参数: size- (sequence or int),若为sequence,则为(h,w),若为int,则(size,size) padding-(sequence or int, optional),此参数是设置填充多少个pixel。

No matching version found for

原文链接 No matching version found for Linux上npm安装依赖报错: npm WARN tar ENOENT: no such file or directory, open '/js-lambert/app/test-blog/mobile-static/node_modules/.staging/autoprefixer-12a2e9a7/lib/prefixes.js' npm ERR! code ETARGET npm ERR! notarget No matching version found for event-stream@3.3.6 npm ERR! notarget In most cases you or one of your dependencies are requesting npm ERR! notarget a package version that doesn't exist. 项目在mac上是能够顺利运行的,传到服务器上却报错。 在网上查资料发现是package-lock.json的原因,删除package-lock.json,问题解决

MySQL Daemon failed to start. 正在启动 mysqld:[失败]

在 CentOS 6.7上之前安装过Mysql数据库,想升级到较新的版本所以就重新升级了一下数据库。可是重新安装后运行:service mysqld start 重启数据库总是会出现如下提示: MySQL Daemon failed to start. Starting mysqld: [FAILED] 的提示。如果直接输入 mysql -root -p登陆会出现[mysql]ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)的错误提示。总之MySql服务器端总是无法启动。网上的提供很多解决方法也没有效果。最后通过如下方法解决: 运行以下命令: rm -fr /var/lib/mysql/* rm /var/lock/subsys/mysqld killall mysqld 然后再运行service mysqld start启动mysql如下图: 再运行: service mysqld start /etc/rc.d/init.d/mysqld status 查看数据库状态如下

图神经网络综述:模型与应用

近年来,图神经网络的研究成为深度学习领域的热点。近日,清华大学孙茂松组在 arXiv 上发布预印版综述文章 Graph Neural Networks: A Review of Methods and Applications。 该文总结了近年来图神经网络领域的经典模型与典型应用,并提出了四个开放性问题。对于希望快速了解这一领域的读者,不妨先从这篇文章看起。 除了这篇综述外,文章作者在 Github 中更新了该领域的参考文章列表(https://github.com/thunlp/GNNPapers),供各位读者参考查看。 引言 图是一种数据结构,它对一组对象(节点)及其关系(边)进行建模。近年来,由于图结构的强大表现力,用机器学习方法分析图的研究越来越受到重视。图神经网络(GNN)是一类基于深度学习的处理图域信息的方法。由于其较好的性能和可解释性,GNN 最近已成为一种广泛应用的图分析方法。 GNN 的第一个动机源于卷积神经网络(CNN)。CNN 的广泛应用带来了机器学习领域的突破并开启了深度学习的新时代。然而 CNN 只能在规则的 Euclidean 数据上运行,如图像(2 维网格)和文本(1 维序列)。如何将 CNN 应用于图结构这一非欧几里德空间,成为 GNN 模型重点解决的问题。 ▲ 图1. 左:图像(欧几里得空间) 右:图(非欧几里德空间) GNN 的另一个动机来自图嵌入(Graph Embedding),它学习图中节点、边或子图的低维向量空间表示。DeepWalk、LINE、SDNE 等方法在网络表示学习领域取得了很大的成功。然而,这些方法在计算上较为复杂并且在大规模上的图上并不是最优的,GNN 旨在解决这些问题。 这篇文章对图神经网络进行了广泛的总结,并做出了以下贡献: 文章详细介绍了图神经网络的经典模型。主要包括其原始模型,不同的变体和几个通用框架。 文章将图神经网络的应用系统地归类为结构化场景、非结构化场景和其他场景中,并介绍了不同场景中的主要应用。 本文为未来的研究提出四个未解决的问题。文章对每个问题进行了详细分析,并提出未来的研究方向。 模型 在模型这一部分中,文章首先介绍了最经典的图神经网络模型 GNN,具体阐述了 GNN 的模型与计算方式,然而 GNN 模型仍然存在一定的限制,比如较高的计算复杂度以及表示能力不足等等。 后续的很多工作致力于解决 GNN 存在的种种问题,在 2.2 一节中文章详细介绍了 GNN 的不同变体。具体来说,文章分别介绍了适应于不同图类型、采用不同的信息传递方式以及采用了不同的训练方法的变体。 ▲ 图2. 不同的GNN变体 在 2.2.1 节中,文章介绍了处理不同图类型的 GNN 变体,包括有向图、异质图和具有边信息的图。在 2.2.2 节中,文章对于采用不同信息传递方式的变体进行了总结与概括。主要分为以下四个类别:

Nginx报错——upstream timed out 10060

前言 在部署项目的时候,Nginx 启动不了,网上看了很多大佬的文章, 最后发现是 Windows 服务器 IP 解析的问题。 过程 部分 error.log: 2018/12/25 19:45:55 [notice] 2368#2644: signal process started 2018/12/25 19:47:10 [error] 5024#3948: *1 upstream timed out (10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond) while connecting to upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8090/", host: "

docker基础命令

docker镜像的基础命令(相关的参数选项option请查看官方文档) 1.docker run -it {images id} bash # 创建并运行容器 // docker run -it sdffasddfsdfe bash 2.docker exec -it {container id} bash # 进入正在运行的容器 // docker exec -it wcsds345fdaszx bash 3.docker start {container id} # 启动容器 // docker start wcsds345fdaszx 4.docker stop {container id} # 终止容器 // docker stop wcsds345fdaszx 5.docker restart {container id} # 重启容器 6.docker cp SRC_PATH|- CONTAINER:DEST_PATH #宿主机拷贝文件到docker内部 // docker cp ./update.tar gdb0802:/home/work 7.docker ps # 查看运行中的容器 8.

localStorage跨域问题

域名1: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/> <title>a.html</title> </head> <body> <iframe style='display:none' src="域名2"></iframe> <script type="text/javascript"> window.onload = function () { window.frames[0].postMessage('信息','域名2'); } </script> </body> </html> 域名2: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/> <title>a.html</title> </head> <body> <script type="text/javascript"> window.addEventListener('message', function (e) { if (e.source == window.parent){console.log(e)} }, false); </script> </body> </html>

windows server 2012 R2 远程桌面授权模式尚未配置,远程桌面服务将在120天内停止工作

windows server 2012 R2 远程桌面授权模式尚未配置,远程桌面服务将在120天内停止工作。如何破解这个宽限期,目前企业7位协议号码均不包含2012 R2以上授权。 那么只能蛋疼的“破解”咯。 解决方法: 首写通过mstsc /v:ip /admin 强制登陆服务器,链接时间有点长,等待一下。 删除注册表中 “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM\GracePeriod” ,如果删除不了需要增加管理员权限修改服务器时间,可以修改到2099年。 最后重启电脑

echarts 添加自定义文字

方法一:配置 graphic https://www.w3cschool.cn/echarts_tutorial/echarts_tutorial-3u872dym.html 实例代码: option = { graphic: [ { type: 'group', left: 'center', bottom: 130, children: [ { type: 'rect', z: 100, left: 'center', top: 'middle', shape: { width: 190, height: 90 }, style: { fill: '#fff', stroke: '#555', lineWidth: 2, shadowBlur: 8, shadowOffsetX: 3, shadowOffsetY: 3, shadowColor: 'rgba(0,0,0,0.3)' } }, { type: 'text', z: 100, left: 'center', top: 'middle', style: { fill: '#333', text: [ '自定义文字自定义文字', '自定义文字自定义文字', '自定义文字自定义文字', '自定义文字自定义文字', '自定义文字' ].

C++修改图片的尺寸

在设置用户头像的时候,从网络上下载下来的用户头像的尺寸可能和我们本身想要的头像的尺寸不一致,这时候我们就需要对用户头像的尺寸进行修改,下面直接给出代码,需要的朋友可以参考。 //改变图片的尺寸 bool ResizePicture(CString strSource, CString strTarget) { int WIDTH = 70; int HEIGHT = 70; CImage oldimg; CImage newimg; oldimg.Load(strSource); if (oldimg.IsNull()) return false; int nWidth = 0; int nHeight = 0; nWidth = oldimg.GetWidth(); nHeight = oldimg.GetHeight(); if (nWidth > WIDTH || nHeight > HEIGHT) { double dRatio = nWidth * 1.0 / nHeight; if (nWidth > nHeight) { nWidth = WIDTH; nHeight = (int)(nWidth / dRatio); } else { nHeight = HEIGHT; nWidth = (int)(nHeight * dRatio); } } if (!

unicode编码下CString、string、char*、int之间的相互转换

//unicode //CString转int CString m_cstr; int m_int; string m_str; m_cstr = L"100"; m_int = _ttoi(m_cstr);//_ttoi m_int = 100; m_cstr.Format(L"%d", m_int);//Format //CString转string //方法一 string m_str2(CW2A(m_cstr.GetString())); //采用的方法 //方法二 CT2CA m_ct2ca(m_cstr); string m_str3(m_ct2ca); //方法三 wstring m_wstr(m_cstr); m_str.assign(m_wstr.begin(), m_wstr.end()); //方法四 m_str = CT2A(m_cstr.GetBuffer());//转化为非unicode. //string转CString /*c_str()和data()区别是:前者返回带'/0'的字符串,后者则返回不带'/0'的字符串*/ CString m_cstr2(m_str.c_str()); CString m_cstr3(m_str.data()); m_cstr = m_str.c_str(); m_cstr = m_str.data(); m_cstr.Format(L"%s", m_str.c_str());//string->CString m_cstr.Format(L"%s", m_str.data());//string->CString //Unicode下CString转换为char*类型 char * m_chr; m_cstr = _T("hello"); USES_CONVERSION; m_chr = T2A(m_cstr);//T2A m_chr = W2A(m_cstr);//W2A int n = m_cstr.

面试官让用5种python方法实现字符串反转?对不起我有16种……

最近身边有个朋友,因为经受不住年薪30W+的诱惑,立志转行成为一名程序员。在自学编程一个月以后,假装自己是学生哥,信心满满地和应届毕业生一起参加了校招。然而,进行了十几次面试,统统折戟沉沙。 这哥们儿面试失意,就来找我诉苦:“面试题目太变态了。比如有家公司,让我用五种编程方法实现字符串反转,整个面试我都在懵逼中度过的!” 啧啧~这明显是基础不够扎实呀!区区五种方法,那可是信手拈来!下面就开始我的表演!~ 更多Python视频、源码、资料加群531509025免费获取 方法一:反转列表法 Python中,列表可以进行反转,我们只要把字符串转换成列表,使用reverse()方法,进行反转,然后再使用字符串的join()方法遍历列表,合并成一个字符串。 方法二:循环反向迭代法 字符串属于序列的一种,我们可以使用for循环遍历字符串,然后,不断反向赋值给变量b,最后输出变量b,就完成了字符串反转。 方法三:反向循环迭代法 字符串本身就可以进行切片,当然也可以设置步长为-1,进行倒序。然后,再进行遍历,迭代变量b,也可以达到反转效果,逻辑和方法二相同。 方法四:倒序切片法 方法二和方法三的终极版本,直接反转,一步到位。 方法五:遍历索引法 字符串作为序列,可以进行索引,我们先遍历索引数字,然后倒序提取字母,然后合并成字符串。 方法六:列表弹出法 列表有一种弹出的方法pop(),弹出其中某个元素,默认为最后一个元素。我们设置变量b,然后不断弹出字符串的最后一个字符,加入变量b中,最终使得字符串反转。 方法七:列表解析式法 方法三的简便写法,使用列表解析式,简化代码书写。最后同样通过join()方法,反转合并字符串。 方法八:反向遍历索引法 range()函数有三个参数:start,end,step,且左闭右开,我们从最后一个索引开始,最开始的索引结束,倒序遍历索引,然后反向提取字符串,最后合并。是方法五的逆向思维。 方法九:累积相加法 使用python中的reduce()函数。先创建一个字符串倒序相加函数和字符串,一起传入reduce函数中,运行,就可以进行字符串倒序累积相加,最后反转字符串。 方法十:匿名函数法 方法九的进阶版,使用lambda匿名函数创建字符串倒序相加函数,然后进行累积,得到字符串反转结果。 方法十一:列表倒序法 用列表的sort(reverse=True)方法,倒序排列,不过,这一方法有个弊端,它并不是按字符串的顺序进行升序或降序排列,而是按英语26个字母进行排序,所以,如果字符串不是按从小到大排列,那么运行后,排序会是错误的。 方法十二:双向队列排序法 使用双向队列进行操作。解释下双向队列,这是一个数据结构,但可以方便的向序列的两边进行添加,删除元素。我们遍历字符串,向左添加入双向队列中,最后使用join()方法合并,使字符串反转。 方法十三:双向队列反转法: 同样使用双向队列,把字符串转换成列表添加入队列中,然后整个进行反转,最后合并导出。 方法十四:一维数组索引法 使用pandas的一维数组结构,对其倒序遍历,反转字符串。 方法十五:函数递归法 使用递归的思想,建立函数,倒序添加字符串,直到字符串长度小于等于1以后停止。 方法十六:对称交换法 这是最为销魂的一个方法~大体思路是遍历字符串前一半的元素,然后和后一半对称的那个位置的元素进行交换,以达到字符串反转。过程非常讲究逻辑~

Redis拾遗

本文整理自剑指Java面试-Offer直通车 主流应用架构 Memcache和Redis的区别 Memcache 代码层次类似Hash 支持简单数据类型 不支持数据持久化存储 不支持主从 不支持分片 Redis 数据类型丰富 支持数据磁盘持久化存储 支持主从 支持分片(Redis3.0+) 为什么Redis能这么快 完全基于内存,绝大部分请求是纯粹的内存啊哦做,执行效率高 数据结构简单,对数据操作也简单 采用单线程,单线程也能处理高并发请求,想多核也可启动多实例 使用多路I/O复用模型,非阻塞IO 多路I/O复用模型 FD File Descriptor,文件描述符 一个打开的文件通过为疑似的描述符进行引用,该描述符是打开文件的元数据到文件本身的映射 传统的阻塞I/O模型 epoll/kqueue/evport/select Redis根据不同的操作系统,选择不同的多路复用函数 优先选择时间复杂度为O(1)的I/O多路复用函数作为底层实现 以时间复杂度为O(n)的select作为保底 基于react设计模式监听I/O事件 Select系统调用 说说你用过的Redis的数据类型 String 最基本的数据类型 二进制安全 可以包含任何数据,比如JPG图片或者序列化的对象 最大512M Hash String元素组成的字典,适合用于存储对象 List 列表,按照String元素插入顺序排序 大约能存储40亿个成员 Set String元素组成的无需集合,通过哈希表实现,不允许重复 Sorted Set 通过分数来为集合中的成员进行从小到大的排序 HyperLogLog 用于计数 Geo 支持存储地理位置信息 底层数据类型基础 简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表 对象 从海量Key里查询出某一固定前缀的Key KEYS pattern 查找所有复核给定模式pattern的key 一次性返回左右匹配的key 键的数量过大会导致服务器卡顿 SCAN cursor [MATCH pattern] [COUNT count]

数据库拾遗

本文整理自剑指Java面试-Offer直通车 如何设计一个关系型数据库 存储 文件系统 程序实例 存储管理 IO效率极低,所以数据库中的行在存储中没有实际意义,一般都是按块或页存储,一次IO读取多行数据 缓存机制 一旦某行数据被访问了,它周围的数据也极有可能被访问 缓存不宜过大,要有淘汰机制 SQL解析 将SQL编译解析,翻译成机器可识别的指令 缓存 日志管理 权限划分 多用户管理 容灾机制 从错误中恢复 索引管理 锁管理 为什么要使用索引 如果不使用索引,数据库会进行全表扫描,使用索引是为了尽量避免全表扫描,加快查询速度 全表扫描在数据量少的表中,查询效率反而更快 索引的灵感来自于字典 什么样的信息能成为索引 能把该记录限定在一定查找范围内的字段,即关键信息,如主键 主键、唯一键以及普通键等 索引的数据结构 平衡二叉树(不适合) 平衡二叉树查找效率为O(logn) 检索深度每加一,都要进行一次IO,严重影响查询效率 数据库的数据经过增删后,很容易变成线性结构,查询效率为O(n) 可通过树的旋转特性,使树保持为平衡二叉树 B-Tree(平衡多路查找树,不适合) 为了减少IO,需要把平衡二叉树变矮,使每个节点存储的数据变多,则成为了B-Tree 查找效率为O(logn) 与平衡二叉树相比,B-Tree可以通过合并、上移下移节点等保持结构 B+-Tree(适合,常用) 是对B-Tree优化后的一种数据类型,所有数据存在叶子节点中,非叶子节点只存储关键字,会比B-Tree更矮 叶子节点有链指针指向下一个叶子节点,可横向做统计 B+-Tree更适合来做存储索引 磁盘读写代价更低(数据都在叶子节点中,一次读取的索引更多) 查找效率更加稳定(非叶子节点只存索引,所有数据走的路径一样,效率O(logn)) 有利于数据库的扫描(链指针) Hash(小众) 缺点 仅能满足“=”,“IN”,不能使用范围查询 无法被用来避免数据的排序操作 不能利用部分索引建查询(组合索引中的某个索引,B+-Tree支持) 不能避免表扫描 遇到大量Hash值相等的情况后,性能并不一定比B-Tree索引高 BitMap(位图)索引 Oracle支持,MySQL不支持 只有几种值的情况(如性别),效率很高 新增修改的时候,通常会把同一个位图的数据都锁住 密集索引和稀疏索引的区别 密集索引文件中的每个搜索码值都对应一个索引值 叶子节点保存的不止是键值,还保存了位于同一行的其他列的信息 由于密集索引决定了表的物理排列顺序,一个表只能有一个密集索引 稀疏索引文件只为索引码的某些值建立索引项 叶子节点仅保存了键位信息以及该行数据的地址 有的稀疏索引仅保存了键位信息及其主键 定位到叶子节点后,还需要通过其中的信息,进一步定位到数据 MySQL中的InnoDB(聚簇) 必须定义一个密集索引 若一个逐渐被定义,则该主键座位密集索引 若没有主键被定义,则该表的第一个唯一非空索引作为密集索引 若不满足以上条件,InnoDB内部会生成一个隐藏主键(密集索引) MySQL中的MyISAM(非聚簇)

计算机网络拾遗

本文整理自剑指Java面试-Offer直通车 TCP 三次握手(建立连接) 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接 第一次握手:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认 第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态 第三次握手:客户端收到服务端的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手 TCP 四次挥手(释放连接) TCP采用四次挥手来释放连接 第一次挥手:客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态 第二次挥手:服务端收到FIN后,发送一个ACK给客户端,确认序列号为收到的序号+1(与SYN相同,一个FIN占用一个序号),服务端进入CLOSE_WAIT状态 第三次挥手:服务端发送一个FIN,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK状态 第四次挥手:客户端收到FIN后,进入TIME_WAIT状态,接着发送一个ACK给服务端,确认序号为收到的序号+1,服务端进入CLOSED状态,完成四次挥手 TIME_WAIT状态给服务端留有足够的时间收到客户端的ACK,如果服务端未收到ACK,会重发FIN TIME_WAIT状态避免数据包缓存(路由器缓存)影响到新连接 TCP 滑动窗口 保证可靠性 保证TCP的流控特性 在浏览器地址栏键入URL,按下回车之后经历的流程 DNS解析 TCP连接 发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束 HTTP 常见状态码 1xx:指示信息--表示请求已接收,继续处理 2xx:成功--表示请求已被成功接收、理解、接受 3xx:重定向--要完成请求必须进行更进一步的操作 4xx:客户端错误--请求有语法错误或请求无法实现 5xx:服务端错误--服务器未能实现合法请求 GET请求和POST请求的区别 HTTP报文层面:GET将请求信息放在URL,POST放在报文体中 数据库层面:GET符合幂等性和安全性(一般GET只做查询,不修改信息),POST不符合 其他层面:GET可以被缓存、被存储,而POST不行 Cookie和Session的区别 Cookie是服务端发送给客户端的特殊信息,以文本形式存放在客户端。客户端再次请求时,会携带Cookie信息,服务端因此可以解析Cookie Session是服务器的极值,保存在服务器上,解析客户端请求并操作sessionId,按需保存状态信息,可通过Cookie把sessionId发送给客户端,也可采用URL回写来实现(Cookie被禁用) HTTP和HTTPS的区别 HTTPS在HTTP和TCP/IP中间加了一层SSL(SSL3.0之后更名为TLS),是安全版的HTTP TLS采用身份认证和数据加密保证了网络通信的安全和数据的完整性 HTTPS数据传输流程 浏览器将支持的加密算法信息发送给服务器 服务器选择一套浏览器支持的加密算法,以证书的形式发回浏览器 浏览器验证证书合法性,并结合证书公钥加密信息发送给服务器 服务器使用私钥解密信息,验证哈希,加密响应消息返回给浏览器 浏览器解密响应信息,并对消息进行验真,之后进行加密交互数据 HTTPS需要到CA申请证书,需要一定的费用,HTTP不需要 HTTPS密文传输,HTTP明文传输 连接方式不同,HTTPS默认使用443端口,HTTP使用80端口 HTTPS=HTTP+加密+认证+完整性保护,比HTTP安全 HTTPS真的很完全吗 浏览器默认填充http://,请求需要进行跳转,有被劫持的风险 可以使用HSTS(HTTP Strict Transport Security)优化 Socket简介 Socket是对TCP/IP协议的抽象,是操作系统对外开放的接口 Socket通信流程

网络地址转换

实验前的 预习情况 一、NAT转换 NAT的实现方式有三种,即静态转换Static Nat、动态转换Dynamic Nat和端口多路复用OverLoad。 静态转换:指将内部网络的私有IP地址转换为公有IP地址,IP地址对是一对一的,是一成不变的,某个私有IP地址只转换为某个公有IP地址。借助于静态转换,可以实现外部网络对内部网络中某些特定设备(如服务器)的访问。 动态转换:指将内部网络的私有IP地址转换为公用IP地址时,IP地址是不确定的,是随机的,所有被授权访问上Internet的私有IP地址可随机转换为任何指定的合法IP地址。也就是说,只要指定哪些内部地址可以进行转换,以及用哪些合法地址作为外部地址时,就可以进行动态转换。动态转换可以使用多个合法外部地址集。当ISP提供的合法IP地址略少于网络内部的计算机数量时。可以采用动态转换的方式。 端口多路复用:指改变外出数据包的源端口并进行端口转换,即端口地址转换(PAT,Port Address Translation).采用端口多路复用方式。内部网络的所有主机均可共享一个合法外部IP地址实现对Internet的访问,从而可以最大限度地节约IP地址资源。同时,又可隐藏网络内部的所有主机,有效避免来自internet的攻击。因此,目前网络中应用最多的就是端口多路复用方式。 二、实验中用到的命令 1.配置串口: Router(config)#interface serial + 接口号 2.配置时钟频率: Router(config-if)#clock rate 64000 3.配置静态地址映射: Router(config)#ip nat inside source static 内部IP地址 要映射成的外网IP 4.定义内部接口: Router(config-if)#ip nat inside 5.定义外部接口: Router(config-if)#ip nat outside 6.定义默认路由: Router(config)#ip route 0.0.0.0 0.0.0.0 +下一跳IP 7.查看NAT表: Router#show ip nat translations 8.删除静态映射: Router(config)#no ip nat inside source static 之前设置的内部IP 外网IP 9.定义地址池: Router(config)#ip nat pool + 地址池名称 + 起始地址 + 末地址 netmask + 子网掩码

mysql show master status为空值

问题 执行show master status,输出结果为空: mysql> show master status; Empty set (0.00 sec) 原因 mysql没有开启日志。 查看log_bin选项: mysql> show variables like '%log_bin%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | log_bin | OFF | | log_bin_basename | | | log_bin_index | | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | | sql_log_bin | ON | +---------------------------------+-------+ 6 rows in set (0.00 sec) 可以看到log_bin是OFF. 解决方法 在mysql 配置文件 /etc/my.cnf中 [mysqld]下添加: log-bin=mysql-bin log-bin配置项表示binlog的base name,产生的日志文件名称类似,mysql-bin.

并行计算——C++ AMP(1)

之前做算法的并行优化加速时,学习过Nvida的CUDA框架,也了解过一些AMD的OpenCL的通用加速框架。最近发现了微软研究人员2011年开发的直接支持C++编程语言的C++AMP框架,简单易用,直接面向C++编程。抱着技多不压身的态度,准备系统的学习一下。 以下是C++ AMP 的简要概述,转自于: C++ AMP:用Visual C++加速大规模并行计算》——1.3 C++ AMP方法 C++ AMP:用Visual C++加速大规模并行计算 C++ AMP是一个并行库和语言层面的小扩展,能够帮助在C++应用程序中实现异构计算。(AMP是Accelerated Massive Parallelism的缩写,即加速大规模并行。)Visual Studio提供了新的工具和功能支持,可以用来调试和剖析C++ AMP应用程序的性能,包括GPU调试和GPU并行可视化。有了C++ AMP以后,主流C++开发人员可以使用熟悉的工具来创建可移植的、不会过时的应用程序,对于适宜数据并行的应用程序而言,能够实现显著加速。 1. C++ AMP将GPGPU(以及更多)带进主流 C++ AMP的使命之一是将GPGPU编程带给每一位开发者,使他们的应用程序可以从中获益。现在,支持C++ AMP的显卡几乎无处不在。然而,C++ AMP的首要任务不仅仅是GPGPU,它是一种利用异构计算平台的方法,例如GPU和CPU的向量处理单元,使数以百万计的主流开发人员能够创造性地使用异构平台。尽管说转向数据并行编程,尤其是用C++实现可移植性,是一项巨大的工程,但从软件开发实践的角度看,C++ AMP并非是第一个吃螃蟹的。 许多改变我们的行业和世界的技术或工艺都肇始于研究领域与学术界,这些技术和工艺起初仅被极少数的开发者所掌握,他们使用非常专业的工具,能够做到非常困难的事情。为改变行业和世界,这些技术走向大众,被视为主流。其他技术(例如GUI界面)也发生了这个过程。起初,只有少数开发者拥有诸如控制、响应鼠标事件这样的工作必需的专业技能。随着库、框架和工具的不断开发和发布,越来越多的开发人员能开发GUI应用程序了,现在这些都已成为规范。一些库、框架和工具比其他库、框架和工具更受欢迎,这些都使得GUI开发生态环境得以繁荣昌盛。 类似的过程在面向对象开发上也发生过。起初,当主流开发者还在使用过程化的方式开发应用时,少数学者就已经开始倡导新的软件设计和构建方式了。随着框架和工具的不断开发和发布,采纳规模已经达到了可以视面向对象开发为标准的程度,基本上大多数主流语言的所有开发者都在不同程度地使用它。 这种改变可能正发生在触摸界面和自然用户界面上,并行革命也势在必行。第一阶段是CPU并行,第二阶段是异构并行。要有工具、库和框架才能使异构计算变得更加容易和普遍。C++ AMP和Visual Studio正是主流开发人员需要的可以发挥GPU功能的工具、库和框架。 一个有趣的可能性是,主流开发人员可能会发现不直接使用C++ AMP也能从中获得好处。如果代码库的开发人员采用C++ AMP,使用这些库的代码无需了解底层库的做法就能获得加速。这一点对于创建面向特定领域的代码库而言很重要。 2. C++ AMP是C++,而不是C GPGPU的开发还有许多其他方法,这些方法都涉及类C语言。虽然C是一种功能强大的高性能语言,但C++仍然会是那些 喜欢使用现代程序设计语言来工作的注重性能的开发人员的头号选择。C++提供了抽象和类型安全的泛型,开发人员能够借此解决较大的问题,使用更强大的库和结构,我们使用C++ AMP时也可以使用这些特性。我们可以使用模板、重载和异常,就像我们在应用程序其他部分做的那样。 因为C++ AMP是C++,而不是C或类C的语言,所以我们进行并行开发所需要的额外类型,并不是语言本身的扩展或补充,而是模板类型。这为我们提供了类型安全的泛型——我们可以区分实数数组和整数数组,同时降低了学习曲线。增加C语言的抽象和有用类型是C++的主要设计目标之一。 标准C++(例如C++ 11)以前就支持CPU独享编程。C++并行模式库PPL以标准库的方式提供了一组类型和算法来支持C++多核开发,这使得C++开发人员可以运用他们正在使用的语言和工具来利用新硬件。C++ AMP为异构计算带来了同样的舒适和便利。 3. C++ AMP使用了我们熟识的工具 Visual Studio 2012已全面支持C++ AMP,Windows计算机也将马上可以使用C++ AMP了。这为在Visual Studio中使用C++的所有开发人员打开了方便之门。这些开发人员不需要学习新工具或新语言便能利用强大的GPU。但他们仍要掌握数据并行的思维方式,评估他们所做的算法和数据结构的决策的成本(以执行时间或功耗来计算)。借用熟悉的工具整体技能差距会被拉平。Visual Studio提供了智能感知、GPU调试、性能剖析,以及其他相关功能,这使得开发人员要做的事情远不止编写和编译代码。 即使对于不以Windows为目标平台的开发人员,Visual Studio也是很受欢迎的。更重要的是,C++ AMP开发并非仅限于Windows或Visual Studio用户,它已经发布成为一个开放的技术规范,其他厂商也正在将C++ AMP添加到他们的工具集中。例如,AMD决定把C++ AMP加入到他们的FSA参考编译器中,可以同时支持Windows平台和非Windows平台。 4. C++ AMP是一个近乎全面的代码库 用熟悉的程序语言编写代码主要是为了保持熟悉的感觉。C++ AMP是对C++的扩展,确实有两个C++11中没有声明的关键字。然而,也只是两个关键字而已,语言的变化并不大。此外,新的主关键字restrict在C99中有声明,因此是一个保留字,不太可能导致与现有代码库的冲突。C++ AMP的其他工作要素还有类型和函数库。对于熟悉标准库或PPL的开发人员,C++ AMP上手也会很快。

supervisor安装

[livingbody@localhost nodejstest]$ cnpm install -g supervisor Downloading supervisor to /usr/local/node-v10.13.0-linux-x64/lib/node_modules/supervisor_tmp Copying /usr/local/node-v10.13.0-linux-x64/lib/node_modules/supervisor_tmp/_supervisor@0.12.0@supervisor to /usr/local/node-v10.13.0-linux-x64/lib/node_modules/supervisor Installing supervisor's dependencies to /usr/local/node-v10.13.0-linux-x64/lib/node_modules/supervisor/node_modules All packages installed (used 3ms(network 2ms), speed 0B/s, json 0(0B), tarball 0B) [supervisor@0.12.0] link /usr/local/node-v10.13.0-linux-x64/bin/node-supervisor@ -> /usr/local/node-v10.13.0-linux-x64/lib/node_modules/supervisor/lib/cli-wrapper.js [supervisor@0.12.0] link /usr/local/node-v10.13.0-linux-x64/bin/supervisor@ -> /usr/local/node-v10.13.0-linux-x64/lib/node_modules/supervisor/lib/cli-wrapper.js 安装完后,可以用来启动node.js应用,当代码改动时,脚本会自动重启。 [livingbody@localhost nodejstest]$ supervisor app.js Running node-supervisor with program ‘app.js’ –watch ‘.’ –extensions ‘node,js’ –exec ‘node’ Starting child process with ‘node app.js’ Watching directory ‘/home/livingbody/nodejstest’ for changes. Press rs for restarting the process.

Android约束布局ConstraintLayout的使用

Android约束布局ConstraintLayout的基本使用 约束布局ConstraintLayout面世已有很长一段时间了,但我一直没有关注这个Android 中继五大布局后的新布局的使用。近日在网友的讨论的强烈推荐下,尝试了ConstraintLayout。使用之后的最大感触就是:为什么我不早点在项目中尝试ConstraintLayout!!! 本篇文章,旨在记录ConstraintLayout的使用,方便日后查阅和学习,项目地址点这里。 首先我们概括的说一下ConstraintLayout的优点。 从开发者的使用上来说:约束布局就是一个强力升级版的RelativeLayout,RelativeLayout能实现的ConstraintLayout也能实现,RelativeLayout不能实现的ConstraintLayout也能实现。 从性能上来说:使用ConstraintLayout的布局基本上不存在ViewGroup的多层级嵌套,我们知道View的绘制是从顶层开始,以遍历的形式完成整个界面的measure、layout、draw。所以在复杂布局的绘制上ConstraintLayout具有一定的性能优势。 ConstraintLayout不仅功能更强大而且性能也比使用其他布局更好,我想这就是为什么Google强烈推荐使用ConstraintLayout的原因吧。而对我们开发者来说,有好用的东西就要积极拥抱。 一、RelativeLayout能完成的ConstraintLayout也能完成 我们先从绘制一个简单布局来开始ConstraintLayout的实战应用(如果你对约束布局一点也不了解可以先看看这篇Android新特性介绍,ConstraintLayout完全解析。) 在这个布局中共有5个控件,我们一个个的来拖拽。 1.先拖一个ImageView 创建布局将底部tab切换到Design,拖出一个ImageView放到左上角给他设置constraint(约束规则)和控件尺寸大小。 2.拖拽中间的三个TextView 设置最上面的TextView约束:其top和ImageView的top对齐,其left和ImageView的right对齐,并设置margin_left。 中间的TextView约束:其top和最上面的TextView的bottom对齐设置margin,其right和最上面的TextView的right对齐。 底部TextVeiw的约束:其bottom和ImageView的bottom对齐,其right和最上面的TextView的right对齐。 3.最右边“立即申请”TextView 我们观察到“立即申请”位于parent右侧且纵向居中的位置,所以我们要设置它的约束如图所示: 其top和bottom分别于ImageView的top和bottom对齐,表示在ImageView纵向范围内垂直居中; 此外,还要将中间第2个TextView 的右边和该控件的左边对齐,然后设置中间第二个TextView的width为match_constraint,否则中间第二个TextView将会位于ImageView和该控件横向中间的位置。 此部分代码如下所示: <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".SecondActivity"> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginLeft="16dp" android:text="哈哈哈" android:textColor="#333333" android:textSize="18sp" app:layout_constraintStart_toEndOf="@+id/imageView" app:layout_constraintTop_toTopOf="@+id/imageView" /> <TextView android:id="@+id/tv_content" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginEnd="4dp" android:layout_marginRight="4dp" android:ellipsize="end" android:maxLines="2" android:text="哈哈哈,你是不是傻子么呀。哈哈哈,你是不是傻子么呀" android:textSize="16sp" app:layout_constraintEnd_toStartOf="@+id/tv_apply" app:layout_constraintStart_toStartOf="@+id/textView3" app:layout_constraintTop_toBottomOf="@+id/textView3" /> <TextView android:id="@+id/tv_apply" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="10dp" android:layout_marginRight="10dp" android:paddingBottom="@dimen/dp_10" android:paddingTop="@dimen/dp_10" android:text="立即申请" android:textColor="

可能是全网唯一一个基于windows和java的关于selenium webDriver绕过网站反爬服务的方法

事情的起因是我需要用selenium的webDriver技术实现一些简单操作,一直用的是chrome和配套的webDriver(chrome的强大和轻量化真的是无敌的),但是突然有一天发现有些网站我用webDriver启动的浏览器是怎么也登录不进去(本来是用自动化登录的,现在人工登录都不行),于是开始在google上找答案,发现chrome和firfox默认的驱动都会被反爬服务识别出来: webdriver.chrome.driver webdriver.firefox.bin IE就算了,调试查看标签的时候简直没法用,我就突然想到firefox不是还有一个驱动么,是三方的驱动: webdriver.gecko.driver 那我用这个驱动试试会不会触发反爬吧,结果跟我预想的一样,可以登录,没有触发反爬机制,我那个高兴啊,高兴的劲儿还没持续多久,又碰到一个问题,之前用selenium里面的Actions类可以实现移动鼠标,拖拽,释放等动作,但是我用decko驱动的话就会报错,怎么办呢,接着查google呗,这个真的查了好一阵,发现了这个回复: GeckoDrive不支持Actions,这下心可就凉了,绕了一圈,好不容易发现一条路,走了一段,发现是条死路。最后找到了一个关键字,爬虫和反爬虫,根据这个思路,用chromeDriver越过了爬虫机制,下面是实现方法。 现在绝大部分网站的反爬策略中都加入了webdriver检测,如果检测到了webdriver则无论如何也不让你过去,还有一种更绝,直接把你的ip封掉,你会发现你正常操作也无法访问网站了。 方法思路:基于mitmproxy代理,把请求中的webdriver隐藏掉即可。 第一步,你得装个mitmproxy,除了最新版,稍微老一点的版本有exe的安装文件,下载后直接安装即可,安装完后在安装目录的bin目录下有两个exe文件,mitmdump.exe和mitmweb.exe,这里我们主要使用mitmdump.exe 第二步,我们需要写一个隐藏webdriver字段的脚本,脚本文件用python编写(我的python版本是3.7.1貌似3.6也可以),脚本如下(感谢大神提供的脚本:https://zhuanlan.zhihu.com/p/43581988): indject_js_proxy.py from mitmproxy import ctx injected_javascript = ''' // overwrite the `languages` property to use a custom getter Object.defineProperty(navigator, "languages", { get: function() { return ["zh-CN","zh","zh-TW","en-US","en"]; } }); // Overwrite the `plugins` property to use a custom getter. Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5], }); // Pass the Webdriver test Object.defineProperty(navigator, 'webdriver', { get: () => false, }); // Pass the Chrome Test.