一。删除文件 1.克隆远程仓库到本地库。
例如使用ssh方法:
git clone git@github.com:xxx/xxx.git
2.对需要删除的文件、文件夹进行如下操作:
git rm test.txt (删除文件)
git rm -r test (删除文件夹)
3.提交修改
git commit -m "Delete some files."
4.将修改提交到远程仓库的xxx分支:
git push origin xxx
二。删除远程仓库 但不删本地资源 我们在使用idea开发的过程中经常会出现新建项目的时候直接把xxx.iml文件也添加到了git trace
当然这并不会出现什么问题,问题是当我们把xxx.iml文件push到我们github上之后,然后在另一台电脑上pull了下来会出现一些问题,因为xxx.iml文件不是项目的源码。也就是说对于导入项目来说是多余的。
正规的源码目录:
src/
pom.xml
.ignore
但是,我们又不能直接在本地删除xxx.iml。因为该文件是我们在本地开发的时候必须的。
那么问题来了:我们要在保留本地文件的情况下,删除远程仓库的文件(程序员一定要通过技术手段来实现目的,捂脸笑)
ok,废话不多说,下面是解决方案:
把xxx.iml加到`.gitignore`里面忽略掉,然后提交使.gitignore生效,也既是
git rm -r --cached xxx.iml //-r 是递归的意思 当最后面是文件夹的时候有用
(git add xxx.iml) //若.gitignore文件中已经忽略了xxx.iml则可以不用执行此句
git commit -m "ignore xxx.xml"
git push
三。本地仓库更换绑定的远程仓库 方法一 通过命令直接修改远程地址 进入git_test根目录git remote 查看所有远程仓库, git remote xxx 查看指定远程仓库地址git remote set-url origin http://192.
建设目标,利用docker技术快速搭建wordpress和dedecms,完成多域名的部署工作。
操作时间评估:20分钟。
主要部署内容,php7,nginx,myssql,wordpress,dedecms。
主要操作过程,几个命令行。
安装环境,安装有docker的服务主机(国外主机),本文略过安装过程。
项目要求,有三个网站,如下要求。
www.a.com,使用dedecmswww.b.com,使用wordpresswww.c.com,静态网站 主要思想,分别安装dedecms和wordprss,再利用nginx转发思想,分别建立转发机制。
操作过程:
第一步:准备工作,
根目录: /opt/docker
网站根目录:/opt/docker/www
nginx相关目录:/opt/docker/nginx/conf.d 第二步:安装php7,nginx,mysql
//取得nginx镜像 docker pull nginx //取得php镜像 docker pull php:7.1.0-fpm //取得mysql镜像 docker pull mysql 第三步:启动基础环境
//启动php docker run -p 9000:9000 --name myphp \ -v /docker/www/:/var/www/html/ \ --privileged=true \ -d php:7.1.0-fpm //启动nginx docker run -p 80:80 --name mynginx \ -v /docker/www:/usr/share/nginx/html \ -v /docker/nginx/conf.d:/etc/nginx/conf.d \ --privileged=true \ -d nginx //启动mysql docker run -d -e MYSQL_ROOT_PASSWORD=yaya --name wp-mysql -v /opt/docker/mysql/data:/var/lib/mysql -p 3306:3306 mysql 第四步:安装dedecms
问题描述:三个div,变成行内块(display:inline-block)之后,div之间会产生空隙;如图所示: 产生的原因:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>小div在大div中居中的方法</title> <style> .parent { width:600px; height:200px; border:2px solid #000; /*font-size: 0;*/ } .child { width:150px; height:100px; margin: auto; display: inline-block; } .parent>div:nth-child(1){ background: red; } .parent>div:nth-child(2){ background: blue; } .parent>div:nth-child(3){ background: green; } </style> </head> <body> <div class="parent"> <div class="child"></div> <div class="child"></div> <div class="child"></div> </div> </body> </html> 浏览器解析的时候,会把行内元素(包括行内块元素)之间的回车换行符解析成一定的间隙,间隙的大小跟默认的字体大小设置有关。 解决办法:将其父元素加上font-size:0的属性,这样就不会有间隙了。注意哦,如果有字,就会看不见了。或者下面这种不换行的写法,但是实际开发中是不现实的。 <div class="parent"> <div class="child"></div><div class="child"></div><div class="child"></div> </div>
本文的知识点包括android客户端的网络编程、消息机制、IO流、多线程和java web服务器端的servlet、数据库操作、javabean技术、工具类和测试类的使用。
客户端
运行效果图
布局文件 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.ningxiaojian.clientlogindemo.MainActivity"> <EditText android:id="@+id/et_username" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入登录账号"/> <EditText android:id="@+id/et_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入登录密码"/> <Button android:id="@+id/bt_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登录" android:onClick="login"/> <Button android:id="@+id/bt_register" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="注册" android:onClick="register"/> </LinearLayout> 程序主入口 MainActivity package com.ningxiaojian.clientlogindemo; import android.annotation.SuppressLint; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.Toast; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.
1. Tiles是什么?能做什么? Apache Tiles is a template based, composite view framework: it allows to reuse page pieces across the application, keeping consistent look and feel. Page layouts in general contains several page-fragments like header,footer, menu & content. In a consistent layout, only content changes between page navigation while other page fragments like header,footer & menu remains fixed most of the time.
Apache Tiles 是一种基于模板的复合视图框架:它允许在应用程序过程中重复使用页面片段,保持一致的外观和感受。一般页面布局包含多个页面片段,比如页眉、页脚、菜单和主体内容部分。在一个一致的布局中,只有主体内容部分会在页面导航之间改变, 而其他页面元素,如:页眉、页脚和菜单栏,大多数时间保持不变。
2. 为什么使用Tiles? 很多时候我们网站的风格布局是一致的,如修真院的页面,页眉页脚在绝大多数页面是不变的。而如果没有Tiles这种页面代码复用,这些页面片段的代码会在每个页面中重复这样显然是没有必要的,这时候使用Tiles框架可以将一致性的代码片段和需要改变的片段分开,提高代码复用。
3. Tiles如何使用? 此处引用http://websystique.
项目搭建
安装vue-cli
npl install vue-cli -g
vue init webpack my-project 初始化项目
npm install 安装项目依赖 -->>npm run build 生成上线目录部署
nmp run dev
在localhost启动测试服务器
步骤一
1.完成node.js安装搭建
目的:配合前端开发搭建 为全局工作 方法:通过官网下载 安装 .msi文件(微软标准安装包文件)
验证:
通过cmd 命令窗口 输入node 进入node工作状态 输入console.log(1); 验证node是否可以工作
退出
输入npm -v 查询版本
2.配置环境变量
配置"主机用户变量"(环境变量上面一栏) 设置PATH 变量 值为C:\Users\lenovo\AppData\Roaming\npm
3.git-bash软件安装配置
4.cd 项目地址
5.cnpm install安装依赖 说明:cnpm为国内常用下载依赖配置方式 国外一般用npm 当然 以实际速度为准
易产生问题:npm 与cnpm版本不一致
建议使用别名设置方法
步骤二 1.安装脚手架工具 输入cnpm install vue-cli -g 2.输入vue --help 看常用命令 3.输入vue -V 看版本 4.
之前网上看了很多教程,走了很多弯路,感觉有必要记一下,cuda、cudnn也都不需要自己装,conda会在装tensorflow-gpu时帮你搞定,省了很多事,具体步骤如下:
一、安装驱动(最简单的安装驱动方法)
1、点桌面左上角搜索本机程序的图标,找到“附加驱动”
2、在“附加驱动”里,系统会自动搜索N卡驱动,列表里会提供对应你显卡的最新版官方驱动。
3、最后点“应用更改”,等待安装完毕。
4、重启系统即可。
参考:https://jingyan.baidu.com/article/60ccbceb50803c64cab1978c.html
二、安装Anconda,并更新
1、https://www.anaconda.com/download/#linux 下载
2、cd到文件下载的位置输入如下命令安装Anaconda
$ bash Anaconda3-5.1.0-Linux-x86_64.sh
3、重启终端,更新
$ conda update -n base conda
三、安装tensorflow-gpu及keras
1、创建一个环境,指定python版本
$ conda create -n tf python=3.6 2、激活创建的tf环境:
$ conda activate tf 或者 $ source activate tf
3、在该环境下安装tensorflow-gpu及keras框架:
$ conda install tensorflow-gpu keras 4、查看安装是否成功
$ python>>import keras import tensorflow 5、安装其他所需要的库
$ conda install pillow$ conda install matplotlib$ conda install scikit-learn$ conda install graphviz pydot 6、退出该环境
$ conda deactivate 或者 source deactivate 7、移除tf环境
工作中用到,写三种用法吧,第四种为大小写匹配查询 1. sql中字符串拼接 SELECT * FROM tableName WHERE name LIKE CONCAT(CONCAT('%', #{text}), '%'); 2. 使用 ${...} 代替 #{...} SELECT * FROM tableName WHERE name LIKE '%${text}%'; 3. 程序中拼接
Java
// String searchText = "%" + text + "%"; String searchText = new StringBuilder("%").append(text).append("%").toString(); parameterMap.put("text", searchText); SqlMap.xml
SELECT * FROM tableName WHERE name LIKE #{text};
4. 大小写匹配查询 SELECT * FROM TABLENAME WHERE UPPER(SUBSYSTEM) LIKE '%' || UPPER('jz') || '%' 或者 SELECT * FROM TABLENAME WHERE LOWER(SUBSYSTEM) LIKE '%' || LOWER('jz') || '%'
public enum HttpStatus { // 1xx Informational /** * {@code 100 Continue}. * @see <a href="http://tools.ietf.org/html/rfc7231#section-6.2.1">HTTP/1.1: Semantics and Content, section 6.2.1</a> */ CONTINUE(100, "Continue"), /** * {@code 101 Switching Protocols}. * @see <a href="http://tools.ietf.org/html/rfc7231#section-6.2.2">HTTP/1.1: Semantics and Content, section 6.2.2</a> */ SWITCHING_PROTOCOLS(101, "Switching Protocols"), /** * {@code 102 Processing}. * @see <a href="http://tools.ietf.org/html/rfc2518#section-10.1">WebDAV</a> */ PROCESSING(102, "Processing"), /** * {@code 103 Checkpoint}. * @see <a href="http://code.google.com/p/gears/wiki/ResumableHttpRequestsProposal">A proposal for supporting * resumable POST/PUT HTTP requests in HTTP/1.
简介 ActiveMQ 特点 ActiveMQ 是由 Apache 出品的一款开源消息中间件,旨在为应用程序提供高效、可扩展、稳定、安全的企业级消息通信。 它的设计目标是提供标准的、面向消息的、多语言的应用集成消息通信中间件。ActiveMQ 实现了 JMS 1.1 并提供了很多附加的特性,比如 JMX 管理、主从管理、消息组通信、消息优先级、延迟接收消息、虚拟接收者、消息持久化、消息队列监控等等。其主要特性有:
支持包括 Java、C、C++、C#、Ruby、Perl、Python、PHP 等多种语言的客户端和协议。协议包含 OpenWire、Stomp、AMQP、MQTT 。提供了像消息组通信、消息优先级、延迟接收消息、虚拟接收者、消息持久化之类的高级特性完全支持 JMS 1.1 和 J2EE 1.4规范(包括持久化、分布式事务消息、事务)对 Spring 框架的支持,ActiveMQ 可以通过 Spring 的配置文件方式很容易嵌入到 Spring 应用中通过了常见的 J2EE 服务器测试,比如 TomEE、Geronimo、JBoss、GlassFish、WebLogic连接方式的多样化,ActiveMQ 提供了多种连接模式,例如 in-VM、TCP、SSL、NIO、UDP、多播、JGroups、JXTA支持通过使用 JDBC 和 journal 实现消息的快速持久化为高性能集群、客户端-服务器、点对点通信等场景而设计提供了技术和语言中立的 REST API 接口支持 Ajax 方式调用 ActiveMQActiveMQ 可以轻松地与 CXF、Axis 等 Web Service 技术整合,以提供可靠的消息传递可用作为内存中的 JMS 提供者,非常适合 JMS 单元测试 基本概念 因为 ActiveMQ 是完整支持 JMS 1.1 的,所以从 Java 使用者的角度其基本概念与 JMS 1.1 规范是一致的。
消息传送模型 点对点模型(Point to Point) 使用队列(Queue)作为消息通信载体,满足生产者与消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。
这个有好几个大神写过了,照着改就可以。我的改好了,需要的留下你的邮箱我发给你。 我的电脑在编译orb-slam2时候卡死了,我用的命令是按照博客上来的: $ chmod +x build.sh $ ./build.sh 我也不知为啥卡死了 然后我用的 1. 在ORB-SLAM2文件夹下 mkdir build 2.cd build 3.cmake .. 4.make ok 解决 对了,在编译Examples下的ROS包时候 要记得在bash文件中声明路径哈。 具体如下: export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/xxx(你的电脑名字)/catkin_ws/src/ORB_SLAM2/Examples/ROS
//while循环 public class Test { public static void main(String[] args){ int i=1; int sum=0; while(i<=100){ sum=sum+i; i++; } System.out.println(sum); } } //for循环 public class Test { public static void main(String[] args){ int sum=0; for(int i=1;i<=100;i++){ sum=sum+i; } System.out.println(sum); } } //do while循环 public class Test { public static void main(String[] args){ int i=0; int sum=0; do{ i++; sum=sum+i; }while(i<100); System.out.println(sum); } }
每次都得啰嗦这么几句,真的是这阵子走来,一步一个脚印,一步一个坑。
1.购买服务器跟域名
首先购买一台学生服务器,选择这个套餐,挺实惠的,顺便买个xin域名。懒人点击这个链接购买购买链接 ,默认购买linux系统centos7.3
2.域名解析
对域名进行dns解析。购买域名后,点击进入控制台,然后点击进入域名和网站栏目 点击域名解析,点击新手引导,进行快捷解析即可。服务器的ip在控制台,ecs服务器实例里面查看,为公网ip。
3.远程登录
由于我是用window的,所以肯定用到了xshell神器进行ssh远程连接,因为这个东西确实好用。
如何使用xshell请自行百度哦。远程连接登录后后,出现这样一个界面证明你成功了
接下来就是linux命令行的基本操作了,按照配置各种文件。linux基本命令跟lrsz的按照参照这篇文章linux基础命令跟lrsz安装
4.安装nodejs的快乐时刻到了~
[root@localhost ~]# cd / #进入根目录 [root@localhost /]# mkdir soft && cd soft #用来放置安装包 [root@localhost soft]# wget https://nodejs.org/dist/v8.9.4/node-v8.9.4.tar.gz #下载nodejs压缩包 [root@localhost soft]# tar -zxvf node-v8.9.4.tar.gz #解压缩 [root@localhost soft]# cd node-v8.9.4.tar && ./configure #进行配置,使用默认配置 [root@localhost node-v8.9.4]# make && make install #进行编译 安装之后就已经自带npm了,但是国外的镜像太慢,我们要换个国内的,参考这篇文章nrm的使用,npm镜像源切换
漫长的等待之后,一个可以使用的node环境就安装好了,可以通过执行node -v或者npm -v来检测当前的node/npm安装是否成功。如果有出现版本号,那么就是安装成功了。
如果编译过程中出现g++: Command not found以及C Compiler可以升级来解决,执行下列指令
[root@localhost ~]# yum -y install gcc make gcc-c++ openssl-devel wget 5.
问题:tweak tool中没用extension选项,这是因为没有开启gnome,解决方法是注销当前用户 然后在登录窗口的右上角,选择gnome,如下图所示
然后在弹出的窗口中选择Gnome即可(我选择的是第一个GNOME)
再次进入系统,打开tweak tool,就可以看到extension了
事件通常与函数配合使用,这样就可以通过发生的事件来驱动函数执行。 事件句柄列表 下面是一个属性列表,这些属性可插入HTML标签来定义事件动作。 onabort:图片加载被中断
onblur: 元素市区焦点
onchange: 用户改变域的内容
onclick: 鼠标点击某个对象
ondblclick: 鼠标双击某个对象
onerror: 加载文档或图像时发生错误
onfocus: 元素获得焦点
onkeydown: 某个键盘的键被按下
onkeypress: 某个键盘的键被按下或按住
onkeyup: 某个键盘的键被松开
onload: 某个页面或图像被完成加载
onmousedown: 某个鼠标按键被按下
onmousemove: 鼠标被移动
onmouseout: 鼠标从某元素移开
onmouseover: 鼠标被移到某元素之上
onmouseup: 鼠标按键被松开
onreset: 重置按钮被点击
onresize : 窗口或框架被调整尺寸
onselect: 文本被选定
onsubmit: 提交按钮被点击
onunload: 用户推出页面
<?php $array1 = array( 0 => 'zero_a' , 2 => 'two_a' , 3 => 'three_a' ); $array2 = array( 1 => 'one_b' , 3 => 'three_b' , 4 => 'four_b' ); $result = $array1 + $array2 ; var_dump ( $result ); ?>
使用SQL Server 2005还原备份的数据库文件时出现的问题,错误提示如下:
尚未备份数据库 "***" 的日志尾部。如果该日志包含您不希望丢失的工作,请使用 BACKUP LOG WITH NORECOVERY 备份该日志。
前提:如果你有个数据库的.bak的备份文件。
右键点击 数据库任务-->还原-->数据库
1.还原的目标选择你要覆盖的数据库
2.还原的源选择 源设备找到你的.bak备份文件的路径
注意:选项中选择“覆盖现有数据库”
截图如下:
原文地址: https://pdf-lib.org/Home/Details/5978
“无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。” deque函数: deque容器为一个给定类型的元素进行线性处理,像向量一样,它能够快速地随机访问任一个元素,并且能够高效地插入和删除容器的尾部元素。但它又与vector不同,deque支持高效插入和删除容器的头部元素,因此也叫做双端队列。deque类常用的函数如下。
(1) 构造函数
deque():创建一个空deque
deque(int nSize):创建一个deque,元素个数为nSize
deque(int nSize,const T& t):创建一个deque,元素个数为nSize,且值均为t
deque(const deque &):复制构造函数
(2) 增加函数
void push_front(const T& x):双端队列头部增加一个元素X
void push_back(const T& x):双端队列尾部增加一个元素x
iterator insert(iterator it,const T& x):双端队列中某一元素前增加一个元素x
void insert(iterator it,int n,const T& x):双端队列中某一元素前增加n个相同的元素x
void insert(iterator it,const_iterator first,const_iteratorlast):双端队列中某一元素前插入另一个相同类型向量的[forst,last)间的数据
(3) 删除函数
Iterator erase(iterator it):删除双端队列中的某一个元素
Iterator erase(iterator first,iterator last):删除双端队列中[first,last)中的元素
void pop_front():删除双端队列中最前一个元素
void pop_back():删除双端队列中最后一个元素
void clear():清空双端队列中最后一个元素
(4) 遍历函数
reference at(int pos):返回pos位置元素的引用
reference front():返回首元素的引用
reference back():返回尾元素的引用
iterator begin():返回向量头指针,指向第一个元素
iterator end():返回指向向量中最后一个元素下一个元素的指针(不包含在向量中)
reverse_iterator rbegin():反向迭代器,指向最后一个元素
上一篇写过线性判别分析处理二分类问题https://blog.csdn.net/z962013489/article/details/79871789,当使用LDA处理多分类问题时,通常是作为一个降维工具来使用的。若我们有一个D维的样本集,该样本集包含C个类别共n个样本,希望将D维降维成K维。之前在二分类问题中,我们定义的类间散度矩阵为:
Sb=(μ1−μ2)(μ1−μ2)T S b = ( μ 1 − μ 2 ) ( μ 1 − μ 2 ) T 当类别为3时就已经不再适用,在这里引出全局散度矩阵的概念:
St=Sw+Sb=∑i=1n(xi−μ)(xi−μ)T S t = S w + S b = ∑ i = 1 n ( x i − μ ) ( x i − μ ) T 其中 μ μ 为整个样本集的均值向量,其中的类内散度矩阵 Sw S w 定义为所有类别的散度矩阵之和,与二分类类似,基于全局散度矩阵,我们就可以求得类间散度矩阵 Sb S b 定义为: Sb=St−Sw=∑i=1nmi(μi−μ)(μi−μ)T S b = S t − S w = ∑ i = 1 n m i ( μ i − μ ) ( μ i − μ ) T 其中 mi m i 为第i个类别样本总数, μi μ i 为第i个类别样本的均值向量。 上图的例子可以作为参考便于理解。 我们要计算一个W矩阵,使样本向量在该投影矩阵的作用下能够实现其与同类样本的中心距离尽量小,而与异类样本的中心距离尽量大。常见的一种优化目标为: maxWtr(WTSbW)tr(WTSwW) max W t r ( W T S b W ) t r ( W T S w W ) 其中的tr()为矩阵的迹,一个n×n的对角矩阵A的主对角线(从左上方至右下方的对角线)上各个元素的总和被称为矩阵A的迹(或迹数),一般记作tr(A)。 这个优化目标实际上等价于求解多个w组合成W,那么该问题就等价于求解多个上一章的优化目标,使用相同的方法,可以求得下式: SbW=λSwW S b W = λ S w W 即 S−1wSbW=λW S w − 1 S b W = λ W W的闭式解为 S−1wSb S w − 1 S b 的k个最大非零广义特征值对应的特征向量组成的矩阵,LDA降维最多可以降至C-1,C为样本类别数,与原始特征维数n无关。 使用python实现LDA降维代码,对Iris数据集从四维降至二维,绘图如下: 其中上图为自己实现的方法降维表现,下图为sklearn自带方法降维表现。 python3.
title: 线性代数笔记11:正定矩阵理解及推导
tags:
linear algebra
categories:linear algebra
date: 2018-04-12 15:55:43
mathjax: true 正定矩阵及半正定矩阵在机器学习和深度学习中有很重要的应用。
引言 定义:特征值全是正实数的实对称矩阵为正定矩阵(positive definite matrix)。类似的,若实对称矩阵的特征值均非负,则为半正定矩阵(positive semidefinite matrix)。 可能用到的概念 主子式
定义:在 n n n阶行列式中任选 k k k行,再取相应的 k k k列,将行列交汇处元素组成新的矩阵行列式,称为 n n n阶行列式的一个 k k k阶主子式。
顺序主子式(the k-th leading principal minor)
定义:在 n n n阶行列式中由第 1 , . . . , k 1,...,k 1,...,k行和第 1 , . . . , k 1,...,k 1,...,k列所确定的主子式称为 k k k阶顺序主子式。直观上看就是矩阵中左上方的子矩阵。
实对称矩阵 A A A正定的充要条件 注意,这里的所有进行判别的矩阵都是实对称矩阵。
这个系列一共有四道题,每道题目之间稍微有些不同,下面通过对比来总结一下,四道题目都可以使用backtracking回溯方法做,当然也可以是使用DP进行求解。首先看第一道: 39. Combination Sum
Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited number of times. Note: All numbers (including target) will be positive integers. The solution set must not contain duplicate combinations. For example, given candidate set [2, 3, 6, 7] and target 7, A solution set is: [ [7], [2, 2, 3] ] 看完题目不难理解,其实就是在一个数组中寻找和为target的组合,数组中不存在重复元素,不过每个元素可以重复使用,但是最终的求解方案不能有重复。我们首先可以将数组进行排序,然后使用回溯法逐个元素求和,当求和等于target的时候将结果保存下来,当求和小于target的时候继续向前遍历,当求和大于target的时候删除当前元素遍历下一个。代码如下所示,可以击败46%的用户:
场景:需要进行大量数据解析,存储,传输
1.数据结构
typedef struct cJSON { struct cJSON *next,*prev; struct cJSON *child; int type; char *valuestring; int valueint; double valuedouble; char *string; } cJSON; 每个json对象都有一个type,对象的值可以是字符串(valuestring),整形(valueint),浮点型(valuedouble)
2.创建json对象
cJSON_CreateObject//创建一个json对象-- {对象}
cJSON_AddStringToObject//向json对象中添加一个元素,元素的值是字符串-- {"type":""}
cJSON_AddNumberToObject//向json对象中添加一个对象,该对象的值是整形-- {"type":int}
cJSON_CreateArray();//创建json对象数组-- [{ : } ,{ : }]
cJSON_CreateString//具体解释可参考下面例子
cJSON_CreateNumber//具体解释可参考下面例子
cJSON_Delete//释放内存
cJSON_PrintUnformatted(root) cJSON_Print(root)//将json数据转换成字符串,然后将字符串打印,第二个是含有换行符等格式的
举例:
2.1.创建 {"name": "fengxin", "passwd": "123", "num": 1 } #include<stdio.h> #include<stdlib.h> #include<string.h> #include"cJSON.h" int main() { cJSON * usr; cJSON *arry; usr=cJSON_CreateObject(); //创建根数据对象 cJSON_AddStringToObject(usr,"name","fengxin"); //加入键值,加字符串 cJSON_AddStringToObject(usr,"
import os import sys import random import math import numpy as np import skimage.io import matplotlib import matplotlib.pyplot as plt import coco import utils import model as modellib import visualize class_names = ['BG', 'your class1', 'your class2', 'your class3'] class InferenceConfig(coco.CocoConfig): # Set batch size to 1 since we'll be running inference on # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU GPU_COUNT = 1 IMAGES_PER_GPU = 1 NUM_CLASSES = 1 + 3 # background + 3 class config = InferenceConfig() config.
import os import sys import random import math import re import time import numpy as np import cv2 import matplotlib import matplotlib.pyplot as plt import yaml from config import Config import utils import model as modellib import visualize from model import log from PIL import Image #%matplotlib inline # Root directory of the project ROOT_DIR = os.getcwd() # Directory to save logs and trained model MODEL_DIR = os.path.join(ROOT_DIR, "logs") # Local path to trained weights file COCO_MODEL_PATH = os.
(上一节练习,笔记本)
Java项目练习:第3期 类和对象(20分钟)
需求描述:
设计一个学生类Student和它的子类Undergradute,要求如下:
Student类有name(姓名)和age(年龄),一个包含两个参数的构造方法,用于给name和age属性赋值,一个show()方法打印Student的属性信息。本科生类Undergraduate增加一个degree(学位)属性。有一个包含三个参数的构造方法,前两个参数用于给继承的name和age赋值,第三个参数给degree专业赋值,一个show()方法打印Undergrate的属性信息。在测试类中创建Student对象和Undergraduate的属性信息。 package com.niuke_1; class Student { String name; int age; public Student(String name, int age){ this.name = name; this.age = age; } public void show(){ System.out.println("name: "+name+" age: "+age); } } class Undergraduate extends Student { private String degree; public Undergraduate(String name, int age, String degree){ super(name, age); this.degree = degree; } public void show(){ System.out.println("name: "+name+" age: "+age+" degree: "+degree); } } public class demo_3 { public static void main(String[] args){ Student stu = new Student("
Spring Cloud 官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud.html
一个Spring Cloud的操作是通过创建“bootstrap”context开始的,它是main application最上层的parent context。开箱机用,它负责载入来自于外部的配置信息(properties),同时在本地解码外部配置文件的properties。所有Spring应用程序都是由2个Context共享来自外部properties的环境Environment。 Bootstrap properties在被加载时具有最高的优先权,所以默认情况下bootstrap properties不会被本地配置覆盖。
bootstrap context 使用不同的方式定位外部配置信息,而不是像main application context那样,所以你可以使用bootstrap.yml 代替 application.yml or application.properties, 最好将外部配置交给bootstrap,并与main context分开。
例如: bootstrap.yml
spring: application: name: foo cloud: config: uri: ${SPRING_CONFIG_URI:http://localhost:8888}如果你的application在server端有任何特殊的配置,最好是将spring.application.name设置到bootstrap.yml内,因为bootstrap.yml 不会被本地配置所覆盖。 你也完全可以通过设置系统属性(system properties)spring.cloud.bootstrap.enabled=false, 来禁用bootstrap process。
RedHat7.0 (Linux) 安装mysql (mysql-5.7.21-1.el7.x86_64.rpm-bundle.tar)
网上有很多资料关于安装的,但由于版本问题,困扰许久本文提供 readHat7.0及相应的mysql,可到相应的百度云盘下载https://pan.baidu.com/s/15dPTThydeJOLOreMWVeaCQ*** 提取密码:34hr ** 安装步骤如下:
在 /home下新建 mysql目录。将 mysql压缩包传入到该文件下。可通过WinSCP
传入到该文件夹下(不再赘述)!
首先先查看是否已经安装了mysql ,执行命令 rpm -qa|grep mysql
如果什么都没显示说明没有安装过,如果已经安装了Mysql就先卸载执行命令 rpm -e --nodeps xxxxxxxx(xxxxxx为已经安装的rpm)
查看是否安装mariadb 系统自带的,之前安装的时候和mysql冲突,所有不用这个数据库的话也可以卸载,查看是否安装rpm -qa|grep mariadb,卸载执行rpm -e --nodeps xxxxxxxxxx
接下里进入 /home/mysql 命令:cd /home/mysql
解压 tar -xf mysql-5.7.21-1.el7.x86_64.rpm-bundle.tar
演示图
解压之后又很多文件,我们只需要安装
(**注意:**下面这个图只看顺序就好了, 图片上是5.7.10.xxx, 实际上在执行命令的时候,要 替换成上图红色文字部分,只是版本变一下。下图只是展示安装顺序。)
命令如下:(因为包的依赖管理,注意要按上面的顺序执行)
rpm -ivh mysql-community-common-5.7.21-1.el7.x86_64.rpm
…
安装完后开始初始化数据库,进入/usr/bin
执行命令mysqld --initialize --user=mysql 或者mysqld --initialize-insecure --user=mysql
第一个命令是为root用户随机生成一个登陆密码,登陆时执行名mysql -u root -p,密码在/var/log/mysqld.log文件中可以查看(这里使用第一种方式安装)
root@localhost: f2*9Pw7smb/9 密码就为: f2*9Pw7smb/9 第二个命令不会为root用户生成密码,登陆时执行mysql -u root--skip-password在初始化过程中可能会出现[ERROR] --initialize specified but the data directory exists.
原因主要是打包没有包含源码所以会出现无法查看的问题 现在要在你的打包项目pom文件<build></build>节点里加入以下代码
<resource>
<directory>src/main/java</directory>
<includes> <include>**/*.java</include> </includes> </resource>
这样就可以把源码一起打包 在另一个maven项目里导入这个项目的jar包就可以查看源码并且可以debug了
希望可以帮到你 !
一、背景 早上突然发现服务器这边所有的请求都报错:502,具体报错信息如下:
connect() to unix:/var/run/php5-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: xxx, server: xxx, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "xxx" 这个意思是无法找到php5-fpm.sock,但是原来是好好的,为什么会出现这种问题呢?
二、第一种可能 1、第一种可能就是,nginx配置的问题:
nginx配置文件中有一句是这样的,监听sock文件 fastcgi_pass unix:/var/run/php5-fpm.sock; 2、解决方案
进入 /etc/php5/fpm/pool.d/www.conf,修改配置,里面找到这样一段代码:
``` listen = 127.0.0.1:9000 ``` 在这上面代码的下面添加一行: ``` listen = /var/run/php5-fpm.sock ``` 保存后启动php5-fpm ``` /etc/init.d/php5-fpm restart ``` 这时就可以正常访问了 三、第二种可能 1、既然是报错502,众所周知,这个错误代表的意思就是:
这个错误是由于服务器压力过大,不能及时处理client的请求导致服务器响应超时而抛出的错误。通俗来讲,我们向服务器发送请求 由于服务器当前链接太多,导致服务器方面无法给于正常的响应,产生此类报错。
那么OK,因为我们使用的是php-fpm的系统服务,那么极有可能是我们在给服务器请求的时候,由于请求量比较大,php-fpm在规定的响应时间内没有响应,自动杀掉这些进程或者卡死造成的。
2、解决方案
1)增大请求的持续时间,防止php脚本或者php-fpm自动杀死进程
//修改php.ini 中的参数,可以把这个参数设置的大一些, 代表置了脚本被解析器中止之前允许的最大执行时间 ,默认是30s。也就是说这个请求如果30s还没得到响应的话 ,脚本会自动杀死这个请求。 max_execution_time = 60s 如果不想修改php.
题目大意:给出八个数和一个x(代表零),问是否可以通过交换零和其它数字的位置到达最终状态 思路:用广搜扩展目的状态所能到达的所有状态,然后直接判断,这个题目我用了map标记,HDU上会超时,把map改成康托展开,或者直接用IDA*算法应该就可以了
#include <stdio.h> #include <string.h> #include <queue> #include <iostream> #include <stdlib.h> #include <algorithm> #include <map> using namespace std; map<string,int> mm; // 用map映射所有能够到达的状态 char ss[10]; int dir[4][2] = {-1,0, 0,-1, 0,1, 1,0}; // 上,左,右,下 char cc[6] ="ulrd"; // 空格移动的四个方向对应移动的四个方向 上0, 左1, 下2, 右3; struct ak { char ch[10]; // 结构体中表示当前状态的数组 int x, y; // 空格所在坐标 int front; // 前驱下标 int arr; // 当前下标 int where; // 方向 }temp, temp2, gg[400000]; queue<ak> qq; // 结构体变量存入队列qq中 void gao(int x) // 类似于递归,输出该点的方向,通过该点的前驱递归,直到最后一个 { if(x == 0) // 递归结束条件 { return ; } printf("
在Ubuntu中遇到 vi 编辑器的上下左右方向金变成ABCD 时:
解决方法: cp /etc/vim/vimrc ~/.vimrc 然后重启终端即可
Java IO流学习总结(二)—— 常用IO流继承关系图 接Java IO流学习总结(一)—— IO流分类和常用IO流汇总中汇总的IO流的继承关系图如下:
加任务: crontab -e 0 */1 * * * command 0 */2 * * * command 查询任务是否加了: crontab -l 0 */1 * * * command 0 */2 * * * command 基本格式 :
* * * * * command
分 时 日 月 周 命令 第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时0~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令 crontab文件的一些例子: 30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache。 45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。 10 1 * * 6,0 /usr/local/etc/rc.
这其实也是个搜索组合问题,但是却可以借助动态规划的思想,将问题一步一步分解
首先来个简单点的,输出全部的可能!
#include <iostream> #include <string> #include <cstdlib> using namespace std; //存储用户输入的整数 int n; //存储用户输入的要拆分的个数 int m; //计数器,记录拆分结果的个数 int totalKind; //存储拆分出的因数 //注意:这里只定义了100长度的数组空间,可根据需要自己扩充 int a[100]; void print() { cout<<n<<" = "<<a[1]; for (int i=2; i<=m; i++) { cout<<" * "<<a[i]; } //输出换行 cout<<endl; //拆分结果个数自增 totalKind++; } void Split(int arrayIndex,int preDivisor,int newDivisor) { //判断是否拆分结束,如果结束则输出该种拆分结果 //拆分结束的条件是: //数组下标(即拆分的因数的个数)等于用户输入的拆分个数 //并且当前因数大于前一个因数(即保证因数从小到大获取,避免重复) if (arrayIndex==m && newDivisor>=preDivisor) { //存储当前(新)的因数 a[arrayIndex] = newDivisor; //输出当前拆分结果 print(); //不是一直存储,是只要满足条件就打印 //退出该函数 return; } //如果拆分没有结束,则将当前(新)的因数继续拆分 for (int i=preDivisor; i<=newDivisor; i++) { //如果当前因数能整除当前i值 if (newDivisor%i == 0) { //再次获得因素 a[arrayIndex]=i; //获得新的因数,继续拆分,递归 Split(arrayIndex+1,i,newDivisor/i); } } } int main() { //计数器初始化 totalKind=0; cout<<"
bash是 Bourne Again Shell 的缩写,是linux默认的标准shell(也是大家常说的系统内核),bash也是Unix/Linux上常见的Shell脚本解释器,既然bash是标准的shell,那么就有非标准的sh,csh,ksh等等,我们常说有多少种Shell,其实说的是Shell脚本解释器,Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本,bash是基于Bourne shell创建的,并且吸收了C shell和Korn shell的一些特性,而且bash完全兼容sh,也就是说,用sh写的脚本可以不加修改的在bash中执行。 sh:sh 由Steve Bourne开发,是Bourne Shell的缩写,sh 是Unix 标准默认的shell。 ash:ash shell 是由Kenneth Almquist编写的,Linux中占用系统资源最少的一个小shell,它只包含24个内部命令,因而使用起来很不方便。 csh:csh 是Linux比较大的内核,它由以William Joy为代表的共计47位作者编成,共有52个内部命令。该shell其实是指向/bin/tcsh这样的一个shell,也就是说,csh其实就是tcsh。 ksh:ksh 是Korn shell的缩写,由Eric Gisin编写,共有42条内部命令。该shell最大的优点是几乎和商业发行版的ksh完全兼容,这样就可以在不用花钱购买商业版本的情况下尝试商业版本的性能了。 现在我们知道Unix/Linux上有多种shell,那我怎么知道当前使用的哪种shell呢,我们可以从当前进程中查看到这些信息。 方法1: ps | grep $$ | awk '{print $4}' 方法2: echo $0 方法3: echo $$ | ps -p $$表示shell的进程号 同样的,在/etc/shells配置文件中记录了用户可以登录的shell的具体路径,有就是说用户可以在当前系统中使用的所有可登录shell的类型,因此查看这个文件的内容,即可知道当前系统中所支持的所有shell类型。 当你想要查看某个用户的Shell类型时,可以在/etc/passwd文件的最后一个字段中,查看到某个特定用户的登录Shell类型。以root为例,执行 cat /etc/passwd | grep ^root 最后一个:号字段显示的即为root用户的登录shell类型,为bash
变量插值(variable interpolation),翻译中允许插入变量进行翻译,比如
$20 20元这样的不同的计数金额的方式,这时在翻译文件就可以定义
price: “%{price}元”这样的形式,在翻译的时候,这样调用 t(:price, price: 20)则会20这个变量一起带入到翻译中来
使用default_url_options加routes#scope的方式在url中添加默认语言区域设置
使用l方法并配合在翻译文件中定义时间格式来翻译时间格式
除了语言可以国际化,视图模板也可以国际化!类似于访问 books_controller#index方法会自动渲染books/index.html.erb一样,如果指定了I18n的locale后,rails会去寻找对应区域语言的视图模板,比如访问 localhost:3000/en/books的时候,如果定义了books/index.en.html.erb模板的话,将会去渲染index.en.html.erb模板文件!如果没有定义将会渲染默认的视图文件
翻译的命名空间:
翻译文件中的翻译可以定义为层级结构,比如:
time:
formats:
short: xxx
那么翻译时可以使用这几种形式,是等价的:
t(‘time.formats.short’)
t(‘short’, scope: [:time, :formats])
t(‘formats.short’, scope: [:time])
惰性查找: rails实现了一种针对视图和控制器专用的便捷方法,调用t方法时,要翻译的单词的第一个字母前写上 .(点),那么rails会自动按照当前视图或者控制器的命名空间去寻找翻译,比如 books_controller.rb#index中的 t(‘.hey’),这个方法将会去寻找
books:
index:
hey: 这样的翻译
针对ActiveRecord的翻译: 模型的翻译需要定义成这种形式:
activerecord:
attributes:
user/gender:
female: "Female"
male: "Male"
errors:
models: user:
attributes
name:
blank:
,定义完之后,model_name.human 以及 model_name.human_attribute_name(attr)就会自动去寻找模型对应的翻译,simple_form_for中使用 f.input :attr这样的形式的时候,也是通过这种规则去寻找翻译。当模型有写validates校验的时候,那么当校验不通过的时候,会按照模型的错误消息的建去寻找翻译比如 user.errors中会有name.blank的建
1.场景还原 最近有些小伙伴问我:“星哥,在springmvc中怎么访问jsp,该怎么配置?”,这里笔者写下这篇博客详细的讲解下配置过程。
2.实现步骤 ① 在spring-web中配置视图解析器
<!--3:配置JSP 显示ViewResolver--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> </bean> ②在WEB-INF下创建view目录 ③controller代码
@Controller @RequestMapping("path") public class PathCheckController { @RequestMapping("/test") public String pathTest(ModelMap model){ model.addAttribute("message","I am zhangxing"); return "index"; } } 注意咯!这里不能用@RestController注解,否则controller中的方法无法返回jsp页面,配置的视图解析器InternalResourceViewResolver也将不起作用,所以 只能用@Controller
④index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>登录</title> </head> <body> <h1>${message}</h1> </body> </html> 3.测试效果
问题描述: 在主从节点的hostname配置都正确,如下:
hadoop集群搭建成功后,主从节点的守护进程都正常启动。
通过http://192.168.254.10:50030可以访问到web页面
但通过http://master:50030却不行
原因: 打开浏览器的Windows系统的配置文件,也要配置hostname属性,它也不知道master是哪个ip啊......
加上之后,虽然有警告,但没啥事情,因为是我们预知的设置
IMP-00003: 遇到 ORACLE 错误 959 ORA-00959: 表空间 'XXXXXXXXXXX' 不存在。 今天有个需求: 需要从一个用户导15张表到另一个用户,数据挺大,就选在用exp/imp工具,简单方便; 由于表空间两个用户默认不同,所以加了参数ignore=y,以便能成功导入; imp ***/*** ignore=y tables(***) file=E:\bak\table1.dmp log=E:\bak\imp.log 但遇到问题了,15张有12张表导入成功,3张导入时报错,这3张表有一个共同点,都是包含了clob字段,无法用ignore忽略; 解决办法: 通过导出用户复制这三张表的表结构,修改sql语句中的表空间,再在导入用户下执行创建表语句; 删掉之前已经导入的表,加上ignore=y,再次执行导入表语句; imp ***/*** ignore=y tables(***) file=E:\bak\table1.dmp log=E:\bak\imp.log导入成功; 其他imp导入时遇到表空间更改和包含clob字段的场景时,此办法可解决;
这部分题分两个问题:1组合优化问题(顺序无关)。2排列选择问题(一般有个book[]数组记录搜索过没有)
一:回溯法 注意:回溯法是一种完全搜索,有时进行适当的裁剪可以减少好多不必要的搜索步骤!
首先实现的是一个简单版本的回溯!
#include <vector> using namespace std; class Solution { public: vector<vector<int> > subsets(vector<int> &S) { vector<vector<int>> results; vector<int> item; results.push_back(item); generate(0,S,item,results); return results; } private: vector<int> S ; S.push_back(1); S.push_back(2); S.push_back(3); void generate(int i,vector<int>& nums,vector<int> &item,vector<vector<int>>&results) { if( i >nums.size()) //递归结束的条件 return; item.push_back(nums[i]);//依次添加下一个元素 results.push_back(item); //将当前生成的子集添加进results generate(i+1,nums,item,results); //递归执行上边的代码,直到return时进行下边的操作 item.pop_back(); //这里是回溯的关键 generate(i+1,nums,item,results); } };//这里是回溯的关键 generate(i+1,nums,item,results); } }; 升级一下 再次升级:裁剪的例子 二:搜索算法 常用到的搜素算法有基于递归实现的深度优先搜素算法(DFS)和基于队列实现的广度搜素(BFS);
需要说明:这两种算法和前面的算法没有本质的区别,都是一种完全遍历的算法,因此时间复杂度都先对较高,要想
改进就必须对回溯的过程就行修建,去掉一些不必要的步骤!
特别要注意的是DFS实现全搜索的过程是基于回溯的,回溯的过程是靠标记数组book[ ]来判断的,下边给出一个
简单的例子!
#include <iostream> #include <string.
支持向量机(Support Vector Machine)曾经在分类、回归问题中非常流行。支持向量机也称为最大间隔分类器,通过分离超平面把原始样本集划分成两部分。
首先考虑最简单的情况:线性可分支持向量机,即存在一个超平面可以把训练样本分开。
1.线性可分支持向量机 1.考虑一个线性二分类的问题;如下左图,在二维平面上有两种样本点x,目标值分别标记为{-1,1},可以作出无数条直线wTx+b=0wTx+b=0,直线上方的点标记为{+1}的带入直线公式会得到wTx+b>0wTx+b>0,下方的点,标记为{-1}带入直线公式会得到wTx+b<0wTx+b<0,因此可以用wTx+bwTx+b的符号决定点的分类,写成决策函数为f(x,w,b)=sign(wTx+b)f(x,w,b)=sign(wTx+b)把两类点分开,但是个采用哪个直线最好呢? 2.一般来说,当样本点离直线越远,则分类正确的确信度越大;如下右图所示,A,B,C三个样本点都被预测分类到‘×’类中。但是对于A的分类正确的确信度比C大。因为点C里分类直线wTx+b=0wTx+b=0很近,当直线的斜率稍一点变化,即会导致C被分到另一类中。 综上,我们想要得到的直线是离样本点最远,同时又能保证正确划分的直线综上,我们想要得到的直线是离样本点最远,同时又能保证正确划分的直线。 1.1函数间隔与几何间隔 由二维直线wTx+b=0wTx+b=0扩展到高维被称为超平面(w,b)(w,b)。一个点距离超平面的远近可以表示分类预测的确信程度。在超平面wTx+b=0wTx+b=0确定的情况下,|wTx+b||wTx+b|能够相对地表示点x距离超平面的远近,而且如果分类正确,则y(i)y(i)与wTx(i)+bwTx(i)+b的符号一致,即y(i)(wTx(i)+b)>0y(i)(wTx(i)+b)>0,同时表示分类的正确性以及确信度。 函数间隔:超平面(w,b)(w,b)关于样本点(x(i),y(i))(x(i),y(i))的函数间隔为
函数间隔:γ^(i)=y(i)(wTx(i)+b)函数间隔:γ^(i)=y(i)(wTx(i)+b)
定义超平面关于样本集S的函数间隔为超平面(w,b)与S中所有样本点的函数间隔的最小值 γ^=mini=1,2,...m γ^(i)γ^=mini=1,2,...m γ^(i)
定义γ^γ^是为了最大化间隔,γ^γ^表示关于超平面与训练集中样本的函数间隔最小值,下面只要最大化γ^γ^即可。 注意到函数间隔实际上并不能表示点到超平面的距离,因为当超平面(w,b)(w,b)参数扩大相同的倍数后,如(2w,2b)(2w,2b),超平面的位置并没有改变,但是函数间隔也变大了相同的倍数2γ^(i)2γ^(i). 几何间隔: 如上图所示:设样本点A坐标为x(i)x(i),点A到超平面的垂直距离记为γ(i)γ(i),分离超平面wTx(i)+b=0wTx(i)+b=0的单位法向量为w||w||w||w||,因此点B的坐标为x(i)−γ(i)w||w||x(i)−γ(i)w||w||,且点B在直线上,带入直线公式有: wT(x(i)−γ(i)w||w||)+b=0;解得:γ(i)=(wTx(i)+b)||w||wT(x(i)−γ(i)w||w||)+b=0;解得:γ(i)=(wTx(i)+b)||w||
如果点被正确分类,y(i)y(i)与(wTx(i)+b)||w||(wTx(i)+b)||w||的符号一致,由此 同理定义几何间隔:γ(i)=y(i)(wTx(i)+b||w||)同理定义几何间隔:γ(i)=y(i)(wTx(i)+b||w||)
超平面与样本集S的几何间隔为γ=mini=1,2,...m γ(i)超平面与样本集S的几何间隔为γ=mini=1,2,...m γ(i)
几何间隔不随着超平面参数的变化而变化,例如超平面参数(w,b)变为(2w,2b),函数间隔γ^(i)γ^(i)变为2γ^(i)2γ^(i),而几何间隔γ(i)γ(i)保持不变。 函数间隔与几何间隔的关系:γ(i)=γ^(i)||w||γ(i)=γ^(i)||w||;γ=γ^||w||γ=γ^||w||,若||w||=1,函数间隔与几何间隔相同。
1.2间隔最大化 如上所述,支持向量机的基本想法是求解能够正确划分训练数据集并且几何间隔最大的分离超平面。γγ表示分离超平面与训练集中样本的几何间隔的最小值,为了间隔最大化,只需要最大化γγ,同时所有样本的几何间隔必须满足γ(i)≥γ,i=1,2,...,mγ(i)≥γ,i=1,2,...,m; maxw,b γmaxw,b γ
s.t. y(i)(wTx(i)+b||w||)≥γs.t. y(i)(wTx(i)+b||w||)≥γ
上述问题,可以转变为一个凸二次规划问题,这是支持向量机的一个重要属性,局部极值即为全局最值。 考虑函数间隔与几何间隔的关系: 上述优化问题中,当超平面参数(w,b)同时变为(2w,2b),函数间隔也会变为2γ^2γ^,目标函数的解并不会变化。即γ^γ^的取值不影响优化问题的解。因此令γ^=1γ^=1,目标函数变为最大化1||w||1||w||,即最小化||w||2||w||2,为了后面的求解方便,添加因子1212也不影响目标函数的解; 上述问题为一个凸优化问题,通过某些优化算法可以求解。下面继续介绍拉格朗日对偶算法,可以更进一步优化上述问题,同时自然引入核函数,推广到高维数据。
1.3拉格朗日对偶性 有时考虑解决原始问题的对偶问题会更高效。 原始问题 f(w),gi(w),hi(w)f(w),gi(w),hi(w)均为连续可微: 写出拉格朗日函数,其中αi≥0,β≥0αi≥0,β≥0称为拉格朗日乘子: 定义关于ww的函数θP(w)=maxα,βL(w,α,β)θP(w)=maxα,βL(w,α,β);可以证明如果ww满足上述约束条件gi(w)≤0,hi(w)=0gi(w)≤0,hi(w)=0,则有θP(w)=f(w)θP(w)=f(w) 由此原始问题的约束最优化问题变为极小极大问题: 设原始问题的最优解记为p∗=minwf(w)=minwθp(w)p∗=minwf(w)=minwθp(w). 对偶问题 把上述极小极大问题minw maxα,βL(w,α,β)minw maxα,βL(w,α,β),改为极大极小变为对偶问题,即: 定义: 设此极大极小问题的最优解记为d∗d∗,可以证明 为了使得对偶问题与原始问题的最优解相等d∗=p∗d∗=p∗,必须满足下述几个条件,称为KKT条件 1.4最优间隔分类器 回顾原始问题: 写成拉格朗日函数,由于只有不等式约束所以只包含拉格朗日乘子αiαi: 原始问题最优解p∗=minw,b maxαL(w,b,α)p∗=minw,b maxαL(w,b,α);对偶问题的最优解d∗=maxα minw,bL(w,b,α)d∗=maxα minw,bL(w,b,α) 对偶问题先求关于参数w,b的最小值,再求关于参数αα的最大值。 首先,分别对w,b求偏导数并令为0,得: 把上述结果带入拉格朗日函数L(w,b,α)L(w,b,α) 注意到上述是只关于参数αα的函数,记为W(α)W(α),由对偶函数,下一步即最大化W(α)W(α) 下面的目的是解决上述优化问题,通常采用SMO算法,本篇文章暂不做介绍。假如已经得到最优解α=(α1,α2,...,αm)α=(α1,α2,...,αm),带回到上面对w求偏导得到的公式,可以得到ww的值。下面要求得b得值,考虑KKT条件有:αi[y(i)(wTx(i)+b)−1]=0,i=1,2..mαi[y(i)(wTx(i)+b)−1]=0,i=1,2..m,其中必然存在一个αj≠0αj≠0,(否则w=0w=0,不是原始解)。当αj≠0αj≠0时y(i)(wTx(i)+b)=1y(i)(wTx(i)+b)=1,可以解出bb的代数式,b=y(j)−∑mi=1αiy(i)(x(i),x(j))b=y(j)−∑i=1mαiy(i)(x(i),x(j)),也可以对所有采用满足条件的bb加和求平均;然后即可得到最佳分类超平面: 根据KKT条件有αi[y(i)(wTx(i)+b)−1]=0,i=1,2..mαi[y(i)(wTx(i)+b)−1]=0,i=1,2..m,当αi>0αi>0时,必然有y(i)(wTx(i)+b)=1y(i)(wTx(i)+b)=1,即该样本点的函数间隔为1,如下图所示,落在直线wTx+b=±1wTx+b=±1上,此向量即称为支持向量。对于落在直线wTx+b=±1wTx+b=±1以内的点,函数间隔y(j)(wTx(j)+b)>1y(j)(wTx(j)+b)>1,必然有αj=0αj=0,当计算函数最优分割超平面参数w,b时,这些点对应的αj=0αj=0,所以对参数没有影响。只有支持向量,即落在wTx+b=±1wTx+b=±1上数据影响着最优超平面的计算。 2.
我们首先看一下这个速度表盘的效果: [img]http://dl2.iteye.com/upload/attachment/0129/4726/226e1e99-53d5-36b5-a38d-c61635b92e1c.gif[/img] 为了实现上述的效果,我们首当其冲的是得了解的是贝塞尔曲线,听上去好高大上的样子,接下来我先就我了解贝塞尔曲线的知识给未接触的朋友普及一下。 Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线.主要有起始点、终止点(也称锚点)、控制点这几个概念。通过调整控制点,贝塞尔曲线的形状会发生变化。
大家先欣赏一下各种贝塞尔曲线 一阶 [img]http://dl2.iteye.com/upload/attachment/0129/4728/ada01aab-71d8-3343-b143-f12379a76ee0.gif[/img] 二阶 [img]http://dl2.iteye.com/upload/attachment/0129/4730/c9cfbded-3be3-3673-85ab-6906d1f3a313.gif[/img] 三阶 [img]http://dl2.iteye.com/upload/attachment/0129/4732/8c153e85-82c8-36d1-af2f-4a82cb668f26.gif[/img] 高阶 [img]http://dl2.iteye.com/upload/attachment/0129/4734/14075e50-e6d2-310e-8602-5b341dd2ff81.gif[/img] 我们要完成上述表盘的效果,需要用到的就是贝塞尔曲线! 我们看一下苹果官方文档对它的介绍 The UIBezierPath class lets you define a path consisting of straight and curved line segments and render that path in your custom views. You use this class initially to specify just the geometry for your path. Paths can define simple shapes such as rectangles, ovals, and arcs or they can define complex polygons that incorporate a mixture of straight and curved line segments.
方法:
//parm:请求的url链接 返回的是json字符串 public static String getURLContent(String urlStr) { //请求的url URL url = null; //请求的输入流 BufferedReader in = null; //输入流的缓冲 StringBuffer sb = new StringBuffer(); try{ url = new URL(urlStr); in = new BufferedReader(new InputStreamReader(url.openStream(),"UTF-8") ); String str = null; //一行一行进行读入 while((str = in.readLine()) != null) { sb.append( str ); } } catch (Exception ex) { } finally{ try{ if(in!=null) { in.close(); //关闭流 } }catch(IOException ex) { } } String result =sb.
原文链接:https://www.cnblogs.com/chenjinxinlove/p/7040704.html koa的github地址:https://github.com/koajs/koa.git Koa2的安装和简单使用 需要 nodev7.6.0 或者更高的版本,为了支持 ES2015 and async
安装 npm install koa Hello koa const Koa = require('koa'); const app = new Koa(); // response app.use(ctx => { ctx.body = 'Hello Koa'; }); app.listen(3000); 中文的api文档:https://github.com/guo-yu/koa-guide 简单分析koa的代码 打开koa的源码,核心文件共四个在lib目录下,application.js,context.js,request.js,response.js
application.js app的入口文件,就是一个构造函数
简洁的代码 module.exports = class Application extends Emitter { constructor() { super(); //定义下面的属性 this.proxy = false; this.middleware = []; this.subdomainOffset = 2; this.env = process.env.NODE_ENV || 'development'; this.context = Object.create(context); this.
1、Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
需要将hive-site.xml配置文件中作为值使用的${system:java.io.tmpdir}/${system:user.name}全部替换为/path/to/hive/logs
2、Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
这是因为hive元数据库没有初始化成功的原因,在2.x版本中需要手动初始化。
bin/schematool -dbType mysql -initScheme 3、expected a semi-colon after the reference for entity "useSLL"
在xml配置文件中的url参数值后面如果有多个值,不能直接使用&,需要使用&进行转义。
<property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true&useSSL=false</value> <description>&->&:expected a semi-colon after the reference for entity</description> </property> 最终,程序会解析出来javax.jdo.option.ConnectionURL中的&为&
Metastore connection URL: jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true&useSSL=false
Math.random() 会得到一个[0,1) 的随机浮点数。
(int) (Math.random() * 100) 就会得到0-100之间的随机整数。
转自:http://www.cnblogs.com/zhizhan/p/4870429.html
一、引言
分类算法有很多,不同分类算法又用很多不同的变种。不同的分类算法有不同的特定,在不同的数据集上表现的效果也不同,我们需要根据特定的任务进行算法的选择,如何选择分类,如何评价一个分类算法的好坏,前面关于决策树的介绍,我们主要用的正确率(accuracy)来评价分类算法。
正确率确实是一个很好很直观的评价指标,但是有时候正确率高并不能代表一个算法就好。比如某个地区某天地震的预测,假设我们有一堆的特征作为地震分类的属性,类别只有两个:0:不发生地震、1:发生地震。一个不加思考的分类器,对每一个测试用例都将类别划分为0,那那么它就可能达到99%的正确率,但真的地震来临时,这个分类器毫无察觉,这个分类带来的损失是巨大的。为什么99%的正确率的分类器却不是我们想要的,因为这里数据分布不均衡,类别1的数据太少,完全错分类别1依然可以达到很高的正确率却忽视了我们关注的东西。接下来详细介绍一下分类算法的评价指标。
二、评价指标
1、几个常用的术语
这里首先介绍几个常见的模型评价术语,现在假设我们的分类目标只有两类,计为正例(positive)和负例(negtive)分别是:
1)True positives(TP): 被正确地划分为正例的个数,即实际为正例且被分类器划分为正例的实例数(样本数);
2)False positives(FP): 被错误地划分为正例的个数,即实际为负例但被分类器划分为正例的实例数;
3)False negatives(FN):被错误地划分为负例的个数,即实际为正例但被分类器划分为负例的实例数
4)True negatives(TN): 被正确地划分为负例的个数,即实际为负例且被分类器划分为负例的实例数。
上图是这四个术语的混淆矩阵,我只知道FP叫伪阳率,其他的怎么称呼就不详了。注意P=TP+FN表示实际为正例的样本个数,我曾经误以为实际为正例的样本数应该为TP+FP,这里只要记住True、False描述的是分类器是否判断正确,Positive、Negative是分类器的分类结果。如果正例计为1、负例计为-1,即positive=1、negtive=-1,用1表示True,-1表示False,那么实际的类标=TF*PN,TF为true或false,PN为positive或negtive。例如True positives(TP)的实际类标=1*1=1为正例,False positives(FP)的实际类标=(-1)*1=-1为负例,False negatives(FN)的实际类标=(-1)*(-1)=1为正例,True negatives(TN)的实际类标=1*(-1)=-1为负例。
2、评价指标
1)正确率(accuracy)
正确率是我们最常见的评价指标,accuracy = (TP+TN)/(P+N),这个很容易理解,就是被分对的样本数除以所有的样本数,通常来说,正确率越高,分类器越好;
2)错误率(error rate)
错误率则与正确率相反,描述被分类器错分的比例,error rate = (FP+FN)/(P+N),对某一个实例来说,分对与分错是互斥事件,所以accuracy =1 - error rate;
3)灵敏度(sensitive)
sensitive = TP/P,表示的是所有正例中被分对的比例,衡量了分类器对正例的识别能力;
4)特效度(specificity)
specificity = TN/N,表示的是所有负例中被分对的比例,衡量了分类器对负例的识别能力;
5)精度(precision)
精度是精确性的度量,表示被分为正例的示例中实际为正例的比例,precision=TP/(TP+FP);
6)召回率(recall)
召回率是覆盖面的度量,度量有多个正例被分为正例,recall=TP/(TP+FN)=TP/P=sensitive,可以看到召回率与灵敏度是一样的。
7)其他评价指标
计算速度:分类器训练和预测需要的时间; 鲁棒性:处理缺失值和异常值的能力; 可扩展性:处理大数据集的能力; 可解释性:分类器的预测标准的可理解性,像决策树产生的规则就是很容易理解的,而神经网络的一堆参数就不好理解,我们只好把它看成一个黑盒子。 对于某个具体的分类器而言,我们不可能同时提高所有上面介绍的指标,当然,如果一个分类器能正确分对所有的实例,那么各项指标都已经达到最优,但这样的分类器往往不存在。比如我们开头说的地震预测,没有谁能准确预测地震的发生,但我们能容忍一定程度的误报,假设1000次预测中,有5次预测为发现地震,其中一次真的发生了地震,而其他4次为误报,那么正确率从原来的999/1000=99.9%下降到996/1000=99.6,但召回率从0/1=0%上升为1/1=100%,这样虽然谎报了几次地震,但真的地震来临时,我们没有错过,这样的分类器才是我们想要的,在一定正确率的前提下,我们要求分类器的召回率尽可能的高。
http://blog.sciencenet.cn/blog-460603-785098.html
分类是一种重要的数据挖掘算法。分类的目的是构造一个分类函数或分类模型(即分类器),通过分类器将数据对象映射到某一个给定的类别中。分类器的主要评价指标有准确率(Precision)、召回率(Recall)、Fb-score、ROC、AOC等。在研究中也有采用Accuracy(正确率)来评价分类器的。但准确率和正确率这两个概念经常有人混了。【没有耐心看下面内容的博友请看最后的结论】
准确率(Precision) 和召回率(Recall)是信息检索领域两个最基本的指标。准确率也称为查准率,召回率也称为查全率。它们的定义如下:
Precision=系统检索到的相关文件数量/系统检索到的文件总数量
Recall=系统检索到的相关文件数量/系统所有相关文件数量
Fb-score是准确率和召回率的调和平均:Fb=[(1+b2)*P*R]/(b2*P+R),比较常用的是F1。
在信息检索中,准确率和召回率是互相影响的,虽然两者都高是一种期望的理想情况,然而实际中常常是准确率高、召回率就低,或者召回率低、但准确率高。所以在实际中常常需要根据具体情况做出取舍,例如对一般搜索的情况是在保证召回率的情况下提升准确率,而如果是疾病监测、反垃圾邮件等,则是在保证准确率的条件下,提升召回率。但有时候,需要兼顾两者,那么就可以用F-score指标。
ROC和AUC是评价分类器的指标。ROC是受试者工作特征曲线 receiver operating characteristic curve ) 的简写,又称为感受性曲线(sensitivity curve)。得此名的原因在于曲线上各点反映着相同的感受性,它们都是对同一信号刺激的反应,只不过是在几种不同的判定标准下所得的结果而已[1]。ROC是反映敏感性和特异性连续变量的综合指标,是用构图法揭示敏感性和特异性的相互关系,它通过将连续变量设定出多个不同的临界值,从而计算出一系列敏感性和特异性,再以敏感性为纵坐标、(1-特异性)为横坐标绘制成曲线。AUC是ROC曲线下面积(Area Under roc Curve)的简称,顾名思义,AUC的值就是处于ROC curve下方的那部分面积的大小。通常,AUC的值介于0.
安装Centos7之后,系统安装了libreoffice 3.x版本。现在想安装 6.x版本。 在自己的电脑上亲自实验安装成功,下面是每一步操作的纪录
卸载系统当前的libreoffice 执行如下命令:
yum remove libreoffice-* 为了能使用镜像,在etc 目录之下的hosts文件内加入代理。 注意没有加的话,可能第三步无法操作.可不加。
.208.46.146 www.google.com .208.46.146 dl.google.com .208.46.146 dl-ssl.google.com 获取rpm文件 http://mirrors.ustc.edu.cn/tdf/libreoffice/stable 选择6.0.3 (可能发布最新版时候就是5.05,目前我使用的是6.0.3) 然后选择rpm然后选择x86_64
http://mirrors.ustc.edu.cn/tdf/libreoffice/stable/6.0.3/rpm/x86_64/ 下载3个文件 LibreOffice_6.0.3_Linux_x86-64_rpm.tar.gz LibreOffice_6.0.3_Linux_x86-64_rpm_sdk.tar.gz LibreOffice_6.0.3_Linux_x86-64_rpm_langpack_zh-CN.tar.gz ceontos直接复制代码就行
wget http://mirrors.ustc.edu.cn/tdf/libreoffice/stable/6.0.3/rpm/x86_64/LibreOffice_6.0.3_Linux_x86-64_rpm.tar.gz wget http://mirrors.ustc.edu.cn/tdf/libreoffice/stable/6.0.3/rpm/x86_64/LibreOffice_6.0.3_Linux_x86-64_rpm_sdk.tar.gz wget http://mirrors.ustc.edu.cn/tdf/libreoffice/stable/6.0.3/rpm/x86_64/LibreOffice_6.0.3_Linux_x86-64_rpm_langpack_zh-CN.tar.gz 解压文件,执行如下命令 mkdir /usr/libreoffice tar -zxvf LibreOffice_6.0.3_Linux_x86-64_rpm.tar.gz -C /usr/libreoffice/ tar -zxvf LibreOffice_6.0.3_Linux_x86-64_rpm_sdk.tar.gz -C /usr/libreoffice/ tar -zxvf LibreOffice_6.0.3_Linux_x86-64_rpm_langpack_zh-CN.tar.gz -C /usr/libreoffice/ 进入到的RPMS目录 上面两个文件解压之后,/usr/libreoffice/下面会有3个文件夹,里面都有一个RPMS文件夹
LibreOffice_6.0.3_Linux_x86-64_rpm LibreOffice_6.0.3_Linux_x86-64_rpm_sdk LibreOffice_6.0.3_Linux_x86-64_rpm_langpack_zh-CN
进入到LibreOffice_6.0.3_Linux_x86-64_rpm的rpm ,执行入下命令 cd /usr/libreoffice/LibreOffice_6.0.3_Linux_x86-64_rpm/RPMS 用yum来进行rpm的安装,不要用rpm命令来进行安装 yum localinstall *.rpm
【注意: 因为有 依赖关系 libgnomevfs-2.
java执行sql语句使用别名时显示Column ‘*’ not found 在做一个小项目时遇到个问题,执行sql语句使用别名时总是报sql异常 Column ‘*’ not found,折腾半天终于找到了原因,下面是具体的错误,如果大家遇到同样的问题在找解决方法,可直接跳过看最后的解决方法。
问题描述 我在本地使用的是java、mysql、tomcat 服务器上的数据库为MariaDB(完全兼容MySQL) 在服务器上MariaDB中建立test数据库,新建student表如下 执行sql语句 select name as id , age as StuAge from student 带有as设置别名
在本地发布工程,连接服务器上的数据库,可以正常执行 而把工程原封不动的发布在服务器上,却获得不了数据,查看日志报一下异常: 两次测试用的是同一个数据库,问题应该不会出在MariaDB的配置上,对此也做了个小验证: 正常获得数据,猜测没错。
那么,异常的原因肯定就出在tomcat的配置或服务器自身了,服务器是租的成熟的云服务器,问题应该不大。先从tomcat下手。
找了半天,终于发现了本地和服务器上的tomcat的不同,使用tomcat连接池,tomcat/lib下mysql-connector-java版本不同! 服务器上为5.1.14,本地为3.1.12。百度了下两个版本,确实有类似的问题!
解决方法一 简单粗暴,直接把服务器的驱动版本换为3.1.12(只测试过这个版本可行,其他不确定),去下载
解决方法二 在连接池配置中,url加以下内容:
…:3306/test?characterEncoding=UTF-8&useOldAliasMetadataBehavior=true
如图: 注意在xml中&要用&;代替,不能有空格!
亲测以上方法都可用!
参考https://www.2cto.com/database/201507/414486.html
MND解释:Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。
我的理解就是promise是一种完成异步功能并检查状态触发回调的机制。
1、两种常用创建方式: 声明一个变量:(声明一个promise类型的对象)
const myFirstPromise = new Promise((resolve, reject) => { // ?做一些异步操作,最终会调用下面两者之一:// resolve(result); // fulfilled// ?或 reject(error); // rejected}); 声明一个函数:(返回一个promise类型的对象)
function myAsyncFunction(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onload = () => resolve(xhr.responseText); xhr.onerror = () => reject(xhr.statusText); xhr.send(); }); }; 显而易见,如果需要给异步过程传递函数,当然要优先选择第2种方式了。
2、promise的状态 promise的中文释义为承诺,对象如其名,在未来的某一个时刻将会有状态变化进而有真实的结果。当代码执行到变量myFirstPromise或调用函数myAsyncFunction时,得到的都应该是一个空值或空对象,同时会有一个new promise()对象被构建。此时的promise对象处于一种名为pending状态,表示为初始状态。此时promise开始执行。
new promise( /*...code...*/ ) 中的code只是相当于一个参数被传递给promise对象,和以往的函数调用传参的不同在于:code是函数类型的参数 (resolve, reject) => { } ,不是一个字符串、数值等等类型的参数。这个函数类型的参数code只接收resolve、reject两种类型的参数。code函数体内可以正常使用当前文件里的变量参数、函数等等。
promise执行过程中,对我们来说最终的就是这个具有定制意义的code参数,该参数可以是一个XHR请求、setTimeout()函数等等。执行code,如果顺利完成,得到我们预期的正确结果,promise对象将处于一种名为fulfilled状态,表示操作成功完成。执行code,如果未完成,将可以报错,promise对象将处于一种名为rejected状态,表示操作失败。此时我们之前声明的变量或函数的调用将有一个结果:兑现承诺,得到的仍然是之前的promise,只是此时此刻,它有了新的状态,表明之前的承诺有了结果。
3、promise的回调 promise状态从pending改变后,它将触发(异步调用)相应的函数(如同我们之前常用的回调函数),这些函数存在于promise的yuanxing里如then()、catch(),当然还有一个finally()。
this.addEventListener(egret.TouchEvent.TOUCH_BEGIN, (event) => { if (event.target!=this) return;//防止按钮事件冒泡穿透 this.isCancelTap = false; }, this) 转载于:https://www.cnblogs.com/guochunyang2004/p/8729189.html
ubuntu16.04配置tensorflow-gpu 个人记录:
安装nvidia驱动安装cuda安装cudnn安装tensorflow-gpu 安装nvidia驱动 软件更新-安装之后,cuda安装驱动的地方选择no
安装cuda 参考:https://blog.csdn.net/qlulibin/article/details/78714596
安装cudnn 参考:https://www.cnblogs.com/go-better/p/7625541.html
安装tensorflow-gpu 感谢参考链接的作者 cuda9.1与tensorflow不融洽,这个大坑要躲开
当你觉得你的脚本没有问题,但是却又怎么也出你想要的结果时,你就需要用到调试了
一个是设置context.log_level="debug"
脚本在执行时就会输出debug的信息,你可以通过观察这些信息查找哪步出错了
而另一个就是 用pwnlib.gdb.attach(p)
在发送payload前加入这条语句,同时加上pause() 时脚本暂停
然后就会弹出来一个开启着gdb的终端,你先在gdb中设置好断点
然后再运行脚本的那个终端按一下回车继续运行脚本,程序就会运行到断点,你就可以查看相应的寄存器,或者是栈的信息
例如:
from pwn import* import pwnlib p = process('./xxxx') payload = ..... pwnlib.gdb.attach(p) pause() p.sendline(payload) p.interactive()
JAVA和C语言在基本的数据类型上的比较
1. 数据类型:
共同点:数据类型决定了内存中存储数据的类型及所需内存的大小。
都满足自动类型转换和强制类型转换。
都通过定义变量来申请数据存储空间,并通过变量名获取或改变存储的值。
常量是值不可变的变量,即不能重新赋值。
不同点:
Java:Java的数据类型可分为两大类:
-基本数据类型:byte、short、int、long、double、float、boolean、char
-引用数据类型:类、接口、数组、枚举、注解
变量与常量:
-常量有final关键字修饰。
基本数据类型引用:
-定义float类型时,赋值时一定要在浮点数后加f,否则自动视为double类型,且会编译失败。
-Java中当高精度赋值给低精度类型时,会编译失败,显示不兼容的类型。
-Java中字符型中字符对应的Unicode编码。
-Java字符型占两个字节。
C语言:C语言的数据类型可分为:
-基本数据类型:short int、int、long int、double、float、char、long longint(C99增加)、long double、bool(C99增加)、float_complex、double_complex、long long _complex
-枚举类型:enum
-空类型:void
-派生类型:指针类型(*)、数组类型([])、结构体类型(struct)、共用体类型(union)、函数类型 变量与常量:
-常量由#define定义。
基本数据类型引用:
-C语言中定义浮点型不会出现类似问题。
-C语言中当高精度赋值给低精度类型时,会有精度缺失,但并不会造成编译失败。
-C语言中字符型中字符对应ASCII码。
-C语言中字符型占一个字节。
2. 计算机内的储存原理:
共同点:补码是计算机用于规范计算的一种二进制表示方式,由于计算机使用数值的第一位来表示数据的正负,例如:00000011表示+3,而10000011表示-3,这些非0数值在逻辑上的表示都是没有问题的,这中表示方法称为源码表示法。但是用00000000表示+0,而10000000表示-0,则出现逻辑上的偏差,即:+0 不等于 -0。为了解决这个问题,提出了补码表示法。
• 补码的计算公式:
正数:源码、反码和补码都相同。
负数:补码 = 反码(符号位保持不变)+ 1
• 注意:
负数在计算补码的时候,在源码取反的过程中要保留符号位不变,其他位取反,例如:10001010取反11110101(第一个1不变)。
不同点:
Java:先将编码转换为字节码文件,再通过JVM虚拟机转换为二进制码,再储存到计算机中,由计算机输出内容。
C语言:直接将编码转换为二进制码,由计算机识别输出。
3. 标识符:
共同点:各种数据类型的定义都需要标识符。
标识符标准的比较:
Java:Java标识符有如下命名规则:
1、标识符由字母、数字、 “_”、 “$”组成,且首字母不能是数字;
2、不能把Java关键字作为标识符;
3、标识符没有长度限制;
4、标识符对大小写敏感。
5、自定义标识符最好取具有一定意义的字符串,便于记忆和理解。
C语言:C语言标识符有如下规则:
1、标识符必须以字母a~z、 A~Z或下划线开头,后面可跟任意个(可为0)字符,这些字符可以是字母、下划线和数字,其他字符不允许出现在标识符中。
Xms 我猜测是EXtended Memory Size可扩展的内存大小,Xmx是EXtended Memory Max Size 可扩展的最大内存(就算不是,这样理解记忆也挺好的) Xms 通常为操作系统可用内存的1/64大小 Xmx 是对堆区的内存配置,Xms是初始化的内存大小,Xmx是堆的最大内存,通常为操作系统可用内存的1/4大小。 详细参考: https://blog.csdn.net/qq_27258799/article/details/51599093 https://www.cnblogs.com/koik/p/4452029.html
请回答,国产手机的18年历史(转) 江湖上流传着一个特殊班级,被称为国产班。 它历经数十年,培育出的莘莘学子一举超越欧洲班、美国班以及日本班,并问鼎全年级,令人羡煞。 然而,曾经的国产班学生,其实成绩特别差,不仅基础薄弱,还不会独立思考,总喜欢抄袭别人的作业,让班主任很头痛。 当时,班上的第一名是波导同学,学霸级人物,他有一个响亮的名头:“波导同学,同学中的战斗机,非洲人民都爱的波导同学。” 除了波导,还有靓丽的厦新妹子,第一次期中考试她就“惊艳”了整个年级,并获得奥数竞赛一等奖,十分厉害。 熊猫同学的努力一直有目共睹,他和欧洲班的爱立信是好基友,一直珍藏着和梁朝伟的合照。在一次文艺晚会上,熊猫的父亲参与赞助,让熊猫在学校的名气大幅提升。 最厉害的还属中兴,虽然成绩普通,但他很擅长捣鼓一些通讯作品,在国外经常能拿大奖。 国产班看似实力辉煌,班主任却心知肚明,波导、厦新和熊猫如果放在在年级排名中,根本就不入流,整个班级缺乏一种危机感,都在享受虚假的繁荣。 更让他苦恼的是,每次改完学生作业,答案高度一致,完全抄袭欧洲班的学霸诺基亚和爱立信。因此,他决定要改变这种现状。 高一下学期 转机出现在高一下学期,班主任想到一个妙计,他以交换生的名义,邀请诺基亚、摩托罗拉和爱立信等人来国产班交流学习。这样下来,有超级学霸的带领下,国产班的学渣就能共同进步了。 理想和现实总会有鸿沟。很快,诺基亚就让国产班的学霸知道花儿为什么这样红,他连续6次月考全级第一,花式吊打波导和熊猫。 摩托罗拉等插班生同样强势,其他学渣的自信渐渐受挫,心灰意冷,选择自暴自弃,脱离了班主任的预期。 雪上加霜的是,学校发现国产班两极分化很严重,便制定淘汰制度,凡是月考倒数前五名的学生,一律以退学处理。 波导有点慌了,前十名的位置已经不保,在同学中的威望快速下跌,而熊猫和厦新也是愁眉苦脸。 令学渣羡慕的是,魅族和步步高作为艺术生,一点都没有危机感,天天坐在后排听MP3,哼着歌曲,逍遥自在。 天语对这些插班生没什么好感,他带头闹事,经常抄袭作业,嘴上总挂着口头禅:“我凭本事抄的作业,为什么要动脑筋学习!” 第一个受不了国产班死气沉沉的是传音,他主动申请调到非洲班,惹得同学一阵鄙夷。再不行的国产班,依然比非洲班有优越感。 接下来,松下、夏普、LG、索爱和西门子都进入国产班,牢牢占据班级前十名,将更多不思进取的学渣淘汰掉,班主任只能干着急。 幸好,国产班冲上来几名后起之秀,如联想、中兴和华为,班主任终于捡回一点颜面,并全力栽培他们。 高二上学期 国产班又来了一名气质非凡的艺术生:苹果。 他和魅族一样,都是学音乐的,整天塞着耳机听MP3,嘴里哼着难以听懂的曲调,性格很孤僻。 经过一番洗牌后,班级前十名稳定下来,诺基亚是当之无愧的老大,摩托罗拉和三星为抢夺第二名争来争去。 相貌平平无奇的LG,渐渐站稳第三名,就连一向神秘高贵的班花黑莓,也不声不响冲到了前五。 华为和中兴尚在埋头苦读,班主任寄予更多希望的是HTC,他作为国产班的领头人,实力稳步提升,在班级前列扎根,赢回了一丝国产尊严。 有一次数学课上,诺基亚和摩托罗拉为了一道题吵起来,争论谁的解题方法更好,一旁的学生只有吃瓜的份,没资格说话。 这时候默默听歌的苹果发话了:“这也叫解题?我教你们什么是真正的数学思维。”于是,他放下MP3,大步走上讲台,刷刷刷地写出一大串公式。 诺基亚有着鲁莽的老大哥气质,他只瞄了眼就不屑道:“老子摸过的试卷比你听过的歌还要多,就你这种解题方法,考试根本不行!” 台下一阵哄堂大笑,只有谷歌在皱眉,他认真琢磨苹果的思路,越看心里就越凉,默念着:苹果野心太大,诺基亚的老大位置不保。 果然,今后的试卷出现大刀阔斧的改革,原先的解题思路全部过时。苹果凭借独一无二、无法模仿的解题思路“iOS”,成绩扶摇直上,冲到班级前茅,欲要动摇诺基亚的老大位置。 此外,作为班草的苹果,穿着打扮一直站在潮流最前线,领先所有学生的衣品,吸引无数人的眼球。 虽然他们无法模仿iOS的解题思路,但是可以模仿苹果的外形打扮,因为那样真的很酷很时尚。 诺基亚开始慌了,他表面上波澜不惊,固执地守着自己的僵硬思路,强行考试,惹得老师经常皱眉。 聪明的谷歌早已联合34名学生,成立“开放解题联盟”,讨论出新的解题“安卓”,三星、LG、摩托罗拉和HTC同样参与其中。 眼看“iOS”和“安卓”声势浩大,诺基亚很烦恼,他实在无法拉下脸皮进入安卓阵容,毕竟“塞班”是维持他江湖老大的唯一制胜法宝,拥有控制权和话语权。 他不敢想象,如果真的用“安卓”去解题,到时候会有人在一旁叽叽哇哇:“看,那个诺基亚不是很拽吗,怎么用“安卓”解题的速度这么慢?分数也不高啊?” 就在这时,一个叫微软的外校妹子出现,她知道诺基亚的苦恼,便抛出橄榄枝,主动传授“WindowsPhone”,承诺给予诺基亚超然的地位。 诺基亚确实心动了,加上微软妹子说话很好听,脑袋一热,听从了她的建议。 高二下学期 HTC充分吸收“安卓”的思路后,第一次在考试中发挥出来,成绩果然迅猛提升。 三星的实力同样很强,作为高富帅的他,拥有最多的家教和最齐全的学习工具,加上形象极佳,一举将诺基亚拉下老大位置,牢牢占据第一名。 苹果虽然无缘第二,但他凭借“iOS”打败天下无敌手,多次获得奥数竞赛冠军和选秀冠军,成为学校的最强风云人物。 当大部分学生都在用“安卓”解题时,只有黑莓坚守自己的思路,导致很多改卷老师看不懂,成绩自然下滑,处于淘汰的边缘。 最落魄的是诺基亚和摩托罗拉两人。 诺基亚发现微软妹子越来越不靠谱,用“WindowsPhone”解题很费劲,他只能干着急,内心却一直暗恋着她,将所有怨言往肚子里吞,既然上了贼船,只能咬牙挺下去了。 摩托罗拉让人惋惜,虽然他早早用上“安卓”去解题,脾气却很倔强,经常和老师顶撞,导致成绩大跌。 后来他的脾气有所收敛,不过投靠谷歌后依然不思进取,成绩下滑如雪崩,不复王者风范。 所谓强者恒强,弱者恒弱,原本国产班有无数种解题思路,百花齐放,现在只有“iOS”和“安卓”两种,班主任不知道是好事还是坏事。 但令他生气的是,国产班的学生就像扶不起的阿斗,既错过“安卓”解题,又没有任何补救措施,整天得过且过。 最终,班主任抓着华为带头去学习“安卓”,做一个好表率。尝到“安卓”甜头后,华为当即告诉弟妹:你们啊,想提高成绩,赶紧学习“安卓”呀。 正因为有华为的鼓动,中兴使用“安卓”后,智商一下开窍,成绩突飞猛进,一度冲进班级前五名,让班主任笑得合不拢口。 整天听MP3的魅族,脑袋同样开了窍,某次当他看到苹果身边总有一群妹子围着转时,仿佛一道晴天霹雳,瞬间做出决定:放下MP3,好好学习。 高三上学期 国产班依然被苹果、三星、诺基亚和LG把持着前几名,众学渣熬了几年后,终于让班主任看到一丝希望。 班上渐渐出现“中华酷联”的呼声,他们代表着国产班最后的尊严,也是开疆扩土的前锋,更是学渣们唯一的精神寄托。 就连班主任都以为国产班格局已定时,一个不起眼的学生开始冒泡,他就是小米。 和班级里的高富帅Lenovo、海尔双胞胎不一样,小米身上带着一股朴实气质,经常露出憨厚的笑容,逢人就说:“Are you OK?” 这一切假象逃不过格力女士的金睛火眼:“我赌10元!小米太鸡贼了,当初我就看不起他的做法!”同学们都以为小米会被淘汰,没想到他开了挂,成绩上升比坐火箭还要快,就连最难的附加题都能解出来,让大家跌破双下巴。 班主任眼光火热,这是国产班辉煌的前兆啊,便急忙让小米分享学习心得。 小米第一次站在讲台上,语气略带紧张,还有点结巴,他缓缓说出自己的制胜攻略。 原来,小米洞察出这群尖子生的软肋,不懂得用互联网思维解题,曲高和寡。于是他运用“饥饿”思路,冠以“发烧”名义,渐渐脱颖而出。 竟然还有这种操作!一群尖子生虽然佩服,内心却很不屑,如此没有技术含量的营销技巧,不值得模仿。 反而吊车尾的学渣,一个个狰狞着眼珠子,摩拳擦掌,他们从来没有放弃成为一个伟大学霸的理想,小米成功点燃起他们心中的那团火。 于是,小米自创的互联网解题,解救了无数水深火热的学渣,如锤子、小辣椒魅蓝、一加和乐视等,开始在班上发光发热。 意外的是,学生们都不喜欢乐视,因为他总是说同学坏话,又不尊重他人,还向老师打小报告,让快播同学退学。 OPPO和vivo也想学习小米模式,却没有这方面慧根,苦苦摸索许久。后来他们发现,每个人都在追求所谓的“学习技巧”,为何不能踏实地背书呢? 领悟到这一层道理后,他们开始挑灯夜战,熬夜背书。由于宿舍没有光线,他们就坐在路灯下学习,称为“线下地推”法,如今每个大街小巷,都有OV勤劳的身影。 天语混的越来越落魄,眼看没有学生跟着他抄袭作业,心里惴惴不安,却不肯专心学习。最终,他在一次考试中被校领导抓住,离开了国产班。 一直以来,班主任有点气恼,国产班的学渣自从用“安卓”解题后,总是狗尾续貂,添加各种不实用的步骤,并美其名“创新”,结果一到考试全都遭殃。 他将这群自以为是的学生臭骂一顿后,终于有所收敛,老实了起来。 高三下学期 如今,华为成为国产班的扛把子,和三星、苹果平起平坐。OPPO、vivo、小米、金立和中兴等同学牢牢霸占前十名。 在一次课间操上,三星比较调皮,玩起了鞭炮,不慎将自己炸伤,住院有一段时间。等到出院后,他却找不回学习状态了,让人惋惜。 小米一如既往地争强好胜,喜欢参加各种生活大赛,即使没获奖也要露个脸,家里更是堆满各种奖项:打扫卫生一等奖、全国平衡车大赛安慰奖、空气净化特等奖.
目录 目录一、参考文献二、勇敢尝试三、最终选择交互方式 一、参考文献 原生Ajax与JQuery Ajax
SpringMVC接受JSON参数详解及常见错误总结
提交方式为 POST 时,
JQuery Ajax 以 application/x-www-form-urlencoded 上传 JSON对象 ,
后端用 @RequestParam 或者Servlet 获取参数。
JQuery Ajax 以 application/json 上传 JSON字符串,
后端用 @RquestBody 获取参数。
总结成表 Controller接收参数以及参数校验AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式 二、勇敢尝试 前端js发送ajax请求( application/x-www-form-urlencoded )
var jsonObj = {"openid":"xxx","username":"Ed sheeran","password":"123"}; /* Jquery默认Content-Type为application/x-www-form-urlencoded类型 */ $.ajax({ type: 'POST', url: "/login", dataType: "json", data: JSON.stringify(jsonObj), success: function(data) { console.log(data) }, error: function() { console.log("fucking error") } });
后端Servlet接受参数。前端报 200,后端报 返回值都是null
1.前言 本渣最近在学习《深入理解Java虚拟机 JVM高级特性与最佳实践》,看到关于对象内存分配的时候,书中有段测试对象分配的代码,自信满满地以为已经理解了其内存分配策略,结果自己在电脑上敲了一下,发现并不是那么回事,运行结果根本不一样,这是怎么回事呢?难道是作者大神搞错了?不,一定不是。分析本机GC日志发现,代码示例和本机默认使用的收集器不一样,代码示例中用的是 Serial/Serial Old 组合收集器,而本机的默认的是 Parallel Scavenge/Parallel Old 组合收集器,这才明白内存分配策略要根据具体使用的收集器而定。以下将针对这两种收集器组合进行详细对比。
2.环境: java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
JVM 为 Server 模式
3.代码 以下代码限定了Java堆大小为20M,不可扩展,其中新生代为10M,老年代为10M,且新生代中 Eden:Survivor=8:1。
/** * 对象内存分配测试 * @author huangyan */ public class ObjectAllocationTest { private static final int _1MB = 1024 * 1024; /** * 1.VM 参数,默认使用 Parallel Scavenge/Parallel Old: * -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 * 2.
编译程序包括 预编译, 编译,汇编,链接,包含头文件了,仅能说明有了线程函数的声明, 但是还没有实现, 加上-lpthread是在链接阶段,链接这个库。pthread是动态库,需要用-lpthread,所有的动态库都需要用-lxxx来引用用gcc编译使用了POSIX thread的程序时通常需要加额外的选项,以便使用thread-safe的库及头文件,一些老的书里说直接增加链接选项 -lpthread 就可以了而gcc手册里则指出应该在编译和链接时都增加 -pthread 选项编译选项中指定 -pthread 会附加一个宏定义 -D_REENTRANT,该宏会导致 libc 头文件选择那些thread-safe的实现;链接选项中指定 -pthread 则同 -lpthread 一样,只表示链接 POSIX thread 库。由于 libc 用于适应 thread-safe 的宏定义可能变化,因此在编译和链接时都使用 -pthread 选项而不是传统的 -lpthread 能够保持向后兼容,并提高命令行的一致性。目前gcc 4.5.2中已经没有了关于 -lpthread的介绍了。所以以后的多线程编译应该用-pthread,而不是-lpthread。
字符串str:在python中用” ” 双引号,或者 ’ ‘单引号括起来的内容就是字符串,本文只写了简单的字符串的用法,字符串中的函数操作有很大的作用,再以后的编程中将会经常用到。
字符串拼接 str1+str2,输出中间没有空格
str1 = "Hello World" str2 = "Today is full of hope" print(str1+str2) 字符串不能直接与其他类型拼接在一起,只能转换成字符串以后再进行拼接
乘法运算 * 重复输出字符串
print(str1 * 3) 字符串单个访问str[],c起始位置为0
print(str1[2]) 字符串的截取,包前不包后
print(str1[2:8]) 成员运算符 in/not in 如果字符串中包含给定字符,返回True,否则返回Fals 转意字符;就是具有特殊含义的字符 \n 换行 \ 反斜杠符号 \’ 单引号 \” 双引号 \t 横向制表符 “”” “”” 中间可以放换行的字符串 如果字符中有好多字符串都需要转义,就需要加入好多\, 为了简化,Python允许用r表示内部的字符串默认不转义
print("Today is full of 'hope'") 字符串操作函数 以下为字符串的简单操作函数,由于用法简单,故直接列出来,没有进行代码演示
len() 方法返回对象(字符、列表、元组等)长度或项目个数。 len = len(str1) eval() 函数用来执行一个字符串表达式,并返回表达式的值。 string.lower() 转换 string 中所有大写字符为小写. string.upper() 转换 string 中的小写字母为大写 string.
(1)视图透明度,值在0-1之间,0为完全透明,1为完全不透明 android:alpha setAlpha(float) (2)视图背景 android:background setBackgroundResource(int) (3)视图是否可点击 android:clickable setClickable(boolean) (4)设置view的备注说明,作为一种辅助功能提供,为一些没有文字描述的View提供说明 android:contentDescription setContentDescription(CharSequence) (5)设置绘图时半透明质量。auto-默认,有框架决定 high-高质量,使用较高的颜色深度,消耗更多内存。 low-低质量,使用较低颜色深度,但是用更少内存 android:drawingCacheQuality setDrawingCacheQuality(int) (6)直接从父容器中获取绘图状态 android:duplicateParentState (7)定义没有使用ScrollBar的时候,是否褪色 android:fadeScrollbars setScrollbarFadingEnabled(boolean) (8)设置边框渐变的长度 android:fadingEdgeLength getVerticalFadingEdgeLength (9)view 窗口被其他窗口覆盖的时候是否过滤触摸事件 android:filterTouchesWhenObscured setFilterTouchesWhenObscured(boolean) (10)设置布局调整的时候是否考虑系统窗口(如状态栏) android:fitesystemWindows setFocusable(boolean) (11)是否获得焦点(若有requestFocus()被调用 优先处理这个) android:focusable setFocusable(boolean) (12)设置在touch模式下view是否能获取焦点 android:focusableInTouchMode setFocusableInTouchMode(boolean) (13)设置是否启动触摸反馈,启动就是在触摸的时候有震动等效果。 android:hapticFeedbackEnabled setHapticFreebackEnabled(boolean) (14)定义ID android:id setId(int) (15)设置可达性的重要性 android:impotantForAccessibility setImportantForAccessibility(int) (16)设置view为滚动效应 android:isScrollContainer setScrollContainer(int) (17)视图在可见的情况下是否保持亮屏 android:keepScreenOn setKeepScreenOn(boolean) (18)设置指定层的类型,可以取以下3个值: none——不指定 software——软件层。 hardware——硬件层。使用硬件加速。" android:layerType setLayerType(int,Paint) (19) 定义布局图纸的方向 android:layoutDirection setLayoutDirection(int (20)是否响应长点击事件 android:longClickable setLongClickable(boolean) (21)设置视图最小高度 android:minHeight setMinimumHeight(int) (22)设置视图最小宽度 android:minWidth setMinimumWidth(int) (23)下一个获取焦点的view的id android:nextFocusForward setNextFocusForwardId(int) (24)向下移动焦点时,下一个获取焦点的view的id android:nextFocusDown setNextFocusDownId(int) (25)向左移动焦点时,下一个获取焦点的view的id android:nextFocusLeft setNextFocusLeftId(int) (26) 向右移动焦点时,下一个获取焦点的view的id android:nextFocusRight setNextFocusRightId(int) (27) 向上移动焦点时,下一个获取焦点的view的id android:nextFocusUp setNextFocusUpId(int) (28)点击时,要调用的方法的名称。 android:onClick setOnClick() (29) 设置上下左右的边距 android:padding setPaddingRelative(int,int,int,int) (30)下边距 android:paddingBottom setPaddingRelative(int,int,int,int) (31)右边距 android:paddingRight setPadding(int,int,int,int android:paddingEnd setPaddingRelative(int,int,int,int) (32)左边距 android:paddingLeft setPadding(int,int,int,int) android:paddingStart setPaddingRelative(int,int,int,int (33) 定义滚动时边缘是否褪色 android:requiresFadingEdge setVerticalFadingEdgeEnabled(boolean) (34)旋转度数 android:rotation setRotation(float) (35)水平旋转度数 android:rotationX setRotationX(float) (36) 竖直旋转度数 android:rotationY setRotationY(float) (37)在配置改变等情况出现时是否保存view的状态数据。如果你的view有id,那默认系统就会帮你保存。 android:saveEnabled setSaveEnabled(boolean) (38) 水平方向缩放比例 android:scaleX setScaleX(float) (39)竖直方向缩放比例 android:scaleY setScaleY(float) (40)x方向的滚动偏移。即在水平方向滚动了多少距离 android:scrollX (41) y方向的滚动偏移。即在竖直方向滚动了多少距离 android:scrollY (42) 是否总是绘制水平滚动条的滚动轨道 android:scrollbarAlwaysDrawHorizontalTrack (43)是否总是绘制竖直滚动条的滚动轨道 android:scrollbarAlwaysDrawVerticalTrack (44)滚动条在n毫秒后开始淡出。 android:scrollbarDefaultDelayBeforeFade setScrollBarDefaultDelayBeforeFade(int) (45)滚动条用多长时间淡出完毕。 android:scrollbarFadeDuration setScrollBarFadeDuration(int) (46)设置滚动条的尺寸。垂直滚动条的宽度、水平滚动条的高度 android:scrollbarSize setScrollBarSize(int) (47)"
找到gitbash快捷图标,右键,点击属性 废话不多直接上图: 将目标: –cd -to-home 删掉 起始位置填写即将打开的路径,如下图。点击【应用】【确定】。
1.附加到进程调试
此方法适用于项目(b/s)生成需要大量时间的项目调试
方法:
1.1.将项目部署到本地iis上进行发布,发布好之后通过浏览器打开该项目。
1.2.在浏览器中打开之后在vs环境中点击“工具”---“附加到进程”出现该窗口。
1.3.再该窗口“可用进程”列表上左键单击找到‘w3wp.exe‘ 然后点击“附加”。
注意:你要是找不到该进程可以看是否勾选了“显示全部进程”。
1.4.配置好之后,你在要调试的地方添加断点,即可进行断点调试。
2.TestDriven.NET 插件单元调试
https://www.cnblogs.com/AlexLiu/archive/2008/12/01/1345002.html
https://www.cnblogs.com/stan0714/archive/2009/01/12/1374004.html
作者:【果冻:https://blog.csdn.net/jelly_9】
Description:
Field testService in com.xxx.xxx.api.controller.TestController required a bean of type 'com.xxx.xxx.service.TestService' that could not be found.
Action:
Consider defining a bean of type 'com.xxx.xxx.service.TestService' in your configuration.
1.maven多模块启动类:
@SpringBootApplication @SpringBootApplication(scanBasePackages = {"com.xxx.xxx.service","com.xxx.xxx.api.controller"})
或 @SpringBootApplication(scanBasePackages = {"com.xxx.xxx.**"}) 2.TestService类加注解@Service
另外,暴力方法:
@Autowired
TestService testService; 改为 TestService testService = new TestService();
但是,这样就不归spring管理了 转载于:https://www.cnblogs.com/guochunyang2004/p/8710177.html
首先进入你需要打包的文件目录
打包的时候命令为:
pyinstaller -F *****.py 这里简单解释一下参数:-F 表示生成单一的exe文件;
-w 表示生成的exe文件执行时去掉背后的dos窗口(这个不建议开始时使用,会影响报错信息的显示。)
-p pyinstaller仍然不够智能,很多包的位置需要手动提供,这个参数就是提供给pyinstaller包的位置(dir1,dir2),以分号隔开;
-i 加入图标
空格后是对应的要打包的python程序。
运行结果:
111357 INFO: checking EXE 111357 INFO: Building EXE because out00-EXE.toc is non existent 111358 INFO: Building EXE from out00-EXE.toc 111359 INFO: Appending archive to EXE D:\pythonWork\baiduai\dist\****.exe 111440 INFO: Building EXE from out00-EXE.toc completed successfully. 会在你的打包文件目录下生成两个文件build和dist,你的exe文件就在dist下。
双击运行后报:
很显然没找到matplotlib.backends.backend_tkagg
于是将打包命令后面加上如下:
D:\pythonWork\baiduai>pyinstaller -F machine1.py --hidden-import matplotlib.backends.backend_tkagg 然后在运行就OK。
在解释第一个问题之前,先说明一下计算机内存管理的中的四个名词:虚拟内存,虚拟内存地址,物理内存,物理内存地址。 先说说为什么会有虚拟内存和物理内存的区别。正在运行的一个进程,他所需的内存是有可能大于内存条容量之和的,比如你的内存条是256M,你的程序却要创建一个2G的数据区,那么不是所有数据都能一起加载到内存(物理内存)中,势必有一部分数据要放到其他介质中(比如硬盘),待进程需要访问那部分数据时,在通过调度进入物理内存。所以,虚拟内存是进程运行时所有内存空间的总和,并且可能有一部分不在物理内存中,而物理内存就是我们平时所了解的内存条。有的地方呢,也叫这个虚拟内存为内存交换区。 那么,什么是虚拟内存地址和物理内存地址呢。假设你的计算机是32位,那么它的地址总线是32位的,也就是它可以寻址0~0xFFFFFFFF(4G)的地址空间,但如果你的计算机只有256M的物理内存0x~0x0FFFFFFF(256M),同时你的进程产生了一个不在这256M地址空间中的地址,那么计算机该如何处理呢?回答这个问题前,先说明计算机的内存分页机制。 计算机会对虚拟内存地址空间(32位为4G)分页产生页(page),对物理内存地址空间(假设256M)分页产生页帧(page frame),这个页和页帧的大小是一样大的,所以呢,在这里,虚拟内存页的个数势必要大于物理内存页帧的个数。在计算机上有一个页表(page table),就是映射虚拟内存页到物理内存页的,更确切的说是页号到页帧号的映射,而且是一对一的映射。但是问题来了,虚拟内存页的个数 > 物理内存页帧的个数,岂不是有些虚拟内存页的地址永远没有对应的物理内存地址空间?不是的,操作系统是这样处理的。操作系统有个页面失效(page fault)功能。操作系统找到一个最少使用的页帧,让他失效,并把它写入磁盘,随后把需要访问的页放到页帧中,并修改页表中的映射,这样就保证所有的页都有被调度的可能了。这就是处理虚拟内存地址到物理内存的步骤。 现在来回答什么是虚拟内存地址和物理内存地址。虚拟内存地址由页号(与页表中的页号关联)和偏移量组成。页号就不必解释了,上面已经说了,页号对应的映射到一个页帧。那么,说说偏移量。偏移量就是我上面说的页(或者页帧)的大小,即这个页(或者页帧)到底能存多少数据。举个例子,有一个虚拟地址它的页号是4,偏移量是20,那么他的寻址过程是这样的:首先到页表中找到页号4对应的页帧号(比如为8),如果页不在内存中,则用失效机制调入页,否则把页帧号和偏移量传给MMC(CPU的内存管理单元)组成一个物理上真正存在的地址,接着就是访问物理内存中的数据了。总结起来说,虚拟内存地址的大小是与地址总线位数相关,物理内存地址的大小跟物理内存条的容量相关。 转自:https://blog.csdn.net/fukaibo121/article/details/75105848
@charset "utf-8"; /* CSS Document */ /*手机总体*/ @media screen and (max-device-width: 1025px) { body{background:blue;} } /*pc总体*/ @media screen and (min-device-width: 1026px) { body{background:red;} } /*5*/ @media screen and (min-device-width: 300px) and (max-device-width: 373px) { } /*6*/ @media screen and (min-device-width: 374px) and (max-device-width: 412px) { } /*plus*/ @media screen and (min-device-width:413px) and (max-device-width: 767px) { } /*ipad*/ @media screen and (min-device-width:768px) and (max-device-width: 1025px) { } /*1280 1366*/ @media screen and (min-device-width: 1026px) and (max-device-width: 1367px) { } /*1920*/ @media screen and (min-device-width: 1368px) and (max-device-width: 1440px) { } /**/ @media screen and (min-device-width: 1441px) { }
快速排序: 快速排序的主要思想是: 1)选定一个基准元素 2)经过一趟排序,将所有元素分成两部分 3)分别对两部分重复上述操作,直到所有元素都已排序成功 因为单链表只能从链表头节点向后遍历,没有prev指针,因此必须选择头节点作为基准元素。这样第二步操作的时间复杂度就为O(n)。由于之后都是分别对两部分完成上述操作,因此会将链表划分为lgn个段,因此时间复杂度为O(nlgn) 从中可以看出,快排实现也是先对数据进行一遍遍历找到关键值得位置,和数组不同的是数组可以从两端向中间靠拢,但是单向链表只能从一段开始,但用两个指针同样可以实现。 需要明白的一点是节点的指针就是我们在节点中定义的next指针,不要考虑的太多
//#include <iostream> #include "stdio.h" #include "stdlib.h" //using namespace std; //构造结点并初始化 typedef struct node { int val; node * next; node(int x):val(x),next(NULL){} }mynode,*pmynode; void swap(int* a,int * b) { int tmp = *a; * a = *b; * b = tmp ; } //定位 node *partion(node *pbegin ,node * pend) { if(pbegin ==pend ||pbegin->next ==pend) return pbegin; int mykey = pbegin ->val; //选择基准 node * p =pbegin ; node* q =pbegin; while(q !
作为一个 Confluence 的管理员,你可以修改用户的用户名。对 Confluence 的管理员来说可能有很多种情况需要修改用户的用户名,比如下面的这种情况:
每一个系统中活动的用户必须有一个独一无二的用户名,因此 2 个激活的用户是不可能有相同的用户名的。但是你可以将一个 disabled user 用户的用户名指派给一个激活的用户。
如何对用户名进行修改与你如何对系统的用户进行配置有关,请查看 Configuring User Directories 页面相关的内容。
如果你使用 Confluence 内部目录来管理你的用户,你可以在 Confluence 中直接对用户名进行重命名。
你需要具有 Confluence 管理员的权限才能对用户名进行重命名。
希望修改一个用户名:
选择 > 用户管理(User management)对用户名进行查找或者选择 显示所有用户(Show all users)选择你希望进行编辑的用户,然后选择 编辑详细(Edit Details)输入新的用户名,然后选择 提交(Submit) 被修改的这个用户现在需要使用新的用户名才能登录 Confluence 了。新的用户在Confluence 中提供了反射调用的功能,包括下面的方式 @mentions。
https://www.cwiki.us/display/CONFLUENCEWIKI/Change+a+Username
背景 我们都知道浏览器有一个既核心也最基本的安全功能,即同源策略。同源分别是:协议,域名,端口。如果浏览器访问服务器不同源的话,就会访问不到数据。那开发中常常访问的服务器不同源,那么可以借助一个服务器当做中介来访问需要访问的服务器从而获得数据。因为同源策略是浏览器的安全机制,而服务器之间是不受此限制的。
之前vue-cli模板build文件夹下有dev-serve.js文件,可以在此文件中配置本地node服务器实现跨域,现在的模板下没有此文件,那我们该如何使用node跨域呢?不逼逼,上方法。
具体操作 在build文件夹下面新建一个dev-serve.js文件,其中添加代码如下:
'use strict' const express = require('express') const axios = require('axios') module.exports = function () { let app = express() app.get('/api/getDiscList', (req, res) => { let url = '请求地址' axios.get(url, { headers: { //这里请求的是QQ音乐的接口,带上下面参数是为了骗服务器是自己人 referer: 'https://c.y.qq.com/', host: 'c.y.qq.com' }, params: req.query }).then((response) => { res.json(response.data) }).catch((e) => { console.log(e) }) }) app.listen(3000) } 复制代码 在build.js中引入并且运行
只需要在最上面添加 require('./dev-serve.js')()
当我们npm run dev运行项目的时候,node服务器就会启动自动监听3000端口 3.本地发送ajax请求,就可以通过node服务器访问到数据,请求我使用的是axios。请求如下:
import axios from 'axios' function getDiscList() { const data = { //.
深度学习越来越火了,伴随着的是对python的学习和使用。其中python函数keras函数算是被经常提到的一个了,但是要使用它就要费点功夫,特别是gpu环境的搭建问题。以下是我搭建数次gpu环境 得出的总结。
keras backend我看好多使用的是theano 但是theano 麻烦而且效率不高网上好多都是指导theano为backend的安装
下面我以cntk为backend说一下(tensorflow也不错但最好不要用theano)
需要材料:visual studio(2013/2015) cuda(8.0) cudnn(6.0) python(3.6) window(8.0/10)
其对应的下载地址,及其安装
visual studio(2013/2015)https://www.visualstudio.com/zh-hans/downloads/
最好注册一个账号这样可以‘’使用你的权益‘’
然后直接搜索visual studio 2015
在安装时其中''用于c++的microsoft''选项一定要选择,这个好像是为cuda 的编译工具
cuda(8.0) https://developer.nvidia.com/cuda-80-ga2-download-archive
下载完成后选择自定义安装,不然会有一些安装包会被漏掉。
安装完成之后打开cmd 直接输入nvcc -V 如果出现cuda的版本信息说明安装成功
anaconda :https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
anaconda安装很简单我就不多重复了(别忘勾选添加环境变量的选项)
cudnn 地址:https://developer.nvidia.com/rdp/form/cudnn-download-survey
cudnn需要注册账号才能下载,记得要要下载6.0版本的
下载完成之后解压出来是三个文件包lib bin include 把他们复制到cuda安装的C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0目录下
python 的keras包安装
打开cmd 输入conda install -c anaconda mingw libpython
完成之后把D:\Anaconda3\MinGW\bin添加到环境变量path的值下文件路径是自己安装的对应路径
再安装theano
conda install theano 安装后引入可能出现版本问题只要添加环境变量就能解决
变量名为MKL_THREADING_LAYER变量值为GNU.
然后安装tensorflow,可能也会出现版本问题我安装的方法是pip install tensorflow-gpu==1.3
接着安装cntk下载2.0 gpu版本的cntk地址https://www.nuget.org/packages/CNTK.GPU/2.0.0
用本地安装的方法 pip install cntk文件路径/cntk文件全名
最后安装keras pip install keras 其中可能会遇到spyder 打不开的问题那是版本冲突把spyder卸了重装就好(更新到最新版本)
在讲 Event Loop (事件循环)之前,我们来了解点 node 的东西,来帮助我们更加明白事件循环是干什么的
Node 是什么 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,Node 不是一门语言,是让 js 运行在后端的,运行时不包括 js 全集,因为在服务端中不包含 DOM 和 BOM,Node 也提供了一些新的模块,比如 http,fs等模块。
Node 解决了什么 Node 的首要目标是提供一种简单的,用于创建高性能服务器的开发工具 Web 服务器的瓶颈在于并发的用户量,对比 Java 和 Php 的实现方式
Node在处理高并发,I/O 密集场景有明显的性能优势 高并发,是指在同一时间并发访问服务器I/O 密集指的是文件操作、网络操作、数据库,相对的有 CPU 密集,CPU 密集指的是逻辑处理运算、压缩、解压、加密、解密 Web 主要场景就是接收客户端的请求读取静态资源和渲染界面,所以 Node 非常适合 Web 应用的开发。
进程与线程 进程是操作系统分配资源和调度任务的基本单位,线程是建立在进程上的一次程序运行单位,一个进程上可以有多个线程。
浏览器线程 用户界面-包括地址栏、前进/后退按钮、书签菜单等浏览器引擎-在用户界面和呈现引擎之间传送指令(浏览器的主进程)渲染引擎,也被称为浏览器内核(浏览器渲染进程)一个插件对应一个进程(第三方插件进程)GPU提高网页浏览的体验( GPU 进程)浏览器渲染引擎 渲染引擎内部是多线程的,内部包含 ui 线程和 js 线程js 线程 ui 线程 这两个线程互斥的,目的就是为了保证不产生冲突。ui 线程会把更改的放到队列中,当 js 线程空闲下来的时候,ui 线程在继续渲染js 单线程 js 是单线程,为什么呢?如果多个线程同时操作 DOM ,哪页面不会很混乱?这里所谓的单线程指的是主线程是单线程的,所以在 Node 中主线程依旧是单线程的。webworker 多线程 它和 js 主线程不是平级的,主线程可以控制 webworker,但是 webworker不能操作 DOM,不能获取 document,window其他线程 浏览器事件触发线程(用来控制事件循环,存放 setTimeout、浏览器事件、ajax 的回调函数)定时触发器线程(setTimeout 定时器所在线程)异步 HTTP 请求线程(ajax 请求线程) 单线程特点是节约了内存,并且不需要在切换执行上下文。而且单线程不需要管锁的问题,所谓 锁,在 java 里才有锁的概念,所以我们不用细研究
前言:最近,新换了一家公司,公司的软件需要通过蓝牙与硬件进行通讯,于是趁此机会将Android蓝牙详细的了解了一下。本篇内容是基于普通蓝牙。
Android系统已经为我们提供了操作蓝牙的API,我们只要通过这些API便可以操控蓝牙,实现打开蓝牙设备,搜索周围蓝牙设备,与已连接的设备进行数据传输等操作。
阅读本文后你将会有一下收获
知道怎样打开手机蓝牙。知道怎样获取已经进行蓝牙配对过的设备。知道怎样进行设备之间的连接以及通讯。知道怎样设置蓝牙设备可进行搜索到以及设置可被搜索的时长 蓝牙操作 打开手机蓝牙 设置蓝牙权限 要在应用中使用蓝牙功能,必须声明蓝牙权限 BLUETOOTH。您需要此权限才能执行任何蓝牙通信,例如请求连接、接受连接和传输数据等。设置权限的代码如下
<uses-permission android:name="android.permission.BLUETOOTH" /> 复制代码 判断是否支持蓝牙 在打开手机蓝牙之前首先判断手机是否支持蓝牙,判断是否支持蓝牙的代码如下
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { Toast.makeText(this,"当前设备不支持蓝牙!",Toast.LENGTH_SHORT).show(); } 复制代码 解释一下BluetoothAdapter的作用
BluetoothAdapter代表本地设备蓝牙适配器**,BluetoothAdapter**可让您执行基本的蓝牙任务,如启动设备发现,查询绑定(配对)设备列表,使用已知的MAC地址实例化 BluetoothDevice,并创建 BluetoothServerSocket以侦听来自其他设备的连接请求,并开始扫描蓝牙LE设备。
如果设备支持蓝牙,则进行打开蓝牙的操作
打开蓝牙 调用 BluetoothAdapter的isEnabled() 方法来检查当前是否已启用蓝牙。 如果此方法返回 false,则表示蓝牙处于停用状态。想要启用蓝牙,则需要设置Intent的Action为ACTION_REQUEST_ENABLE ,然后通过startActivityForResult()来启动蓝牙。具体的代码如下
if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } 复制代码 这段代码执行完后,手机则会弹出是否允许开启蓝牙的提示框,如下图
当用户点击“拒绝”或则“允许”的时候 Activity 将会在 onActivityResult() 回调中收到结果代码。
当成功开启蓝牙时 Activity 将会在 onActivityResult() 回调中收到 RESULT_OK 结果代码。 如果由于某个错误(或用户响应“拒绝”)而没有启用蓝牙,则结果代码为 RESULT_CANCELED。我们便可以重写 onActivityResult()方法来判断蓝牙是否已经成功开启。
查询设备 查询已经配对的设备 在搜索设备之前,我们应该先查找已经进行配对的设备,如果目标设备已经进行过配对,则不需要进行设备搜索。因为,执行设备发现对于蓝牙适配器而言是一个非常繁重的操作过程,并且会消耗大量资源。可以通过BluetoothAdapter的getBondedDevices()方法来查询已经配对的设备,具体代码如下
1、查看cuda版本
cat /usr/local/cuda/version.txt 2、查看cudnn版本
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2 根据输出判断:eg:
#define CUDNN_MAJOR 5 #define CUDNN_MINOR 1 #define CUDNN_PATCHLEVEL 5 -- #define CUDNN_VERSION (CUDNN_MAJOR * 1000 + CUDNN_MINOR * 100 + CUDNN_PATCHLEVEL) CuDNN版本为 5.1.5
我的输出为:说明版本为6.0.21
#define CUDNN_MAJOR 6 #define CUDNN_MINOR 0 #define CUDNN_PATCHLEVEL 21 -- #define CUDNN_VERSION (CUDNN_MAJOR * 1000 + CUDNN_MINOR * 100 + CUDNN_PATCHLEVEL) #include "driver_types.h
安装
登录MySQL网站
用dmg的方式安装。Download MySQL Community Server
或者常规方式,打开官网 : http://www.mysql.com/downloads/ 进入, 点击下方的DOWNLOADS : MySQL Community Server
选择选择不登录,直接下载
接着, 会跳转到如下页面, 你只需要选择不登录,直接下载即可
记住临时密码
下载完成后,双击打开一路确定,但是当弹出一个MYSQL Installer提示框的时候一定打开备忘录复制粘贴记下弹出框的密码
2016-10-16T02:52:44.474550Z 1[Note] A temporary password is generated for root@localhost: /kL_M_zXd3rA。
或者只复制密码部分就可以了/kL_M_zXd3rA为什么不截图记下来呢?因为密码有点复杂囧不好打。
打开MySQL服务
正常情况下,安装成功。
此时只是安装成功,但还需要额外配置:
1、进入系统偏好设置
2、点击MySQL
3、开启MySQL服务
点击按钮
打开后界面上红色的部分会变成绿色的running。
配置路径
用文本编辑器打开 .bash_profile 文件
vim ~/.bash_profile 加入
PATH=$PATH:/usr/local/mysql/bin 并保存(vim 中先按 Esc键,在输入 :wq )
在命令行输入
source ~/.bash_profile 登陆 MySQL
在命令行输入
mysql -u root -p 登陆,输入之前保存的密码
输入密码时光标不会移动
修改密码
MySQl 输入
先安装虚拟机,我使用的是WMware 11.1.3 build-3206955+Centos7
其中出现一个问题是,我需要在虚拟机上安装软件,需要上网,虚拟机有几种网络连接方式:
暂时了解的是,“仅主机模式”是虚拟机和主机形成局域网,所以你可以在主机使用ssh连接虚拟机,但是这种实模式虚拟机不能上外网。“NAT模式”:虚拟机可以上外网,但是主机默认不能ssh连接虚拟机,虚拟机ip不会变。“桥接模式”:虚拟机可以上外网,但是主机默认不能ssh连接虚拟机,虚拟机ip会变化。那么上面没有一种方式可以默认又能上外网,又能ssh的,所以我找了一个解决方案,使用NAT模式,让虚拟机上外网,然后使用下面的方法来解决ssh的问题(原文http://blog.csdn.net/jiuduan2009/article/details/51737004):
上面设置后点击确定,然后查看虚拟机的ip:
然后ssh这个ip地址就好:
如果出现ip addr找不到虚拟机ip的情况(我遇到的是从wifi下切换到有线网络出现问题),移除掉其他网络,剩下一个NAT模式的网络即可:
版权声明:本文为原创文章,版权属文章作者所有,欢迎转载,请在文章底部注明原文链接,谢谢!邮箱:1035097367@qq.com https://blog.csdn.net/disalong/article/details/78411073
以上为转载。下面补充:
做完以上步骤,请确定本地主机的虚拟网卡处于启用状态,如下图
JAVA内存泄露分析和解决方案及WINDOWS自带查看工具 Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历与各位分享解决这些问题的办法.
作为Internet最流行的编程语言之一,Java现正非常流行.我们的网络应用程序就主要采用Java语言开发,大体上分为客户端、服务器和数据库三个层次.在进入测试过程中,我们发现有一个程序模块系统内存和CPU资源消耗急剧增加,持续增长到出现java.lang.OutOfMemoryError为止.经过分析Java内存泄漏是破坏系统的主要因素.这里与大家分享我们在开发过程中遇到的Java内存泄漏的检测和处理解决过程.
一. Java是如何管理内存
为了判断Java中是否有内存泄露,我们首先必须了解Java是如何管理内存的.Java的内存管理就是对象的分配和释放问题.在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的,程序员不需要通过调用函数来释放内存,但它只能回收无用并且不再被其它对象引用的那些对象所占用的空间.
Java的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收.GC为了能够正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控.监视对象状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用.
在Java中,这些无用的对象都由GC负责回收,因此程序员不需要考虑这部分的内存泄露.虽然,我们有几个函数可以访问GC,例如运行GC的函数System.gc(),但是根据Java语言规范定义,该函数不保证JVM的垃圾收集器一定会执行.因为不同的JVM实现者可能使用不同的算法管理GC.通常GC的线程的优先级别较低.JVM调用GC的策略也有很多种,有的是内存使用到达一定程度时,GC才开始工作,也有定时执行的,有的是平缓执行GC,有的是中断式执行GC.但通常来说,我们不需要关心这些.
二. 什么是Java中的内存泄露
导致内存泄漏主要的原因是,先前申请了内存空间而忘记了释放.如果程序中存在对无用对象的引用,那么这些对象就会驻留内存,消耗内存,因为无法让垃圾回收器GC验证这些对象是否不再需要.如果存在对象的引用,这个对象就被定义为"有效的活动",同时不会被释放.要确定对象所占内存将被回收,我们就要务必确认该对象不再会被使用.典型的做法就是把对象数据成员设为null或者从集合中移除该对象.但当局部变量不需要时,不需明显的设为null,因为一个方法执行完毕时,这些引用会自动被清理.
在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是有被引用的,即在有向树形图中,存在树枝通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象.如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存.
这里引用一个常看到的例子,在下面的代码中,循环申请Object对象,并将所申请的对象放入一个Vector中,如果仅仅释放对象本身,但因为Vector仍然引用该对象,所以这个对象对GC来说是不可回收的.因此,如果对象加入到Vector后,还必须从Vector中删除,最简单的方法就是将Vector对象设置为null.
实际上这些对象已经是无用的,但还被引用,GC就无能为力了(事实上GC认为它还有用),这一点是导致内存泄漏最重要的原因. 再引用另一个例子来说明Java的内存泄漏.假设有一个日志类Logger,其提供一个静态的log(String msg),任何其它类都可以调用Logger.Log(message)来将message的内容记录到系统的日志文件中.
Logger类有一个类型为HashMap的静态变量temp,每次在执行log(message)的时候,都首先将message的值写入temp中(以当前线程+当前时间为键),在退出之前再从temp中将以当前线程和当前时间为键的条目删除.注意,这里当前时间是不断变化的,所以log在退出之前执行删除条目的操作并不能删除执行之初写入的条目.这样,任何一个作为参数传给log的字符串最终由于被Logger的静态变量temp引用,而无法得到回收,这种对象保持就是我们所说的Java内存泄漏. 总的来说,内存管理中的内存泄漏产生的主要原因:保留下来却永远不再使用的对象引用.
三. 几种典型的内存泄漏
我们知道了在Java中确实会存在内存泄漏,那么就让我们看一看几种典型的泄漏,并找出他们发生的原因和解决方法.
3.1 全局集合
在大型应用程序中存在各种各样的全局数据仓库是很普遍的,比如一个JNDI-tree或者一个session table.在这些情况下,必须注意管理储存库的大小.必须有某种机制从储存库中移除不再需要的数据.
通常有很多不同的解决形式,其中最常用的是一种周期运行的清除作业.这个作业会验证仓库中的数据然后清除一切不需要的数据.另一种管理储存库的方法是使用反向链接(referrer)计数.然后集合负责统计集合中每个入口的反向链接的数目.这要求反向链接告诉集合何时会退出入口.当反向链接数目为零时,该元素就可以从集合中移除了.
3.2 缓存 缓存一种用来快速查找已经执行过的操作结果的数据结构.因此,如果一个操作执行需要比较多的资源并会多次被使用,通常做法是把常用的输入数据的操作结果进行缓存,以便在下次调用该操作时使用缓存的数据.缓存通常都是以动态方式实现的,如果缓存设置不正确而大量使用缓存的话则会出现内存溢出的后果,因此需要将所使用的内存容量与检索数据的速度加以平衡.
常用的解决途径是使用java.lang.ref.SoftReference类坚持将对象放入缓存.这个方法可以保证当虚拟机用完内存或者需要更多堆的时候,可以释放这些对象的引用.
3.3 类装载器 *****
Java类装载器的使用为内存泄漏提供了许多可乘之机.一般来说类装载器都具有复杂结构,因为类装载器不仅仅是只与"常规"对象引用有关,同时也和对象内部的引用有关.比如数据变量,方法和各种类.这意味着只要存在对数据变量,方法,各种类和对象的类装载器,那么类装载器将驻留在JVM中.既然类装载器可以同很多的类关联,同时也可以和静态数据变量关联,那么相当多的内存就可能发生泄漏.
四. 如何检测和处理内存泄漏
如何查找引起内存泄漏的原因一般有两个步骤:第一是安排有经验的编程人员对代码进行走查和分析,找出内存泄漏发生的位置;第二是使用专门的内存泄漏测试工具进行测试.
第一个步骤:在代码走查的工作中,可以安排对系统业务和开发语言工具比较熟悉的开发人员对应用的代码进行了交叉走查,尽量找出代码中存在的数据库连接声明和结果集未关闭、代码冗余等故障代码.
第二个步骤:就是检测Java的内存泄漏.在这里我们通常使用一些工具来检查Java程序的内存泄漏问题.市场上已有几种专业检查Java内存泄漏的工具,它们的基本工作原理大同小异,都是通过监测Java程序运行时,所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化.开发人员将根据这些信息判断程序是否有内存泄漏问题.这些工具包括Optimizeit Profiler,JProbe Profiler,JinSight , Rational 公司的Purify等.
4.1检测内存泄漏的存在 这里我们将简单介绍我们在使用Optimizeit检查的过程.通常在知道发生内存泄漏之后,第一步是要弄清楚泄漏了什么数据和哪个类的对象引起了泄漏.
一般说来,一个正常的系统在其运行稳定后其内存的占用量是基本稳定的,不应该是无限制的增长的.同样,对任何一个类的对象的使用个数也有一个相对稳定的上限,不应该是持续增长的.根据这样的基本假设,我们持续地观察系统运行时使用的内存的大小和各实例的个数,如果内存的大小持续地增长,则说明系统存在内存泄漏,如果特定类的实例对象个数随时间而增长(就是所谓的“增长率”),则说明这个类的实例可能存在泄漏情况.
另一方面通常发生内存泄漏的第一个迹象是:在应用程序中出现了OutOfMemoryError.在这种情况下,需要使用一些开销较低的工具来监控和查找内存泄漏.虽然OutOfMemoryError也有可能应用程序确实正在使用这么多的内存;对于这种情况则可以增加JVM可用的堆的数量,或者对应用程序进行某种更改,使它使用较少的内存.
但是,在许多情况下,OutOfMemoryError都是内存泄漏的信号.一种查明方法是不间断地监控GC的活动,确定内存使用量是否随着时间增加.如果确实如此,就可能发生了内存泄漏.
4.2处理内存泄漏的方法 一旦知道确实发生了内存泄漏,就需要更专业的工具来查明为什么会发生泄漏.JVM自己是不会告诉您的.这些专业工具从JVM获得内存系统信息的方法基本上有两种:JVMTI和字节码技术(byte code instrumentation).Java虚拟机工具接口(Java Virtual Machine Tools Interface,JVMTI)及其前身Java虚拟机监视程序接口(Java Virtual Machine Profiling Interface,JVMPI)是外部工具与JVM通信并从JVM收集信息的标准化接口.字节码技术是指使用探测器处理字节码以获得工具所需的信息的技术.
Optimizeit是Borland公司的产品,主要用于协助对软件系统进行代码优化和故障诊断,其中的Optimizeit Profiler主要用于内存泄漏的分析.Profiler的堆视图就是用来观察系统运行使用的内存大小和各个类的实例分配的个数的.
首先,Profiler会进行趋势分析,找出是哪个类的对象在泄漏.系统运行长时间后可以得到四个内存快照.对这四个内存快照进行综合分析,如果每一次快照的内存使用都比上一次有增长,可以认定系统存在内存泄漏,找出在四个快照中实例个数都保持增长的类,这些类可以初步被认定为存在泄漏.通过数据收集和初步分析,可以得出初步结论:系统是否存在内存泄漏和哪些对象存在泄漏(被泄漏).
接下来,看看有哪些其他的类与泄漏的类的对象相关联.前面已经谈到Java中的内存泄漏就是无用的对象保持,简单地说就是因为编码的错误导致了一条本来不应该存在的引用链的存在(从而导致了被引用的对象无法释放),因此内存泄漏分析的任务就是找出这条多余的引用链,并找到其形成的原因.查看对象分配到哪里是很有用的.同时只知道它们如何与其他对象相关联(即哪些对象引用了它们)是不够的,关于它们在何处创建的信息也很有用.
最后,进一步研究单个对象,看看它们是如何互相关联的.借助于Profiler工具,应用程序中的代码可以在分配时进行动态添加,以创建堆栈跟踪.也有可以对系统中所有对象分配进行动态的堆栈跟踪.这些堆栈跟踪可以在工具中进行累积和分析.对每个被泄漏的实例对象,必然存在一条从某个牵引对象出发到达该对象的引用链.处于堆栈空间的牵引对象在被从栈中弹出后就失去其牵引的能力,变为非牵引对象.因此,在长时间的运行后,被泄露的对象基本上都是被作为类的静态变量的牵引对象牵引.
总而言之, Java虽然有自动回收管理内存的功能,但内存泄漏也是不容忽视,它往往是破坏系统稳定性的重要因素.
一.eclipse中tomcat运行内存大小的设置 1.在tomcat配置内存 2.点击eclipse上的debug图标旁边的下拉箭头 3.系统弹出设置tomcat配置页面,在Argument中末尾添加参数中的VM arguments中追加: -Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m 参数的意思 -vmargs:说明后面是VM的参数 -Xms40m:虚拟机占用系统的最小内存 -Xmx256m:虚拟机占用系统的最大内存 -XX:PermSize:最小栈内存大小。一般报内存不足时,都是说这个太小,堆空间剩余小于5%就会警告,建议把这个稍微设大一点,需要要视自己机器内存大小来设置 -XX:MaxPermSize:最大栈内存大小。这个也适当大些 -Xmx512M的5%为25.6M,理论上要求-Xmx的数值与-XX:MaxPermSize必须大于25.6M 二.系统环境配置 1.环境变量添加 变量名:JAVA_OPTS 变量值:-Xms512m -Xmx512m 三.文件中配置 Windows下,在文件/bin/catalina.bat,Unix下,在文件/bin/catalina.sh的前面,增加如下设置: JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】 需要把这个两个参数值调大。例如: JAVA_OPTS='-Xms256m -Xmx512m' 表示初始化内存为256MB,可以使用的最大内存为512MB。 注意:建议把内存的最高值跟最低值的差值缩小,不然会浪费很多内存的,最低值加大 最高值可以随便设,但是要根据实际的物理内存 ,如果内存设置太大了,比如设置了512M最大内存,但如果没有512M可用内存,Tomcat就不能启动,还有可能存在内存被系统回收,终止进程的情况。 在catalina.bat的@echo off下面添加(就是第二行) set JAVA_OPTS=-server -Xms512m -Xmx1024m -XX:MaxNewSize=512m -XX:MaxPermSize=256m
一直想做个自己的音乐播放器,可是苦于找不到音乐的直链解析的方法,所以也就一直搁置。今天逛论坛时偶然找到了个网易云音乐的api,试了下,还真的能解析出来(感动)。这个把api分享下。且用且珍惜,没准哪天又被官方封了。
api格式:
更多查看原文地址http://www.tometu.com/item/view/20180303155946.html
https://blog.csdn.net/tonyshengtan/article/details/43698711
数学形式的标准Sobel为:
此模板为最早提出的Sobel模板,由于模板的对称性,我们可以将它分解一下,并根据卷积的运算性质,可以得到: 也就是说,图像对Sobel 的响应等于,对模板分解后的小模板分别卷积,而观察小模板我们可以发现,其中[1,0,-1]或其转置为差分,也就是用于寻找边缘候选点的,而另一个[1,2,1]是一个标准平滑算子,这也就是很多书上说,Sobel具有平滑和微分的功效,原因就是这里了,也就是说,算子先将图像横向或纵向平滑,然后再纵向或横向差分,得到的结果是平滑后的差分结果。 或者,也可根据以下方式得到分解到的两个模板,其中星号表示卷积: 另一种得到模板的方法是通过帕斯卡三角,得到,并且帕斯卡三角的奇数行是最有高斯模板的整数系数的逼近,也就是说,高斯模板可以通过帕斯卡三角查询到其整数系数的近似,来观察帕斯卡三角:
其中标注的就可以用来生成扩展的Sobel算子,其中较常用的有5x5和7x7的模板。
用两个小模板分别卷积的另一个好处是减少计算量,对于使用大小为nxn的模板,卷积计算量为O(n*n*width*height)而分开成小模板卷积计算量是O(2*n*width*height)也就是O(n*width*height)减少了一项,当n相对较大的时候,计算量明显减少。 帕斯卡三角的计算是通过组合公式给出,具体不在这里描述,所以Sobel算子的模板计算方法我们就有了大概的了解。 opencv文档中给出了关于sobel算子的下面信息: 和上面描述的方法类似,更直观,可以用来理解sobel的模板结构,不同的差分方向带来的问题就是边缘方向的确定,由于算子属于一阶微分,也就是梯度算子之一,所以梯度方向信息也显得很重要,比如后面要说的canny就是用到了梯度方向的信息,所以,在确定方向时要注意算子的差分方向。 对于阶梯型边缘,计算过程及结果如下,红色为模板中心: 可以看到,相比于Robert算子,Sobel得到的边界候选位置相对较宽,而且包括全部的内边界和外边界。并且差分被放大了,也就是说,用Sobel算子处理后的图片有可能超过原图像灰度级别,对于这个问题,处理方法是将平滑分算子(分解后的平滑部分,例如【1,2,1】)归一化,得到的差值仍在原始灰度级范围内。
链接
题目 求每次提问后家庭的人数。
分析 用并查集。
代码 #include <cstdio> #include <cctype> using namespace std; int f[100001],sum[100001],n,m; char k; int in(){ int ans=0; char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=ans*10+c-48,c=getchar(); return ans; } int getf(int u){return (f[u]==u)?u:f[u]=getf(f[u]);} void uni(int x,int y){ int fa=getf(x),fb=getf(y); if (fa!=fb) f[fb]=fa,sum[fa]+=sum[fb]; } int main(){ n=in(); m=in(); for (int i=1;i<=n;i++) f[i]=i,sum[i]=1; while (m--){ while (!isalpha(k)) k=getchar(); if (k=='M') uni(in(),in()); else printf("%d\n",sum[getf(in())]); k=getchar(); } return 0; }
下面只是针对于基本类型
对于标准C来说:const修饰的变量是只读变量,会分配内存空间。但是不能作为左值直接改变。可以通过指针来改变
对于现代C编译器来说:会做一些优化,会进入符号表。如果有对内存的操作出现,那么它就不会去符号表取值,而是去内存中取值。这个和C++进入符号表有些不同。
对于C++来说:const int a=1;会进入符号表,就算给它分配了空间也不会去内存空间去取值。如果加上volatile 就会成为只读变量,和C一样了。
C++中其他const只读变量的情况:
const int& a=1;//a是只读变量
int b=1;const int a =b;//a是只读变量
const int b=1;const int& a=b;//a是只读变量,而b会进入符号表。
等等情况;
我对只读变量的理解(在C++中): 不但要分配空间,还要去内存取值。不能作为左值直接改变,可以用指针和引用改变。 1,c语言
const修饰的变量是只读变量,不能作为左值,不能直接赋值,但是可以通过指针去改变该变量的值
(有的书上说会进入符号表,可能编译器的不同)
2,C++
a,const修饰的是常量,会进入符号表。但是可能会分配存储空间,只是没有去内存中取值而已,下面就是这个情况。
下面是引用的情况
b,加volatile修饰 就会成为只读变量。与上面的程序就只是一个volatile区别
下面是引用的情况
c,当使用字面量对const引用进行初始化时,C++编译器会为常量值分配空间,是只读变量
指针不能指向引用,所以没有指针的情况
d,使用其它变量初始化的const常量仍然是只读变量
引用情况
e,const引用的类型与初始化变量的类型
相同:
不同:生成一个新的只读变量,其初始值与初始化变量相同
综合例子:
int main(int argc, char *argv[])
{
const int x = 1;
const int& rx = x;//x分配了内存,只是不能再内存里去值,rx是只读变量
int& nrx = const_cast<int&>(rx);//此时rx还是只读变量
nrx = 5;
printf("x = %d\n", x);//1
printf("rx = %d\n"
最近逛博客,发现好多博主都加了网页看板娘,简直可爱到血槽空了,赶紧学习模仿改造了一下~
给博客园的博客也添加了看板娘!!就在右边~喜欢的请打赏我~
不过因为移植过来比较复杂,就不出教程啦~记得多来调教她哦~
效果展示==》
源码下载==》
官网==》
官网示例sdk下载==》
开发备注:chrome直接调试会有跨域问题,建议更换火狐或者搭建本地服务器或者在服务器端调试~
在项目中遇到一种情形,一个TextView如果可以点击-文字颜色为黑色,当点击以后就变为不可点击-文字颜色为蓝色。
然后当然是选择selector了,
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/black_333333" android:state_enabled="true" /> <item android:color="@color/blue" android:state_enabled="false" /> </selector> 注意代码中设置颜色不是用drawable!
注意! android:color 这个属性是联想不出来的(我的Studio2.2.2,联想不出来)
直接手敲出来!直接手敲出来!直接手敲出来!
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@drawable/selector_text_color" />
然后直接设置到android:textColor属性上面就可以了
后续:
发现为啥联想不出来android:color属性了,上面的Selector是直接在drawavble文件夹里面创建的,
设置item时候联想不出来android:color属性。
可以在res文件夹上面直接右键——>new——>Android resources directory;
创建color文件夹取名就叫color
然后在color文件下新建selector文件就可以直接设置android:color属性了。
【题目来源】:解二元一次方程组
【题目描述】:
给定一个二元一次方程组,形如: a * x + b * y = c; d * x + e * y = f; x,y代表未知数,a, b, c, d, e, f为参数。 求解x,y 数据规模和约定 0 < = a, b, c, d, e, f < = 2147483647 输入 输入包含六个整数: a, b, c, d, e, f; 输出 输出为方程组的解,两个整数x, y。 样例输入 3 7 41 2 1 9 样例输出 2 5 【解析】:很简单的一道数学题目,题目描述的不太清楚,不用考虑分母为0的情况
【代码】:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.
一、问题背景 手Q每个版本上线以后研发同学都会收到各种问题反馈。在跟进手Q内部用户反馈的问题时,发现多例问题,其表象和原因如下:
1、问题表象:“未读不消失”、“图片不展示”、“菊花一直在转” 。。。
2、问题原因:死锁导致的功能不可用。
这类由死锁造成的功能不可用的问题,具有表象简单但影响非常严重的特点。一般用户在遇到这类问题后,除了采取杀掉进程重启的策略,没有其他办法继续使用应用。由此可见,死锁问题对产品的影响是巨大的,那么有没有有效的方法能够监控Android应用的死锁呢?
首先想到的是使用代码规范来避免死锁的发生。手Q有250多个业务模块,400w+行代码,这么多业务代码交叉调用,仅通过代码规范,很难避免死锁发生。
然后想到的是CodeDog的代码工具扫描。与CodeDog同事沟通后,发现Converity静态扫描无法识别嵌套调用使用锁的情况,而锁的嵌套调用是死锁发生场景中一个比较常见的场景。显然通过代码的静态扫描没法解决问题。
既然现成的代码扫描工具无法完全解决问题,只能硬着头皮试着自己造轮子来监控Android线程的死锁问题。
下面将详细介绍这套Android线程卡死监控系统。(注意这里用的词是“卡死”而不是死锁。死锁只是线程卡死原因中比较重要的分类,除了死锁还有许多其他问题造成线程的卡死。)
二、方案详述 2.1整体方案概述 下面是手Q自建Android线程卡死监控的整体方案:
Android线程监控整体方案分为两部分:客户端与后台。
1、客户端:由监控线程(WatchThread)与被监控线程(Thread)组成。
客户端线程的监控的核心主要利用线程的Looper方法,监控线程监控从被监控线程消息队列取出的消息的执行。当监控线程发现一个出队列的消息在一定时间(3分钟,可以自己设定)没有执行完成,则可认定被监控的线程发生卡死。这时,由监控线程获取线程持有、等待的阻塞锁信息,将这些信息上报到后台,客户端部分便完成了使命。
2、后台:由自动化分析工具,分析线程卡死的原因。原因分析完成以后,就可以进行提单,然后再跟进每个卡死问题的解决。
整个方案的关键是上图中两个标红的部分:客户端上报线程卡死的关键信息,后台自动化分析卡死原因。下面将详细介绍这两部的实现。
2.2 客户端上报 2.2.1卡死信息 Android线程卡死监控中客户端上报线程卡死的关键信息,那么哪些信息是关键信息呢?答案很明显:线程信息与线程持有、等待锁的信息。
在如何获取这两类信息之前,先来分析一下Java中锁的分类与特点。
Java中锁的分类有自旋锁、可重入锁、阻塞锁等等分类,其中能够造成线程卡死的锁,只有阻塞锁。对于阻塞锁有如下三种:
根据这三种锁是否有线程等待方和线程持有方,为了达到分析线程卡死的目标,需要获取如下信息:
1、对于sychronized锁:需要获取其持有线程和等待线程。
2、对于LockSupport锁:需要获取其持有线程和等待线程。
3、对于Object锁:需要获取其等待线程。
那么接下来的重点就是如何获取线程的信息与锁的信息上报。
2.2.2 上报方案1:抓取java堆栈—不可行 首先想到的方案是:抓取java的堆栈进行上报。下面是抓取的java堆栈与其对应的代码:
上图中右的代码中121行已经获取了sychornized锁,但是左边的java堆栈中并没有展示对应锁的信息,故使用抓取java堆栈的方式不可行。
既然使用Java抓取堆栈信息不可行,有没有其他方案呢?答案:有。
2.2.3上报方案2:抓取系统Traces.txt——可行 既然抓取java的堆栈行不通,只能寻求其他解决方案。突然想到,Android在发生ANR时有一套系统机制:
1、Android应用发生ANR时,系统会发出SIGQUIT信号给发生ANR进程。
2、系统信号捕捉线程触发输出/data/anr/traces.txt文件,记录问题产生虚拟机、线程堆栈相关信息。
3、这个trace文件中包含了线程信息和锁的信息,借助这个trace文件可以分析卡死的原因。
由此,如果利用这个系统原有的机制,自己在线程卡死时候触发traces文件的形成进行上报,便可以把线程卡死的关键进行进行上报。本监控方案便是利用系统机制进行卡死信息的抓取:
1、当监控线程发现被监控线程卡死时,主动向系统发送SIGQUIT信号。
2、等待/data/anr/traces.txt文件生成。
3、文件生成以后进行上报。
4、当然,这里也有少数Trace文件生成失败的情况,但是,对于手Q大盘监控可忽略。
既然方案可行,就需要分析利用系统机制抓取的信息(所有线程信息、线程堆栈中锁的信息)是否满足需求。下面是一个利用系统机制继续抓取的例子: 右图代码中的synchonized锁信息已经在左边系统dump的堆栈中,由此可见,可以利用这个堆栈进行卡死分析。那是否利用这些信息就足够进行线程卡死原因的分析了呢?
天下永远没有这么便宜的晚餐。
2.2.4上报难点:Traces中没有LockSupport锁的持有者信息 通过分析上报的Traces文件与抓取锁信息对比,sychornized、object锁的信息得到解决,但是LockSupport锁的信息竟然缺少了持有线程。利用系统机制抓取的堆栈,可以获取锁的信息如下表所示: 下面是LockSupport锁无法获取持有线程信息的一个例子: 右图的代码在执行lock.lock()之后,线程已经获取了LockSupport锁,但是从左边的系统堆栈中却没有这个锁的信息。
这将是后续进行自动化分析的一个难点问题。那么有没有什么解决方案?通过深入分析手Q的代码,找到了答案。
2.2.5 解决方案:主动记录LockSupport锁的线程信息 解决问题的思路,先人工分析所有上报trace文件,需找关键特征:
1、找到发生死锁时系统dump堆栈的关键特征。
2、人工对卡死问题聚类分析,发现卡死堆栈中locksupport锁的问题全部为数据库问题。
3、再分析手Q的数据库相关代码,发现数据库事务LockSupport锁的入口统一,能够记录获取、等待获取的线程信息。
在上面的分析结论中,为了解决LockSupport没有持有线程信息这个难点,利用发现问题统一、程序代码入口统一的特点,采取下面这一招:
在系统dump的Trace文件中人工记录LockSupport锁信息。
解决方案:在数据库相关的代码中添加如下记录代码。 上述代码中,将等待获取LockSupport锁线程记录到等待列表中,获取LockSupport锁以后从等待列表中移除,并记录当前线程(记录当前线程id、name信息)为LockSupport锁的持有线程,当前线程释放LockSupport锁以后再将记录清空。
有了上述记录的LockSupport锁线程信息,只要在卡死形成的traces文件最后添加这些信息,然后再进行上报,这样就解决了没有LockSupport锁持有线程信息的问题。
在traces文件最后一行添加的具体如下图所示: 当然,为了方便后续的问题分析,在trace文件最后一行还添加了其他一些信息,如:被卡死线程的名称、系统版本号、发生时间等等。
目前,客户端已经解决了线程卡死以后上报信息不完整的问题,那么,接下来的重点就是要识别这些卡死的原因,下面章节将详细道来。
2.3 服务端识别 2.3.1识别方案:关键信息上报,自动化分析 服务端识别方案可概述为:关键信息上报,自动化分析。
pip install --upgrade keras==2.1.0 升级到指定版本 pip install keras==2.0.9安装指定版本
前几篇文章中分别介绍了
单线程化线程池(newSingleThreadExecutor)
可控最大并发数线程池(newFixedThreadPool)
可回收缓存线程池(newCachedThreadPool)
newScheduledThreadPool用于构造安排线程池,能够根据需要安排在给定延迟后运行命令或者定期地执行。
在JAVA文档的介绍
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize); 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。 参数:corePoolSize - 池中所保存的线程数,即使线程是空闲的也包括在内。 返回:新创建的安排线程池 需要注意的是,参数corePoolSize在这个方法中是没用意义的,详解见JAVA进阶----ThreadPoolExecutor机制。
具体实现:
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ThreadPoolByNewScheduledThreadPool { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " : 延迟3秒"); } }); /** * 定长线程池,支持定时及周期性任务执行 */ ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); //延迟3s后运行 scheduledThreadPool.schedule(thread, 3, TimeUnit.SECONDS); //首次执行延迟1s,每次间隔3秒 //scheduledThreadPool.scheduleAtFixedRate(thread, 1, 3, TimeUnit.
https://www.cnblogs.com/brianzhu/p/6404081.html
puppet 安装网址
一共进行了两面,二面有点心痛。
一面:上来英语自我介绍,然后问了一下项目,接着开始问C++的基础,像多态;函数重载和重写;C语言能不能重载;
栈变量,全局变量,静态变量的区别,内存中的位置;虚拟地址、逻辑地址定义和区别;然后问进程与线程的区别,三次握手四次挥手,中间问了select和epoll,没有回答出来,最后给了我一个链接,在线写两段代码,一个二叉树的前序非递归遍历,一个链表的翻转。
二面:上来问我项目(然后因为我的简历主要是机器学习的项目,就问我是不是不想做研发,或者以后只想做机器学习方向,我说不是,巴拉巴拉解释一大堆,这里表现的不好,没想到会问这种问题,然后说我不是专门写代码的之类的,我觉得我项目已经讲得很好了,唉。),后面就直接出了一个设计题,设计一个读写锁,写四个函数,要求读写互斥,写写互斥,然后中间就开始刁难我,语气很不耐烦。。。最后在解决问题的时候出现了写被饿死的情况,我一直没思路,感觉因为这个把我pass掉了。
总结:一面很基础,也很简单,重点是心态放好,二面感觉就是在刁难我,开始就显示出不太想让我过的感觉,应该还是自己表现的不够诚恳,继续努力。
转载于:https://www.cnblogs.com/YiRanYouQingFeng/p/9657857.html
labelme(标注mask数据集用的) github地址:https://github.com/wkentaro/labelme
windows python2
pip install pyqt pip install labelme python3
pip install pyqt5 pip install labelme ubuntu16.04 系统自带的python2.7环境 sudo apt-get install python-qt4 pyqt4-dev-tools sudo pip install labelme # python2 works 使用 (1)在终端中执行以下命令:
labelme (2)出现labelme的界面: (3) 点击“open”,打开需要标注的图像,选择对目标区域进行标注 假如你要标注的对象为人和狗,在画掩码过程中,一幅图像中如果有多个person、dog,命名规则为person1、person2…… dog1、dog2……。因为labelme生成的标签为一个label.png文件,这个文件只有一通道,在你标注时同一标签mask会被给予一个标签位,而mask要求不同的实例要放在不同的层中。最终训练索要得到的输入为一个w*h*n的ndarray,其中n为该图片中实例的个数
(4) 标注完成后点击,产生一个json文件 (5)进入<文件名>.json所在目录下,在终端中执行 labelme_json_to_dataset <文件名>.json 可得到一个文件夹,里面有五个文件,分别是: *.png info.yaml label.png label_names.txt label_viz.png
其中 label.png 和 info.yaml 是我们需要用到的! 标注已经完成!
label.png相当于mask 文件,可视化为:
其中每个对象上的红色数字,是我截图的时候加上去的的,表示每个对象区域在图像中的真实像素值
(6)如果需要批量转换的话,就需要自己写shell 脚本
参考: Mask RCNN训练自己的数据集 【图像语义分割】Label data的标注–Labelme(python) labelme标注的数据分析
vsftpd复制文件到远端时错误.
安装完VSFTPD,无法上传文件到FTP服务器,也无法显示FTP服务器内容
用WINSCP,链接时,报错: 复制文件到远端时错误.
在服务器端:用sestatus -b | grep ftp,查看相关配置
或则执行,getsebool -a|grep ftp查看
对其参数进行修改
setsebool -P tftp_home_dir on
setsebool allow_ftpd_full_access 1
setsebool allow_ftpd_use_cifs 1
setsebool allow_ftpd_use_nfs 1
setsebool httpd_enable_ftp_server 1
set httpd_can_connect_ftp 1
重启VSFTP服务器,就可以了
service vsftpd restart
Description:
Field userDao in com.gcy.springsecuritydemo.service.user.UserService required a bean of type 'com.gcy.springsecuritydemo.dao.user.UserDao' that could not be found.
Action:
Consider defining a bean of type 'com.gcy.springsecuritydemo.dao.user.UserDao' in your configuration.
Disconnected from the target VM, address: '127.0.0.1:61935', transport: 'socket'
Process finished with exit code 1
解决办法:启动类加注解@MapperScan
@SpringBootApplication @MapperScan("com.gcy.springsecuritydemo.dao")//mybatis扫描 public class SpringsecuritydemoApplication { public static void main(String[] args) { SpringApplication.run(SpringsecuritydemoApplication.class, args); } } 转载于:https://www.cnblogs.com/guochunyang2004/p/8667997.html
本页中的内容:
在开始之前第一步:确定管理员第2步:替换管理员密码第3步:将内部目录放置为第一位第4步:清理 如果你不能作为管理员登录 Confluence (例如,你弄丢了你的管理员密码),你可以以恢复模式启动 Confluence 来恢复你的管理员用户权限。
如果你使用的是下面的方式,那么这个指南可能并不适用你:
Confluence 被配置通过使用 Crowd 来 SSO。
这个指南只覆盖了如何从 Confluence 内部目录中重置管理员用户密码。如果你启用了 Crowd SSO,你就不能通过这个方法重置你的系统管理员密码。请参考 Integrating Crowd with Atlassian Confluence 页面的内容来获取如何启用和禁用 Crowd SSO。你正在使用 Confluence 3.4 或更早的版本。
请参考操作的版本 OSUser 或者 AtlassianUser。 如果你还在使用早期的版本的话,我们建议你尽快升级。
在开始之前 下面的步骤我们是在示例数据库上进行操作的,应该也能够在 MySQL 和 PostgreSQL 上正确配置。你可能需要针对你安装数据库的不同进行一些 SQL 的调整。
我们强烈推荐你在正式运行的数据库上进行任何 SQL 操作之前先在测试数据库上先运行和测试。
如果你知道你的管理员用户名,并且这个管理员的邮件地址是有效的,同时你的系统也正确配置了邮件服务器的话。你可以使用界面的重置用户密码链接进行对你管理员账号的密码进行重置。
系统将会向你的管理员账号下发送一个重置密码的链接。
获得数据库的访问权限 如果你使用默认安装嵌入的 H2 数据库,你可以在 <confluence-home-directory>/database 中找到你的额数据库文件。查看 通过重置密码来获得管理员权限 来获得更多的信息。
如果你使用的是外部生产数据库,你可以使用你常用的工具连接这些外部数据库。你需要具有这些数据库的查询和更新权限。
第一步:确定管理员 希望找到那些用户具有管理员权限,你需要连接你的数据库。你可以使用一些数据库工具例如 DBVisualiser。
如果你的系统还没有安装这些工具,你需要首先进行下载和安装,然后在数据库管理工具中运行下面的 SQL 来获得你的管理员用户名和 ID。
select u.id, u.user_name, u.active from cwd_user u join cwd_membership m on u.
2的幂表(n=1-200)2幂表
2^n (n=1~500)
2^0=1
2^1=2
2^2=4
2^3=8
2^4=16
2^5=32
2^6=64
2^7=128
2^8=256
2^9=512
2^10=1024
2^11=2048
2^12=4096
2^13=8192
2^14=16384
2^15=32768
2^16=65536
2^17=131072
2^18=262144
2^19=524288
2^20=1048576
2^21=2097152
2^22=4194304
2^23=8388608
2^24=16777216
2^25=33554432
2^26=67108864
2^27=134217728
2^28=268435456
2^29=536870912
2^30=1073741824
2^31=2147483648
2^32=4294967296
2^33=8589934592
2^34=17179869184
2^35=34359738368
2^36=68719476736
2^37=137438953472
2^38=274877906944
2^39=549755813888
2^40=1099511627776
2^41=2199023255552
2^42=4398046511104
2^43=8796093022208
2^44=17592186044416
2^45=35184372088832
2^46=70368744177664
2^47=140737488355328
2^48=281474976710656
2^49=562949953421312
2^50=1125899906842624
2^51=2251799813685248
2^52=4503599627370496
2^53=9007199254740992
2^54=18014398509481984
2^55=36028797018963968
2^56=72057594037927936
2^57=144115188075855872
2^58=288230376151711744
2^59=576460752303423488
2^60=1152921504606846976
2^61=2305843009213693952
2^62=4611686018427387904
2^63=9223372036854775808
2^64=18446744073709551616
2^65=36893488147419103232
类型1:
classA.h
#include <QObject>
class classA : public QObject
{
Q_OBJECT
public:
static classA* instance(){static classA m_classA; return &m_classA;}
~classA();
private:
explicit classA();//explicit classA(QObject *parent = 0);
}
类型2:
classA.h
#include <QObject>
class classA : public QObject
{
Q_OBJECT
public:
static classA* instance();
~classA();
private:
explicit classA();//explicit classA(QObject *parent = 0);
private:
static classA *m_classA;
}
classA.cpp
classA* classA::m_classA = new classA;
classA classA* instance()
{
return m_classA;
};
欢迎去我的博客观看: https://github.com/mly-zju/blog/issues/9 koa.js是最流行的node.js后端框架之一,有很多网站都使用koa进行开发,同时社区也涌现出了一大批基于koa封装的企业级框架。然而,在这些亮眼的成绩背后,作为核心引擎的koa代码库本身,却非常的精简,不得不让人惊叹于其巧妙的设计。
在平时的工作开发中,笔者是koa的重度用户,因此对其背后的原理自然也是非常感兴趣,因此在闲暇之余进行了研究。不过本篇文章,并不是源码分析,而是从相反的角度,向大家展示如何从头开发实现一个koa框架,在这个过程中,koa中最重要的几个概念和原理都会得到展现。相信大家在看完本文之后,会对koa有一个更深入的理解,同时在阅读本文之后再去阅读koa源码,思路也将非常的顺畅。
首先放出笔者实现的这个koa框架代码库地址:simpleKoa
需要说明的是,本文实现的koa是koa 2版本,也就是基于async/await的,因此需要node版本在7.6以上。如果读者的node版本较低,建议升级,或者安装babel-cli,利用其中的babel-node来运行例子。
四条主线 笔者认为,理解koa,主要需要搞懂四条主线,其实也是实现koa的四个步骤,分别是
封装node http Server构造resquest, response, context对象中间件机制错误处理 下面就一一进行分析。
主线一:封装node http Server: 从hello world说起 首先,不考虑框架,如果使用原生http模块来实现一个返回hello world的后端app,代码如下:
let http = require('http'); let server = http.createServer((req, res) => { res.writeHead(200); res.end('hello world'); }); server.listen(3000, () => { console.log('listenning on 3000'); }); 实现koa的第一步,就是对这个原生的过程进行封装,为此,我们首先创建application.js实现一个Application对象:
// application.js let http = require('http'); class Application { /** * 构造函数 */ constructor() { this.callbackFunc; } /** * 开启http server并传入callback */ listen(...args) { let server = http.
一、安装acme.sh
curl https://get.acme.sh | sh 二、检查是否安装好
#直接运行 acme.sh #如报错请运行如下 source ~/.bashrc 三、2种验证方式
1、DNS方式:获取阿里云的ID和Secret
https://ak-console.aliyun.com/#/accesskey
# 替换成从阿里云后台获取的密钥 export Ali_Key="ID" export Ali_Secret="Secret" # 换成自己的域名 acme.sh --issue --dns dns_ali -d baidu.com -d *.baidu.com 等待120秒
四、安装证书
#请把域名换成自己的域名 acme.sh --installcert -d baidu.com -d *.baidu.com \ --keypath /home/ssl/baidu.com/baidu.com.key \ --fullchainpath /home/ssl/baidu.com/fullchain.cer \ --reloadcmd "sudo service nginx force-reload" 五、配置nginx
server { listen 80; listen 443 ssl; server_name www.baidu.com; ssl on; ssl_certificate /home/ssl/baidu.com/fullchain.cer; ssl_certificate_key /home/ssl/baidu.com/baidu.com.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.
一 前言 死锁其实是一个很有意思也很有挑战的技术问题,大概每个DBA和部分开发朋友都会在工作过程中遇见。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助。 二 案例分析 2.1 业务场景 业务上的主要逻辑: 首先执行插入数据,如果插入成功,则提交。如果插入的时候报唯一键冲突,则执行更新。 如果同时出现三个并发在执行数据初始化动作,sess1 插入成功,sess2 和 sess3插入遇到唯一键冲突,插入失败,则都执行执行更新,于是出现死锁。 2.2 环境准备 MySQL 5.6.24 事务隔离级别为RR create table ty ( id int not null primary key auto_increment , c1 int not null default 0, c2 int not null default 0, c3 int not null default 0, unique key uc1(c1), unique key uc2(c2) ) engine=innodb ; insert into ty(c1,c2,c3) values(1,3,4),(6,6,10),(9,9,14); 2.3 测试用例 为了方便分析死锁日志,三个会话插入的c3的值分别为1 2 3 ,生产上其实是相同的值。 sess1 sess2 sess3 begin; begin; begin; T1 insert into ty (c1,c2,c3) values(4,4,4); T2 insert into ty (c1,c2,c3) values(4,4,4); T3 insert into ty (c1,c2,c3) values(4,4,4); T4 commit T5 update ty set c3=5 where c1=4; T6 update ty set c3=5 where c1=4; ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction 2.