微信公众平台服务号配置JS接口安全域名

微信公众平台服务号配置JS接口安全域名 一、注意事项: 1、可填写三个域名或路径(例:wx.qq.com或wx.qq.com/mp),需使用字母、数字及“-”的组合,不支持IP地址、端口号及短链域名。 2、填写的域名须通过ICP备案的验证。 3、 将文件MP_verify_.txt(点击下载)上传至填写域名或路径指向的web服务器(或虚拟主机)的目录(若填写域名,将文件放置在域名根目录下,例如wx.qq.com/MP_verify_.txt;若填写路径,将文件放置在路径目录下,例如wx.qq.com/mp/MP_verify_.txt),并确保可以访问。 二、若应用工程在Tomcat 8.5上部署,则配置如下即可: 参考文件:http://www.qchcloud.cn/tn/article/36

Pandas - A value is trying to be set on a copy of a slice from a DataFrame

(想要直接解决问题的请直接拉到最后) 使用的DataFrame的 yearstatepopdebtone2000Ohio1.5NaNtwo1000Ohio1.71000three2002Ohio3.6NaNfour2001Nevada2.4-1.5five2002Nevada2.9-1.7 当使用 frame2['year']['two'] = 10000, 即df名[列名][行名]的方式去赋值就会报错, 提示如下 SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy 进入提示网页, 查找与SettingWithCopyWarning有关部分, 这里简单翻译了一下(渣翻译, 推荐大家去看原文, 在最后几部分里) chained indexing 这就是出现警告的原因, 我们在使用pandas中要极力避免出现chained index) 下面是一个例子解释到底什么是chained indexing In [4]: dfmi = pd.DataFrame([list('abcd'), list('efgh'), list('ijkl'), list('mnop')], ...: columns=pd.MultiIndex.from_product([['one', 'two'], ['first', 'second']])) ...: In [5]: dfmi Out[5]: one two first second first second 0 a b c d 1 e f g h 2 i j k l 3 m n o p 我们通过两种不同的方式去访问同一值

Linux系统挂起进程的几种方法

Linux系统挂起进程的几种方法 法一 nohup run.sh & --> 输入 exit 推出,会自动 将 输出 写到 当前目录下的 nohup.txt里 法二 使用 tmux 的方法 tmux 使用命令: Mac: yum install tmux -y Ubuntu: sudo apt-get install tmux 命名会话 tmux new -s session tmux new -s session_blake -d #在后台建立会话 tmux ls #列出会话 tmux attach -t session_blake #进入某个会话 【 进入某个 session 后: 启动程序命令的时候,因为已经是后台了,就没必要在加上 & (表示取地址符了),否则,在推出 session 使用 Ctrl+b d 的时候,刚刚启动的进程就会被终止 进程处于 T 的状态,不能正常工作。】 关闭会话: tmux kill-session -t 会话名 最实用的命令: Ctrl+b d 退出tumx,并保存当前会话,这时,tmux仍在后台运行,可以通过tmux attach进入到指定的会话; Ctrl+b s 以菜单方式显示和选择会话

C++ template的使用

1、template的使用 C++ 的高级玩法,当然包含了模板。模板(template)是实现代码重用机制的一种工具,它可以实现类型参数化,把类型定义为参数(模板元编程),从而实现了真正的代码可重用性。 模板是用来批量生成功能和形式都几乎相同的代码的。编译器就能在需要的时候,根据模板自动生成程序的代码。从同一个模板自动生成的代码,形式几乎是一样的。 模板就像一个做饼干的模具,至于饼干是什么味道,则要看具体实例化时制作饼干的材料。 模板可以分为两类,一个是函数模板,另外一个是类模板。 1.1、函数模板 函数模板比较简单,下面我们来看一个两者交换的例子就明白了: template<typename T> void swap(T& t1, T& t2) { T temp = t2; t2 = t1; t1 = temp; } 1.2、类模板 类模板比函数模板稍微复杂一下,主要是实现时的书写,如下面的代码: //stack.h template<typename T> class Stack { public: Stack(); ~Stack(); void push(T t); T pop(); bool isEmpty(); private: T* m_pT; int m_maxSize; int m_size; }; //Stack.cpp #include "Stack.h" template<typename T> Stack<T>::Stack() { m_maxSize = 100; m_size = 0; m_pT = new T[m_maxSize]; } template<typename T> Stack<T>::~Stack() { delete[] m_pT; m_pT = nullptr; } template<typename T> void Stack<T>::push(T t) { m_size++; m_pT[m_size - 1] = t; } template<typename T> T Stack<T>::pop() { T t = m_pT[m_size - 1]; m_size--; return t; } template<typename T> bool Stack<T>::isEmpty() { return m_size == 0; } 上述类模板是模仿了一个栈,这个栈很简单,最多只能支持100个元素入栈。

vue的model选项

今天在看vue-property-decorator时,遇到了@Model选项,也就是vue2.2中新增的实例model选项。原来只知道v-model属性实现双向绑定,对这个model选项突然不是很理解。所以这里重新对v-model和自定义组件的v-model做一个回顾,加深印象后,再去理解model选项到底是做什么的,有什么作用。 vue中的v-model指令实现了表单的双向绑定,这是官网的一个栗子: <input type="text" v-model="message"> <p>{{message}}</p> v-model只是语法糖,真正的实现形式: <input type="text" :value="message" @input="message = $event.target.value"> 1.将输入框的值绑定到message变量上,这只是单向的,改变message的值可以改变input的value,但是改变input的输入不会改变message。 2.监听input事件,当输入类内容时改变message变量,从而实现了双向绑定。 从官网上看到,v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件: text和textarea元素使用value属性和input事件 checkbox和radio使用checked属性和change事件 select使用value和change事件 那么我们知道原理后,可以试着实现自定义输入框组件的v-model,即双向绑定 // js部分 Vue.component('custom-input',{ // 1.监听input,输入时触发自定义组件内部的updateVal事件 template: `<input :value='value' @input='updateVal($event.target.value)' type='text'></input>`, // 5.通过props传递,实现父组件值绑定到输入框的value props: ['value'], methods: { // 2.触发父组件上的input事件 updateVal(val){ this.$emit('input', val); } } }); var app = new Vue({ el: '#app', data(){ price: '' }, methods: { // 3.传递过来的值赋给父组件的price变量,实现了输入框到父元素的单向绑定 onInput(val){ this.price = val; } } }) // HTML部分 <div id="

解决room重复插入数据

我设置的是消息时间为主键 /** * 消息时间 */ @NonNull @PrimaryKey private String messageTime; 插入的时候如果重复则替换 @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(singleMessage: SingleMessage)

机器学习与应用—学习笔记

文章目录 机器学习简介数学知识微积分和线性代数导数向量与矩阵偏导数与梯度雅克比矩阵Hessian矩阵行列式特征值和特征向量二次型向量与矩阵求导 最优化方法梯度下降法牛顿法坐标下降法拉格朗日乘数法凸优化拉格朗日对偶KKT条件 概率论随机事件与概率条件概率随机变量数学期望与方差随机向量最大似然估计 机器学习基本概念算法分类模型评价指标准确率精准率召回率真正(阳)率 假正(阳)率ROC 曲线混淆矩阵交叉验证 模型选择过拟合与欠拟合偏差与方差分解正则化 贝叶斯分类器决策树K近邻算法参考资料 机器学习简介 机器学习的训练过程是通过训练样本寻找分类函数或模型的过程。有监督(聚类和数据降维没有训练过程)的机器学习的一般流程如下图所示,机器学习算法与其它算法的一个显著的区别是需要样本数据,是一种数据驱动的方法。 机器学习(Machine Learning)是人工智能的分支和一种实现方法,根据样本数据学习模型,用模型对数据进行预测与决策,也称为推理(inference)。机器学习是让计算机算法具有类似人的学习能力,像人一样能够从实例中学习到经验和知识,从而具备判断和预测的能力。机器学习的本质是模型的选择以及模型参数的确定。机器学习与之前基于人工规则的模型(逻辑推理、知识库、专家系统)相比,无需人工给出规则,而让程序自动从大量的样本中抽象、归纳出知识与规则。因此,它具有更好的通用性,采用这种统一的处理框架,可以将机器学习算法用于各种不同的领域。 数学知识 微积分和线性代数 导数 导数定义为函数的自变量变化值趋向于0时,函数值的变化量与自变量的变化量比值的极限,即: 如果上面的极限存在,则称函数在该点处可导。导数的几何意义是函数在某一点处的切线的斜率,典型的物理意义是瞬时速度。 导数和函数的单调性密切相关。导数大于0时函数单调增,导数小于0时函数单调减,在极值处导数必为0。导数为0的点称为函数的驻点。 二阶导数决定函数的凹凸性。如果二阶导数大于0,则函数为凸函数;如果二阶导数小于0,则为凹函数。二阶导数等于0的点称为函数的拐点。 根据一阶导数和二阶导数,可以得到一元函数的极值判别法:在驻点处,如果二阶导数大于0,则为函数的极小值点,如果二阶导数小于0,则为极大值点。如果二阶导数等于0,则情况不定。 向量与矩阵 向量是有大小和方向的量,由多个数构成一维数组,每个数称为它的分量。分量的数量称为向量的维数。物理中的力,速度是典型的向量。 如果两个向量的内积为0,则称它们正交,这是几何中垂直这个概念在高维空间的推广。 偏导数与梯度 梯度和 函数的单调性、极值有关 根据Fermat 定理,可导函数在某一 点处取得极值的必要条件是梯度为 0,梯度为0 的点称为函数的驻点 。需要 注意的是,梯度为0 只是函数取极值的必要条件而不是充分条件。 雅克比矩阵 雅克比矩阵可以简化多元复合函数求导的公式。 Hessian矩阵 其中,o表示高阶无穷小。H是Hessian矩阵。它和一元函数的泰勒展开在形式上是统一的。 行列式 特征值和特征向量 二次型 向量与矩阵求导 最优化方法 最优化即寻找函数极值点的数值方法。将最优化问题统一表述为求解函数的极小值问题(极大值问题通过目标函数加负号的方式转换为极小值问题)。对优化变量有约束(等式约束和不等式约束),定义了优化变量的可行域,即满足约束条件的点构成的集合。 梯度下降法 梯度下降法沿梯度向量的反方向进行迭代以达到函数的极值点。 牛顿法 坐标下降法 坐标下降法每次迭代时在当前点处沿一个坐标轴方向进行一维搜索,固定其他的坐标方向,找到一个一元函数的极小值。在整个过程中依次循环使用不同的坐标方向进行迭代,一个周期的一维搜索迭代过程相当于一个梯度迭代。 拉格朗日乘数法 凸优化 求解一般函数的全局极小值是非常困难的,如果目标函数限制为凸函数、优化变量的可行域限定为凸集,同时满足这两个限定条件的最优化问题称为凸优化问题。 拉格朗日对偶 对偶是求解最优化问题的一种手段,它将一个最优化问题转化为另外一个更容易求解的问题。这两个问题是等价的。 KKT条件 概率论 随机事件与概率 条件概率 随机变量 数学期望与方差 随机向量 随机向量是一个向量,它的每个分量都是随机变量。随机向量也有离散型和连续型两种情况。 最大似然估计 已知样本服从的分布,要估计分布函数的参数,确定这些参数常用的一种方法是最大似然估计。 最大似然估计(Maximum Likelihood Estimate,MLE)构造一个似然函数,通过让似然函数最大化,求解出参数。最大似然估计的直观解释是。寻求一组参数,使得给定的样本集出现的概率最大。这样做的依据是这组样本数据已经发生了,因此,应该最大化它们发生的概率,即似然函数。 机器学习基本概念 算法分类 机器学习算法 有监督学习 标签值类型 求解的方法 分类问题 决策函数 线性函数 线性支持向量机 logistic回归 非线性函数 非线性核的支持向量机 人工神经网络 决策树 二分类 多分类 精度与召回率 混淆矩阵 常用指标 准确率 回归问题 评价指标 回归误差 生成模型 根据标签值生成随机的样本数据 贝叶斯分类器 高斯混合模型 隐马尔科夫模型 受限玻尔兹曼机 生成对抗网络 判别模型 根据样本特征向量值判断它的标签值 KNN算法 支持向量机 Adaboost算法 泛化能力 过拟合 欠拟合 无监督学习 聚类 表示学习 自动编码器 降维 半监督学习 无标签样本和标签样本混合 强化学习 根据输入的环境数据确定要执行的动作 模型评价指标 准确率 准确率的定义是预测正确的结果占总样本的百分比,其公式如下:

远程服务器卡死,不能访问。

问题: 1.应用发布在另外一台服务器上,访问的时候,浏览器处于假死状态,甚至不能访问。 解决办法: 1.在操作远程服务器时,发现tomcat的启动窗口处于选择状态。鼠标移出黑窗口,消除选择状态,即可正常访问。

编译原理 —— 递归下降分析法

什么是递归下降分析法 递归下降分析法是确定的自上而下分析法,这种分析法要求文法是LL(1)文法。 为每个非终结符编制一个递归下降分析函数,每个函数名是相应的非终结符,函数体则是根据规则右部符号串的结构和顺序编写。子程序相互递归调用。 示例 设有 LL(1) 文法如下 试构造一个识别该文法句子的递归下降分析程序。 解: 总结 优点:递归下降分析法简单、直观,易于构造分析程序。 缺点:对文法要求高,必须是LL(1)文法,同时由于递归调用较多,影响分析器的效率。

idea lombok简介及报红、报错解决办法

idea lombok lombok简介 Lombok 是能自动接通编辑器和构建工具的一个Java库,对于简单的Java对象,通过注解的形式例如@Setter @Getter,可以替代代码中的getter和setter方法。Lombok中用到了注解,但是它并没有用到反射,而是在代码编译时期动态将注解替换为具体的代码。所以JVM实际运行的代码,和我们手动编写的包含了各种工具方法的类相同。 lombok 注解 val: final 像动态语言一样,声明一个fianl的变量。var: 同JDK10@Data:注解在类上,将类提供的所有属性都添加get、set方法,并添加、equals、canEquals、hashCode、toString方法@Setter:注解在类上,为所有属性添加set方法、注解在属性上为该属性提供set方法@Getter:注解在类上,为所有的属性添加get方法、注解在属性上为该属性提供get方法@NotNull:在参数中使用时,如果调用时传了null值,就会抛出空指针异常@Synchronized 用于方法,可以锁定指定的对象,如果不指定,则默认创建一个对象锁定@Log作用于类,创建一个log属性@Builder:使用builder模式创建对象@NoArgsConstructor:创建一个无参构造函数@AllArgsConstructor:创建一个全参构造函数@ToString:创建一个toString方法@Accessors(chain = true)使用链式设置属性,set方法返回的是this对象。@RequiredArgsConstructor:创建对象, 例: 在class上添加 @RequiredArgsConstructor(staticName = “of”)会创建生成一个静态方法@UtilityClass:工具类@ExtensionMethod:设置父类@FieldDefaults:设置属性的使用范围,如private、public等,也可以设置属性是否被final修饰。@Cleanup: 关闭流、连接点。@EqualsAndHashCode:重写equals和hashcode方法。@toString:创建toString方法。@Cleanup: 用于流等可以不需要关闭使用流对象. lombok报错解决办法: 1.use compiler 选择javac 2.勾选enable annotation processing 3.安装后需重启idea,使插件生效 4.maven版本与idea lombok 版本不一致 4. idea2018版本 IntelliJ IDEA 2018.1.5\plugins\android\lib\templates\gradle\wrapper\gradle\wrapper idea安装目录下 gradle-wrapper.properties文件增加一行 ideaVersion=2018.1 重启idea后手动安装lombok插件再次重启

Ubuntu18.04下编译Linux0.12笔记(编译+调试学习1)

一、下载源代码 网站:http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/ 注:上面的网站下载速度十分快。官网的代码下载速度很慢,不知道怎么搞的。 二、安装x86的as86和ld86 (查找as86和ld86两个工具所在的软件包)输入 apt-cache search as86 ld86 获取as86和ld86所在的安装包名称。 此时终端可能提示: “bin86 - 16-bit x86 assembler and loader”,说明bin86包含了我们所需要的两个软件。 sudo apt install bin86 在bootsect.S中,as86无法识别c语言的注释,需要在前面加上!注释。 三、 make---错误1: cpp -nostdinc -Iinclude -traditional boot/bootsect.S -o boot/bootsect.s as86 -0 -a -o boot/bootsect.o boot/bootsect.s ld86 -0 -s -o boot/bootsect boot/bootsect.o cpp -nostdinc -Iinclude -traditional boot/setup.S -o boot/setup.s as86 -0 -a -o boot/setup.o boot/setup.s ld86 -0 -s -o boot/setup boot/setup.o gas -c -o boot/head.o boot/head.s make: gas: Command not found Makefile:35: recipe for target 'boot/head.

编译原理 —— 正规文法转换为正规式

正规文法与正规式都是描述正规集的工具。对任意一个正规文法,存在定义统一语言的正规式;反之,对每个正规式存在一个生成同一语言的正规文法。 对任何正规文法G,存在定义同一语言的正规式 r 求解过程 ① 将文法中的规则写成关于每个非终结符的正规式方程,得到一个方程组; ② 依照求解规则: 若 A = α A ∣ β A=αA |β A=αA∣β,则解为 A = α ∗ β A= α^*β A=α∗β;若 A = A α ∣ β A=Aα |β A=Aα∣β,则解为 A = β α ∗ A= βα^* A=βα∗; 示例 设有正规文法G: A→ aB | bBB→ aC | a | bC→ aB 试给出该文法生成语言的正规式 解:首先给出相应的正规式方程组(方程组中用“+”代替正规式中的“|”)如下: ① A = aB + bB② B = aC + a + b③ C = aB 把 ③ 式代入 ② 式得

Cloudera Impala RPM安装

官方文档地址,建议通读以下2篇文章: https://www.cloudera.com/documentation/enterprise/5-6-x/topics/impala_noncm_installation.html https://www.cloudera.com/documentation/enterprise/5-6-x/topics/impala_config_options.html 在使用RPM安装之前,我花了一天时间去使用源码编译安装,由于官方文档以及网上没有太多关于源码安装的方法,最后编译完成也无法使用。关于这一点,我感觉Cloudera是故意的。 RPM安装总体比较简单,步骤如下: 1. 新建impala用户及组 groupadd impala useradd -g impala impal 2. 配置CDH yum源,下面的源是我使用CDH5的改了一下baseurl及gpgkey. [root@xxxx catalog]# cat /etc/yum.repos.d/cloudera-cdh6.repo [cloudera-cdh6] # Packages for Cloudera's Distribution for Hadoop, Version 5, on RedHat or CentOS 6 x86_64 name=Cloudera's Distribution for Hadoop, Version 6 baseurl=https://archive.cloudera.com/cdh6/6.2.0/redhat6/yum/ gpgkey =https://archive.cloudera.com/cdh6/6.2.0/redhat6/yum/RPM-GPG-KEY-cloudera gpgcheck = 1 3. 安装impala-server, impala-catalogd, impala statestore $ sudo yum install impala # Binaries for daemons $ sudo yum install impala-server # Service start/stop script $ sudo yum install impala-state-store # Service start/stop script $ sudo yum install impala-catalog # Service start/stop script $ sudo yum install impala-shell 安装impala会有相当多的依赖包,总共大约1G,我粗略的看了一下,https://archive.

C++Builder的基本功能

C++Builder的基本功能 我们用高级语言写程序,我们很得意,因为高级语言比较接近人类的语言,使我们用起来得心应手,所以我们当然得意。但我们更得意的一定是让程序代码赶快变成可执行文件。 无论是在写代码的过程,还是最后要编译成可执行文件,都需要有一个工具存在。这一工具一般称为编程集成环境(IDE)。之所以称为集成,是因为从写代码到最后软件的出炉,我们需要它的地方实在太多了,这里列出其中最重要的功能项。 1、代码编辑:方便的代码编辑功能。尽管你可以使用记事本、Word或其它任何文本编辑器来写代码,但除非特殊需要,否则那将是极为低效的方法。相反,现在的编程集成环境,都相当的智能,举例如:代码自动功能,可以在很多情况下自动完成我们所需的代码,既准确还迅速。Borland公司出品的编程集成环境不仅有常见的关键字高亮等功能,还支持代码模板,支持键盘宏,同样支持高级的脚本插件功能。 2、界面设计:可视化的程序界面设计功能。你所要产生的窗口,在设计期间就真实地出现,包括字体、颜色和定位。比如:你不仅可以插入falsh的动画,而且无需运行,就直接可以在你的界面上看到该动画的演播,这是别的编程环境不能做到的。 3、程序编译:这是编程工具的主要功能。我们写的代码在成为机器能懂的可执行程序时,必须通过编译。 4、程序调试:如何尽量减少你程序的BUG呢?没有编程集成环境提供的强大调试功能,我们做的程序将毫无质量保证。 5、代码优化:Borland 提供的编译器,不仅在编译速度上一直在美国屡获大奖,而且其代码自动优化功能一直领先对手几近一个时代。使用编程集成环境,我们可以轻松获得更快更优的最终可执行程序文件。 6、辅助程序安装:程序的安装已属于另外一种工具的范畴,但我们仍可以通过编程集成环境来决定最终生成单一可执行文件,还是带有其它动态库。如果是后者,我们还可以通过集成环境来检查程序运行时调用了哪些动态库文件。C++Builder 提供的功能远不止我上面所说的,并不是因为我嘴笨,而是我认为对一个工具,你只有动手使用,才会真正了解它。C++是一门语言,而Borland C++Builder 则是语言实现工具。作为一个编程工具,CB提供以上功能正是份内之事。在这个意义上,你可以认为CB是Word2000,而C++则是英语或汉语。正如我们用英语或汉语在Word2000上写出优美文章,编程可说为:我们用C++语言在CB上编写出优美的程序。 VCL vs. MFC 在作为一种编程工具的意义上,我们认为C++Builder和你也许常听的VC(Visual C++)没有什么本质的区别。就像Word2000和WPS2000在本质都是字处理软件。但现在我们要从另外一个角度讨论C++ Builde这个编程工具。这个角度就是“封装”——面向对象编程思想中的最重要也是最基础的概念。 一个要学习编程的人,可能从C开始学起。学C时,我们没有接触那些挺玄的概念,到了C++,一切就来了,什么面向对象,什么封装、继承、多态……于是我们兴奋起来,努力去理解、掌握,运用这些概念所代表的技术,在掌握这些别人暂时未能理解的概念之后而颇有成就感……。 现在我要问的是,为什么要有这些概念?这些技术?正确回答这个问题,不仅有助于我们今后对编程语言各种概念的学习,而且它能让我们避免成为新技术的奴隶,这一切也许听起来有些形而上,不过我想通过以下讨论,至少可以回答一个很现实的问题:为什么要选C++Builder?而不是我们更常听的VC?这是我碰到的编程初学者较疑惑的问题之一。 如果人类长有翅膀,那么飞机大抵永远不会被发明。飞机的发明,是为了弥补人类自已不能飞翔的缺陷。不能说所有的技术都是这样,但C++对于C的发展,完全是为弥补程序员脑力的不足。一个在校生在学会C后,往往并没有机会用C去实践一个大中型的项目,体会不到在一个庞大软件工程中,非面向对象语言的短处,所以在之后学习C++的过程中,也就很难真正体会到面向对象语言的长处。简短一点说:不知道C的短处,就不懂C++的长处。相反,倒是很快就发现C++的缺点:它的代码效率多数情况下都要比C低不少。 前面我们说过低级语言与高级语言的对比,C++语言也正是从语法结构和语言功能上来限定或实现一门编程语言更加接近人在现实生活中的思维习惯,从而达到减轻人的记忆和判断上的负担。这其中最佳的方法之一就是所谓的“封装”。 VC的封装类库称为MFC,它是一种很低阶的封装,它并没有按照人类的思维习惯来重新组织和解释Windows对象(指Windows编程中所需的数据,处理,机制,接口), 而纯粹是API一对一的翻版。这样的封装工作带来代码封装所固有的代码效率降低的副作用,却没有给使用者带来任何方便。如果你是编程初学者,而你身边又有VC高手,那么你一定要多多向他学习请教,因为一个真正的VC编程高手,其同时一定也是一个深刻理解Windows内核机制(消息循环,内存管理,多任务实现,资源使用等),熟悉Windows各种常用API函数等等的高手。 C++Builder对封装库称为VCL(带VC字样,可别以为它是Visual C++,其实它是:Visual Component Library,即:可视控件库)。 VC的MFC和CB的VCL都是基于(但不限于)对Windows API(应用程序接口函数)的封装,为什么要对API进行封装?这就是回到了我们前面说过的,为什么有了C又会有C++的问题。因为操作系统是用C和汇编写成的,它获得到操作系统必须的代码效率,但对应用程序开发者而言,它失去了易用性。所以微软和Borland都使用高级语言对之进行封装工作。二者谁进行得更好呢? 要想成为Windows编程高手,最终一定要绕过各种封装,理解Windows对象。但作为一个初学者,我们必须挑选一个好的封装。下面我们举字体(Font)作为例子,将三者:没有封装过的Windows 字体API、封装过的MFC字体对象和封装过的VCL字体对象做一个对比。为了保证不会有偏倚和差错,有关前二者的代码,都是笔者从MSDN(微软提供的帮助文档)中直接拷贝出来。 Window API Windows API创建指定样式字体: HFONT CreateFont( int nHeight, // height of font int nWidth, // average character width int nEscapement, // angle of escapement int nOrientation, // base-line orientation angle int fnWeight, // font weight DWORD fdwItalic, // italic attribute option DWORD fdwUnderline, // underline attribute option DWORD fdwStrikeOut, // strikeout attribute option DWORD fdwCharSet, // character set identifier DWORD fdwOutputPrecision, // output precision DWORD fdwClipPrecision, // clipping precision DWORD fdwQuality, // output quality DWORD fdwPitchAndFamily, // pitch and family LPCTSTR lpszFace // typeface name

tensorflow中关于 多维tensor的运算(tf.multiply, tf.matmul, tf.tensordot)

multiply 等同与* ,用于计算矩阵之间的element-wise 乘法,要求矩阵的形状必须一致(或者是其中一个维度为1),否则会报错: import tensorflow as tf a = tf.constant([1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12], shape=[2, 3, 2]) b = tf.constant([1, 2, 3, 4, 5, 6], shape=[2, 3, 1]) c = a*b e = tf.multiply(a, a) with tf.Session(): print(a.eval()) print(b.eval()) print(c.eval()) print(d.eval()) print(e.eval()) >> a [[[ 1 2] [ 3 4] [ 5 6]] [[ 7 8] [ 9 10] [11 12]]] >>b [[[1] [2] [3]] [[4] [5] [6]]] >>a*b [[[ 1 2] [ 6 8] [15 18]] [[28 32] [45 50] [66 72]]] >>multiply(a, b) [[[ 1 2] [ 6 8] [15 18]] [[28 32] [45 50] [66 72]]] >>multiply(a,a) [[[ 1 4] [ 9 16] [ 25 36]] [[ 49 64] [ 81 100] [121 144]]] 更改b的形状:

Kotlin 个人踩坑

1. kotlin的Null Safety很方便。但是在和java做interop的时候需要额外小心。 例,java的List可能为空对象,kotlin的List为非空对象。 将一个java List转成kotlin List后,list?.forEach{...}, intellij会提示冗余的非空检查,使用list.forEach{...}就可以了。 但是非空检查其实是有必要的。尤其是调用java第三方类库的时候,可能返回空值。 2.扩展方法重名的问题。 kotlin允许对类(Class)添加扩展方法。 调用的时候直接通过obj.extensionMethod{...}即可,本意是提供更多的语法糖。但是随着引入类库的增多,及自定义扩展方法的增多,会出现不同实现的同名方法。都是通过obj.extensionMethod{...}调用。 需要额外小心选择正确的方法导入,建议不要开启intellij的自动导入,可能会导入错误的实现。 比如,List.flatMap{...}在kotlin.Collection和arrow库中都存在,但实现方式不同,返回值不同,按需正确导入调用。

spring boot 返回jsp页面添加依赖

<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> </dependency>

[Halcon] detect_indent_fft.hdev

* This program demonstrates how to detect small texture * defects on the surface of plastic items by using the fast * fourier transform (FFT). * First, we construct a suitable filter using Gaussian * filters. Then, the images and the filter are convolved * by using fast fourier transforms. Finally, the defects * are detected in the filtered images by using * morphology operators. * * Initializations dev_update_off () dev_close_window () read_image (Image, 'plastics/plastics_01') get_image_size (Image, Width, Height) dev_open_window (0, 0, Width, Height, 'black', WindowHandle) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') dev_set_draw ('margin') dev_set_line_width (3) dev_set_color ('red') * * Optimize the fft speed for the specific image size optimize_rft_speed (Width, Height, 'standard') * * Construct a suitable filter by combining two gaussian * filters Sigma1 := 10.

osg如何能在程序中改变视点的位置?如何不改变相机的位置来切换操作器

这个问题一直困扰可很久,因为没有认真去看osg源码导致的。 1.在网上收集的资料很多都是 利用osg::carmea 的void setViewMatrixAsLookAt(const osg::Vec3d& eye,const osg::Vec3d& center,const osg::Vec3d& up);这样做能够做到,但是前提是不能使用viewer-》run()。因为viwer->run();会判断场景是否存在操作器,米有的话会自动添加操作器,从而抵消setViewMatrixAsLookAt()函数的操作。 2.还可以利用 cameraManipulator->setHomePosition(m_vPosEye, location, vUp); 但是etHomePosition(m_vPosEye, location, vUp);使用过程中会出现很多问题,因为这个函数原本的目的是为了home()使用的,有时调到所需的视点位置后,鼠标和键盘不能移动了,在osgChina上Array大神给一位网友解释的很清除,有需要的可以在osgchina()的论坛上搜索 3.利用cameraManipulator->setmatrix();通过王锐大神的启发,使用这个函数可以调整视点位置,但是需要计算矩阵,比较头突疼,就没往下做 4.最近看源码发现了一个方法,setTransformation();这个函数凡是继承osgGA::StandardManipulator()都可以使用,原型为 virtual void setTransformation( const osg::Vec3d& eye, const osg::Vec3d& center, const osg::Vec3d& up );官方解释如下: /** Sets manipulator by eye position, center of rotation, and up vector.*/,通过设置三个视线向量来设置操作器的位置,这个好像正是需要找的那个函数,,这样只需在事件里填写自己需要的视线方向即可实现相机的视点的移动, 问题二: 另外当需要在同一视点下切换操作器时,及操作器切换的时候会自动根据绑定的node节点和相机的视线范围来自动的调整摄像机的初始位置,也即是切换操作器的时候视点会直接发生跳跃调整到操作器自适应的初始位置,若想不回到初始位置我想了一个办法: 1.事件中通过viewer->getCamera()->getViewMatrixAsLookAt(vPosEye, vCenter, vUp);来获取视点信息,同时vPosEye, vCenter需要调整,因为他们之间的距离被限定为1,因为这个函数原函数是 void getViewMatrixAsLookAt(osg::Vec3f& eye,osg::Vec3f& center,osg::Vec3f& up,float lookDistance=1.0f) const;,可以通过调整第四个参数来调整两者之间的距离到合适的大小, 2.利用setTransformation()和求得的视点信息来设置操作器,将设置完成的操作器加入viewer中。 osg::ref_ptr trac = new osgGA::TrackballManipulator(); trac->setTransformation(m_vPosEye, location, vUp); viewer->setCameraManipulator(trac);