解决AndroidStudio创建模拟器时Unknown Error问题
AndroidStudio在创建模拟器时,遇到了一个问题,具体错误见下图:
Recommendation处总是提示Unknown Error,没有对应的模拟器生成。原因是以前用eclipse开发安卓时,创建的AVD和AndroidStudio的AVD冲突导致的问题,于是把原来的删除。所在的路径为:C:\Users\用户名\.android这个目录下,删除即可。
删后处理效果:
缘由 按照往常的方法一样安装Cocoapods,在安装的过程中遇到了一切问题,按照传统的命令sudo gem install cocoapods出现了如下的错误:
ERROR: While executing gem ... (Errno::EPERM) Operation not permitted - /usr/bin/pod 然后再stackoverflow上找到了如下的解决办法:
安装: sudo gem install -n /usr/local/bin cocoapods -v 1.0.1 卸载 sudo gem uninstall -n /usr/local/bin cocoapods -v 1.0.1 -v可以跟版本号,来按照您想安装的版本。 这就这样Cocopods安装成功了,当然如果您没有翻墙的话安装Cocoapods需要切换ruby源到https://gems.ruby-china.org,具体按照可以参考我的这篇文章《CocoaPods安装和使用教程》。 当我以为一切就绪的时候,我pod search RxSwift却提示我如下的错误:
[!] Unable to find a pod with name, author, summary, or descriptionmatching '······' 对于有些类库确实是在Cocoapods中所不存在的,为了确定我们搜索的库是不是真的在Cocoapods的Repos中存在,我们可以到https://cocoapods.org/中进行搜索。
解决办法 在记录一下自己的解决办法,同时分享一下自己的经验,希望能够帮助到大家。
执行pod setup 在终端输入pod setup,会出现Setting up CocoaPods master repo,等几分钟,会输入Setup completed,说明pod setup执行成功。结果pod search还是失败在终端输入pod search RxSwift依然还是提示Unable to find a pod with name, author, summary, or descriptionmatching 'RxSwift'。但是我输入pod search pop,却有相应的结果。 删除~/Library/Caches/CocoaPods目录下的search_index.
前言 : 战斗里面需要做到兵种,展现攻击动作,发射子弹,子弹爆炸,显示伤害,然后报告本次攻击已经完成。
解决方法有: 1, 用callBack回调,每步回调callback回来,即发射子弹->回调显示伤害->回调战斗完成。太繁琐了 2, 用lua协程,将异步以同步的方法写出来。清晰明了
核心代码如下 : local function attack() local arr = { cc.DelayTime:create(0.25), cc.CallFunc:create(function() coroutine.resume(self.coroutine) end), } self.sprite3D:runAction(cc.Sequence:create(arr)) return coroutine.yield() end local function bullet() for i = 1, #targets do local target = targets[i] local arr = { cc.DelayTime:create(0.25), cc.CallFunc:create(function() coroutine.resume(self.coroutine) end), } self.sprite3D:runAction(cc.Sequence:create(arr)) coroutine.yield() end end local function reportFnish() print("end") end self.coroutine = coroutine.create(function () attack() bullet() reportFinish() end) coroutine.resume(self.coroutine) 理解:在战斗内其他地方的运用: 1,解析完战报,create()一个协程,用for循环遍历战报,用yied()逐步分配战报到各个战斗对象。(主协程) 2,分配到战斗对象的时候,在create()一个协程到攻击动作,发射子弹,子弹爆炸,显示伤害。(子协程) 3,等到战斗对象攻击完成(子线程跑完了),即可通知主线程,resume()到下一个yied里面了。 4,最终变现出来的战斗逻辑清晰,代码结构有层次感,战斗节奏可控。
再makefile中一般默认的 lib 的加载路径是/lib /usr/lib 如果想要改变程序运行时的libs的加载路径 就需要用到 -wl , rpath 参数来添加lib 加载路径。
O0 O1 表示在不影响编译速率的前提下尽可能的优化程序的大小和运行速率。
O2 表示在牺牲部分编译速率的前提下 支持配置优化参数的优化 尽可能的提高运行速率。
O3 表示 采取多项量算法 提高程序的运行速率(他不惜增大程序的大小)
Os 和O3一样只不过他不会为了以为的提高程序运行速率二曾大程序的大小。
Kafka
Kafka是知名社交网络公司LinkedIn于2010年12月份开源的分布式消息系统,主要由Scala语言开发,于2012年成为Apache顶级项目,目前被广泛应用在包括Twitter,Netffix和Tumblr等在内的大型互联网站点上。
Kafka主要用于实现低延迟的发送和收集大量的事件和日志数据——这些数据通常都是活跃的数据通常都是活跃的数据。所谓活跃数据,在互联网大型的Web网站应用中非常常见,通常是指网站的PV数和用户访问记录等。这些数据通常以日志的形式记录下来,然后有一个专门的系统来进行日志的收集与统计。
Kafka是一个吞吐量极高的分布式消息系统,其整体设计是典型的发布与订阅模式系统。在Kafka集群中,没有“中心主节点”的概念,集群中所有的服务器都是对等的,因此。可以在不做任何配置更改与删除,同样,消息的生产者和消费者也能够做到随意重启和机器的上下线。Kafka服务器及消息生产者和消费者之间的部署关系如下图所示:
Broker注册 Broker:几Kafka的服务器,用于存储消息,在消息中间件中通常被称为Broker。
Offset:消息存储在Kafka的Broker上,消费者拉取消息数据的过程中需要知道消息在文件中的偏移量,这个便宜量就是所谓的Offset。
Kafka是一个分布式消息系统,这也体现在起Broker,Producer和Consumer的分布式部署上。虽然Broker是分布式部署并且相互之间是独立运行的,但还是需要有一个注册系统能够将整个集群中的Broker服务器都管理起来。在Kafka的设计中,选择了ZooKeeper来进行所有Broker的管理。
在ZooKeeper上会有一个专门用来进行Broker服务器列表记录的节点,下文中我们称为ieee“Broker”节点,起节点路径为/brokers/ids。
每个Broker服务器在启动时,都会到ZooKeeper上进行注册,即到Broker节点下创建属于自己的节点,其节点路径为/broker/ids[0...N]
从上面的节点路径中,我们可以看到,在Kafka中,我们使用一个全局唯一的数字来指代每一个Broker服务器,可以称其为“BrokerID”,不同的Broker必须使用不同的BrokerID进行注册,例如/broker/ids/1和/broker/ids/2分别代表了两个Broker服务器。创建完Broker节点后,每个Broker就会将自己的IP地址和端口等信息写入到该节点中。
请注意,Broker创建的节点是一个临时节点,也就是说,一旦这个Broker服务器宕机或是下线后,那么对应的Broker节点也就被删除了。因此我们可以通过ZooKeeper上Broker界定啊的变化情况来动态表征Broker服务器的可用性。
Topic注册
在Kafka中,会将同一个Topic的消息分成多个分区并将其分分布到多个Broker上,而这些分区信息以及驭Broker的对应关系也都是由ZooKeeper维护的,由专门的节点来记录,其节点路径为/brokers/topics。下文中我们将这个节点称为“Topic”u节点。Kafka中的每一个Topic,都会以/brokers/topecs/[topic]的形式记录在这个节点下,例如/brokers/topics/login和/brokers/topics/search等。
Broker服务器在启动后,会到对应的Topic节点下注册自己的BrokerID,并写入针对Topic的分区总数。例如,/brokers/topics/login/->2这个节点表明BrokerID为3的一个Broker服务器,对于“login”这个Topic的消息,提供了2个分区进行消息存储。同样,这个分区数节点也是一个临时节点。
消费分区与消费者关系 对于每个消费者分组,Kafka都会为其分配一个全局唯一的GroupID,同一个消费者分组内部的所有消费者都共享该ID。同时Kafka也会为每个消费者分配一个ConsumerID,通常采用“Hostname:UUID”的形式来表示。在Kafka的设计中,规定了每个消息分区有且只能同时有一个消费者进行消息的消费,因此,需要在ZooKeeper上记录下消费分区驭消费者之间的对应的关系。每个消费者一旦确定了对一个消息分区的消费权利,那么需要将其ConsumerID写入到对应消息分区的临时节点上,例如/consumers/[group_id]/owners/[topic]/[broker_id-partition_id],其中“[broker_id-partition_id]”就是一个消息分区的标识,节点内容局势消费分区上消息的消费者的ConsumerID。
消费消息进度Offset记录 在消费者对指定消息分区进行消息消费的过程中,需要定时地将分区消息的消费进度,即Offset记录到ZooKeeper节点上,以便在该消费者进行重启或者其他消费者重新接管该消息分区的消息消费后,能够从之前的进度开始继续进行消息的消费。Offset在ZooKeeper上的记录由一个专门的节点负责,起节点路径为/consumer/[group_id]/offsets/[topic]/[broker_id-partition_id],起节点内容就是Offset值。
消费者注册 下面我们来看看消费者服务器在初始化启动时加入消费者分组的过程。
1.注册到消费者分组。
每个消费者服务器在启动的时候,都会到ZooKeeper的指定节点下创建一个属于自己的消费者节点,例如/consumers/[group_id]/ids/[consumer_id].
完成节点创建后,消费者会将自己订阅的Topic信息写入该节点。注意,该节点也是一个临时节点,也就是说,一旦消费者服务器出现故障或是下线后,其对应的消费者节点就会被删除。
2.对消费者分组中消费者的变化注册监听。
每个消费者都需要关注所属消费者分组中消费者服务器的变化情况,即对/consumers/[group_id]/ids节点注册子节点变化的Watcher监听。一旦发现消费者新增或减少,就会触发消费者的负载均衡。
3.对Broker服务器的变化注册监听。
消费者需要对/brokers/ids/[0...N]中的节点进行监听的注册,如果发现Broker服务器列表发生变化,那么就根据具体情况来决定是否需要进行消费者的负载均衡。
4.进行消费者负载均衡。
所谓消费者负载均衡,是指为了能够让同一个Topic下不同分区的消息尽量均衡地被多个消费者消费者消费而进行的一个消费者于消费分区分配的过程。通常,对于一个消费者分组,如果组内的消费者服务器发上变更或Broker服务器发生变更,会触发消费者负载均衡。
小结 Kafka从设计之初就是一个大规模的分布式i消息中间件,其服务端存在多个Broker,同时为了达到负载均衡,将每个Topic消息分成了多个分区,并分布在不同的Broker上,对各生产者和消费者能够同时发送和接收消息。Kafka使用ZooKeeper作为分布式协调框架,很好滴将消息生产,消息存储和消息消费的过程有机地结合起来。同时借助ZooKeeper,Kafka能够在保持包括生产者,消费者和Broker在内的所有组件无状态的情况下,建立起生产者和和消费者之间的订阅关系,并实现了生产者和消费者的负载均衡。
通过Python PyImport_ImportModule() 或者 PyImport_Import()导入自定义模块时,
原因一:检查路径是否正确,该路径下是否有该文件;原因二:该自定义文件中起始位置import第三方的库有没有安装,如requests;
这两天搞邮件服务器,头大了,不过还是被我搞出来了,初接触,完全靠自己摸索,现在把经验整理一次,供其他同学学习,多多交流。
1、apache服务器里面使用 win10下面WAMP集成环境: Apache/2.4.18 (Win64) PHP/5.6.19 Server at localhost Port 80 php mail()函数在windows不能用,需要安装sendmail ; 1.从http://download.csdn.net/detail/zhezhebie/9761174下载sendmail.zip 2.解压到wamp任意目录下,例如D:\wamp64\sendmail,最好短路径,长路径名有可能产生问题。 以供php和apache调用。 3.配置sendmail.ini,配置文件就在刚刚解压的那个目录里面,我的目录如下:
D:\wamp64\sendmail\sendmail.ini 需要修改的地方:
smtp_server=smtp.exmail.qq.com //这里写发送邮件的邮件服务器 smtp_port=25 //发送邮件服务器端口,默认25,一般不需要修改 error_logfile=error.log debug_logfile=debug.log 这两个是错误调式,一开始建议打开; auth_username=SHUIPING_YANG@laoda.com //邮箱名称 auth_password=kuaikuaichengzhang //邮箱密码 force_sender=SHUIPING_YANG@laoda.com 到这里,sendmail.ini就配置好了
4.配置D:\wamp64\bin\php\php5.6.19\phpForApache.ini
[mail function] ; For Win32 only. SMTP = smtp.exmail.qq.com smtp_port = 25 ; For Win32 only. sendmail_from = SHUIPING_YANG@laoda.com ; For Unix only. You may supply arguments as well (default: “sendmail -t -i”). sendmail_path = “D:\wamp64\sendmail\sendmail.
昨天在JSON.stringify()转数组的时候,发现一直报错,最终确定原因为string中的空格在html显示的时候,会自动加上 知道了问题所在,下面讲解如何解决问题。我们在取数据时,用HTMLDecode2()方法过滤下特殊字符即可
function HTMLDecode2(str) { if (str.length === 0) return ""; var result = "" + str; result = result.replace(">", ">"); result = result.replace("<", "<"); result = result.replace(" ", " "); result = result.replace(""", "\""); result = result.replace("'", "\'"); //对斜线的转义 result = result.replace("\\\\", "\\"); //注意php中替换的时候只能用双引号"\n" result = result.replace("\\n", "\n"); result = result.replace("\\r", "\r"); return result; }
zk是一个可以与java语言进行交互的web应用型框架,使用zk框架,一定程度上免去写javascript代码,而且能够很好的完成界面的交互。 类似于Android应用,它的前端布局也是一系列的控件,并且可以绑定一些事件。
1.eclipse下搭建zk环境 在 help–>install new software中加载插件 链接地址:http://studio.zkoss.org/resource/plugins/eclipse_4_2 见图1. 下载完插件后,重启eclipse就可以创建zk工程了。也可以创建zk页面(后缀名为*.zul)
2.学习简单的zk界面 2.1 创建工程 以下创建的是maven-web工程,然后web端显示的是*.zul页面。 pom.xml文件中要引入zk的jar包(比较多杂,所以直接贴整个文件)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.potix</groupId> <artifactId>zkdemo-Load_On_Demand___Grid</artifactId> <version>8.0</version> <packaging>war</packaging> <properties> <zk.version>8.0.3.1-Eval</zk.version> <zkcharts.version>2.1.1-Eval</zkcharts.version> <maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format> </properties> <repositories> <repository> <id>zk repository</id> <url>http://mavensync.zkoss.org/maven2</url> </repository> <repository> <id>ZK Evaluation</id> <url>http://mavensync.zkoss.org/eval</url> </repository> <repository> <id>com.asual.maven.public</id> <name>Asual Public Repository</name> <url>http://www.asual.com/maven/content/groups/public</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.6</version> </dependency> <!-- CE requirements --> <dependency> <groupId>org.zkoss.zk</groupId> <artifactId>zk</artifactId> <version>${zk.version}</version> </dependency> <dependency> <groupId>org.zkoss.zk</groupId> <artifactId>zhtml</artifactId> <version>${zk.version}</version> </dependency> <dependency> <groupId>org.
gradle 打包可执行jar 参考:
http://www.coderli.com/packag...
http://www.cnblogs.com/yjmyzz...
spring官方文档
方法一:不借助manifest文件 java -classpath jar1:jar2:jar3... mainClassName
解解一下:
红色的是固定部分,中间蓝色的是jar包的路径(多个jar之间用:号连接),最后绿色的部分是main方法所在的类名,按这个思路
把这二个jar包扔同一个目录下,输入如下命令:
java -classpath my-jar.jar:my-lib.jar yjmyzz.runnable.jar.DemoApp
程序就能跑起来了
方法二:借助manifest文件 想办法在my-jar.jar中添加MANIFEST.MF文件,内容参考下面这样:
Main-Class: yjmyzz.runnable.jar.DemoApp
Class-Path: my-lib.jar
同样,将这两个jar包放在一起,然后
java -jar my-jar.jar 就能运行了,至于如何在打包里,自动添加MANIFEST.MF文件,gradle下可以这么做:
jar { manifest { attributes 'Main-Class': 'yjmyzz.runnable.jar.DemoApp' attributes 'Class-Path': 'my-lib.jar' } } maven项目参考http://www.cnblogs.com/yjmyzz...
方法三:借助spring-boot 插件 前面两种方法,主程序的jar包,与依赖的jar包是分开的,这在云环境中,上传部署比较麻烦,得传多个文件(或者上传前,先压缩成一个包,再传到服务器上解压),服务器节点多时,操作起来太累。又到我大Spring出场了,将my-jar项目中的build.gradle改成下面这样:
apply plugin: 'java' apply plugin: 'spring-boot' buildscript { repositories { maven { url 'http://maven.oschina.net/content/groups/public/' } } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.0.RELEASE") } } repositories { maven { url 'http://maven.
朋友们有时侯会碰到在复制一个游戏盘时复制了一部分文件时出现错误,又得重新来过,非常费时。这里介绍一个Linux下有效的方法可以节省复制时间,即类似"断点续传的功能",只复制剩余的部分。
方法: cp -au
其中 -a 等价于 -dpR 即递归复制。
-u /--update 表示只复制源文件比目的文件更新的部分,或复制目的文件不存在时也进行复制。
源文件,目的文件
例如:复制 /file1 目录树到 /file2目录去
cp -a /file1 /file2
如果复制了一半发生错误,则再次输入
cp -au /file1 /file2
即可断点续传。
原文连接 http://www.linuxidc.com/Linux/2008-08/14759.htm
1.前言
本文由xygy8860原创,首发地址:http://blog.csdn.net/xygy8860/article/details/55101326,转载请注明。
在工作工程中,自己掌握的Android开发知识已经感觉到了瓶颈,Android初级知识没问题,写业务逻辑也没问题。但是作为一个Android开发工程师,并不能仅仅满足于现状,看到自身缺陷和瓶颈之后,需要对自身进行努力提高,以提升自身技能。
对于Android开发而言,自定义控件一直是Android开发进阶的一大方向,更何况,如今的APP已经不是简单的功能实现,用户对于APP的体验已经从功能实现转为用户体验,画面是否精美,转场动画是否别出心裁,UI是否美观大方?等等这些内容是必须考虑的。现如今同类APP越来越多,公司为了赢得客户,提高留存率,必然在体验和UI上下功夫。如果这时设计师设计出精美的UI,开发工程师说:I can't !,那么估计老板会说go out 了!
基于以上,开始了自定义View的学习。同时在学习过程中,记录下来,如果你也对自定义View有兴趣,我们也可以一同成长!
2.圆形百分比进度条UI分析
2.1为何会选择圆形百分比进度条?
现在下载进度条等已经高度自定义,传统的progressbar已经样式落后。在使用360手机助手等的过程中,圆形百分比进度条已经普遍而且非常精美,是常规下载组件的一部分。因此,圆形百分比进度条作为第一个学习对象。同时,在学习个过程中,完善一个自定义view的框架,可以很方便的集成各种自定义View。
在本文的学习过程中,学习参考了这篇文章http://blog.csdn.net/wingichoy/article/details/50334595,对于博主后面的自定义View文章,也准备系统的跟着学习下。在此感谢博主的文章,指出了自定义View学习的道路。
2.2 废话不说,上效果
录制的gif有点卡顿,不过在真机上还是很流畅的。
2.3 自定义view知识储备
我们都知道,在自定义view的时候一般都要重写三个方法:onMeasure(),onLayout()和onDraw()。
onDraw()必须有,用来绘制View图像 如果要改变View大小,需要重写onMeasure() 如果要改变View在父控件中的位置,需要重写onLayout() view还有其他的方法,也一并了解下,对于自定义view有时候非常有用。 >> onFinishInflate(): 这是一个回调方法,当应用从XML布局文件加载该组件并利用它来构建界面之后,该方法将会被回调。 >> onMeasure(int,int):调用该方法来检测View组件及它所包含的所有子组件的大小。 >> onLayout(boolean,int,int,int,int):当该组件需要分配其自组件的位置、大小时,该方法就会被回调。 >> onSizeChanged(int,int,int,int):当该组件的大小被改变时回调该方法。 >> onDraw(Canvas):当该组件需要绘制它的内容时回调该方法进行绘制。 >> onKeyDown(int,KeyEvent):当某个键被按下时触发该方法。 >> onKeyUp(int,KeyEvent):当松开某个按键时触发该方法。 >> onTrackballEvent(MotionEvent):当发生轨迹球事件时触发该方法 >> onTouchEvent(MotionEvent):当发生触摸屏事件时触发该方法 >> onWindowFocusChanged(boolean):当该组件得到、失去焦点时触发该方法。 >> onAttachedToWindow():当把组件放入某个窗口时触发该方法 >> onDetachedFrowWindow():当把组件从某个窗口上分离时触发该方法。 >> onWindowVisibilityChanged(int):当包含该组件的窗口的可见性发生改变时触发该方法。 2.4 UI分析
在看到上面这个UI的时候,首先我们需要分析下UI的组成部分。任何高级UI都是有初级UI元素组成的,把一个高级UI拆解成一个个初级UI的组成部分,那么也就离我们实现它不远了。
从上面的gif图上我们可以看到,自定义圆形百分比进度条,含有三个元素:(1)一个大圆;(2)一个弧形色带;(3):百分比进度的文字。从上面的拆解我们可以发现,大圆好实现,文字也好实现,但是弧形色带怎么实现呢?
其实,经过分析我们也可以再次分解,将色带分解为:(1)一个圆弧;(2)一个中心小圆。这样实现是不是更加容易了呢?
最终,我们将UI拆解为四个部分:
(1)外层大圆; (2)中间圆弧; (3)内层小圆; (4)中心文字。 其图层显示如下(图片来源于参考博客,感谢博主): 3.圆形百分比进度条代码编写
3.1 继承View并实现构造函数
自定义view的第一步,必然是继承View或viewgroup,由于我们此文主要实现是控件,而不需要布局,同时我们是完全自绘控件,所以只需要继承View即可,同时实现构造函数。首先我们定义一个CircleProgressBar的自定义类,并实现构造函数。代码如下: // 将前面二个构造函数都指向第三个 public CircleProgressBar(Context context) { this(context, null); } // XML中使用此构造函数 public CircleProgressBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // 默认值,色带宽度,文字大小等 mStripeWidth = PxUtils.
PHP5.5一个比较好的新功能是加入了对迭代生成器和协程的支持。对于生成器,PHP的文档和各种其他的博客文章已经有了非常详细的讲解。协程相对受到的关注就少了,因为协程虽然有很强大的功能但相对比较复杂, 也比较难被理解,解释起来也比较困难。 这篇文章将尝试通过介绍如何使用协程来实施任务调度, 来解释在PHP中的协程。
迭代生成器 生成器也是一个函数,不同的是这个函数的返回值是依次输出,而不是只返回一个单独的值。或者,换句话说,生成器使你更方便的实现了迭代器接口。下面通过实现一个xrange函数来简单说明:
<?php function xrange($start, $end, $step = 1) { for ($i = $start; $i <= $end; $i += $step) { yield $i; } } foreach (xrange(1, 1000000) as $num) { echo $num, "\n"; } 上面这个xrange()函数提供了和PHP的内建函数range()一样的功能。但是不同的是range()函数返回的是一个包含属组值从1到100万的数组(注:请查看手册)。而xrange()函数返回的是依次输出这些值的一个迭代器,而且并不会真正以数组形式返回. 这种方法的优点是显而易见的。它可以让你在处理大数据集合的时候不用一次性的加载到内存中。甚至你可以处理无限大的数据流。当然,也可以不同通过生成器来实现这个功能,而是可以通过继承Iterator接口实现。但通过使用生成器实现起来会更方便,不用再去实现iterator接口中的5个方法了。生成器为可中断的函数 要从生成器认识协程,理解它们内部是如何工作是非常重要的: 生成器是一种可中断的函数,在它里面,yield构成了中断点。 紧接着上面的例子,如果你调用xrange(1,1000000)的话,xrange()函数里代码其实并没有真正地运行。相反,PHP只是返回了一个实现了迭代器接口的生成器类实例:
<?php $range = xrange(1, 1000000); var_dump($range); // object(Generator)#1 var_dump($range instanceof Iterator); // bool(true) 你对对象调用迭代器方法一次,其中的代码运行一次。例如,如果你调用$range->rewind(), 那么xrange()里的代码就会运行到控制流第一次出现yield的地方。而函数内传递给yield语句的返回值可以通过$range->current()获取。 为了继续执行生成器中的代码,你必须调用$range->next()方法。这将再次启动生成器,直到下一次yield语句出现。因此,连续调用next()和current()方法 你将能从生成器里获得所有的值,直到再没有yield语句出现。对xrange()来说,这种情形出现在$i超过$end时。在这中情况下, 控制流将到达函数的终点,因此将不执行任何代码。一旦这种情况发生,vaild()方法将返回假,这时迭代结束。 协程 协程给上面功能添加的主要功能就是回送数据给生成器的能力(调用者发送数据给被调用的生成器函数)。这就把生成器到调用者的单向通信转变为两者之间的双向通信。 你可以调用生成器的send()方法传递数据给协程。下面的logger()协程是这种通信如何运行的例子:
<?php function logger($fileName) { $fileHandle = fopen($fileName, 'a'); while (true) { fwrite($fileHandle, yield .
SDUT 1867 最短路径问题 Time Limit: 1000MS Memory Limit: 65536KB
Problem Description
平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是找出从一点到另一点之间的最短距离。
Input
第1行为整数n。 第2行到第n+1行(共n行),每行两个整数x和y,描述了一个点的坐标(以一个空格分隔)。 第n+2行为一个整数m,表示图中连线的个数。 此后的m行,每行描述一条连线,由两个整数i和j组成,表示第1个点和第j个点之间有连线。 最后一行:两个整数s和t,分别表示源点和目标点。
Output
仅1行,一个实数(保留两位小数),表示从s到t的最短路径长度。
Example Input
5 0 0 2 0 2 2 0 2 3 1 5 1 2 1 3 1 4 2 5 3 5 1 5
Example Output
3.41
Hint
本题和 SDUT 2143 图结构练习——最短路径(http://blog.csdn.net/yxc9806/article/details/55522586) 基本完全一致,变化无非是源点和目标点改变了,边长需要求出罢了。
Submit
#include <bits/stdc++.h> #define INF 9999999.9 using namespace std; const int MAXN = 110; struct node { double x, y; }n[MAXN]; int N, S, T, i, j, k; double mp[MAXN][MAXN]; bool visit[MAXN]; double dist[MAXN]; void dijkstra() { memset(visit, 0, sizeof(visit)); for(i = 0; i <= N; i++) { dist[i] = mp[i][S]; } visit[S] = 1; dist[S] = 0; for(i = 1; i <= N; i++) { double Min = INF; for(j = 1; j <= N; j++) { if(!
1、LVDS接口概述
LVDS,即Low Voltage Differential Signaling,是一种低压差分信号技术接口。克服以TTL电平方式传输宽带高码率数据时功耗大、EMI电磁干扰大等缺点而研制的一种数字视频信号传输方式。LVDS输出接口利用非常低的电压摆幅(约350mV)在两条PCB走线或一对平衡电缆上通过差分进行数据的传输,即低压差分信号传输。采用LVDS输出接口,可以使得信号在差分PCB线或平衡电缆上以几百Mbit/s的速率传输,由于采用低压和低电流驱动方式,因此,实现了低噪声和低功耗。
2、LVDS接口电路的组成
在液晶显示器中,LVDS接口电路包括两部分,即主板侧的LVDS输出接口电路(LVDS发送端)和液晶面板侧的LVDS输入接口电路(LVDS接收器)。LVDS发送端将TTL信号转换成LVDS信号,然后通过驱动板与液晶面板之间的柔性电缆(排线)将信号传送到液晶面板侧的LVDS接收端的LVDS解码IC中,LVDS接收器再将串行信号转换为TTL电平的并行信号,送往液晶屏时序控制与行列驱动电路。也就是其实TFT只识别TTL(RGB)信号。这部分我们做samsung的方案中用的比较多,因为samsung芯片没有LVDS输出,所以我们用LVDS接口的TFT-LCD的时候就要加一个(RGB-LVDS)转换芯片,这个后面我们重点说。
3、LVDS接口的信号类型
LVDS信号有数据差分和时钟差分信号组成。如下图所示:
(1)、单通道LVDS
单通道6位数据(如果是6位的Y3M/P这组红色的线没有)有4组差分线,3组信号线,一组时钟线。Y0M、Y0P、Y1M、Y1P、Y2M、Y2P、CLKOUT_M、CLKOUT_P。单通道8位数据有5组差分线,4组信号线,一组时钟线。分别是Y0M、Y0P、Y1M、Y1P、Y2M、Y2P、CLKOUT_M、CLKOUT_P。
(2)、双通道
LVDS在传输分辨率较高的数据时,抗干扰能力比较强,可是1920X1080以上分辨率时,单路不堪重负,所以有双路接口出现。目的很简单,加快速度,增强抗干扰能力。双通道6位数据刚好是单通道的两倍,时钟也是两路,红色部分:Y3M、Y3P、Y3M1、Y3M1这两组信号不接。双通道8位数据和前面的比较类似。
01-Keras之用MNIST数据集训练一个DNN 模型code # -*- coding: utf-8 -*- '''Trains a simple deep NN on the MNIST dataset. Gets to 98.40% test accuracy after 20 epochs (there is *a lot* of margin for parameter tuning). 2 seconds per epoch on a K520 GPU. ''' from __future__ import print_function import numpy as np np.random.seed(1337) # for reproducibility from keras.datasets import mnist from keras.models import Sequential from keras.layers.core import Dense, Dropout, Activation from keras.
obs版本的选择:
工作室版,优化了很多东西,缺点是不能用插件,在部分机型不稳定,因为更新的很频繁。不过这个插件不能用的说法还是停留在早起,截至到今天已经完美支持,所以在不久的将来会越来越好,如果是开发的,推荐使用这个,开发团队也是推荐使用这个。
经典版。绝大部分的大主播用的都是这个版本,因为用习惯了,而且支持插件,稳定性比较强,但是性能没有前者高。
obs插件的选择:
现在主流而且最专业的应该是小葫芦开发的obs管家,涵盖国内直播平台的obs直播插件。
http://www.obsapp.com/
当然,obs在使用的过程上,以下网址可以提供一些帮助,比如实用教程,插件使用等:
http://www.xspliter.com/
http://tieba.baidu.com/f?kw=obs
当然,老外的网站是最专业的,不过根据国内平台的特殊情况,估计方法没那么多,同样,管网论坛也是有很多插件提供选择的,可以参考:https://obsproject.com/forum/
其它直播插件平台:
http://obspod.com/
obs插件的开发研究:
开发语言:C++,据说可以使用C#,不过没有具体研究过(基于OBS CLRHostPluginhttps://obsproject.com/forum/resources/clr-host-plugin.21/)。所以我建议既然要开发这个插件,最好选择C++开发,毕竟可以实现跨平台编译。C#还没到火候。
涵盖的平台:全平台,通过C++的CMake工具转换成特定平台的包进行编译开发,最终实现全平台。
搜索了一下obs插件开发教程,国内对于插件开发的比较少资料,还是如果要开发可以参考管网论坛进行查找资料,同样可以搜索github上一些资料进行参考,这是一个非常重要的线索。
管网下载:https://obsproject.com/download
github源码:https://github.com/jp9000/obs-studio(工作室版本),https://github.com/jp9000/obs(经典版本)
管网论坛:https://obsproject.com/forum/
以下是我搜索到国内的一些资料:
http://www.cnblogs.com/csuftzzk/p/OBS_Plugins_Development.html
http://www.jianshu.com/p/1dcc2208d01d
https://github.com/NlsNi/OBS-PicSwitcherPlugin(C#开发的插件)
http://www.cnblogs.com/xylc/p/3640994.html
对于开发的思路:把github代码下载下载,里面就有一些插件的,可以对着来开发,同样也可以搜索github上开有没有插件可以参考的,管网论坛上也提供了一些开发资料可以参考。
转载于:https://www.cnblogs.com/EasonJim/p/6408131.html
1.mysql日期和字符相互转换方法 date_format(date,’%Y-%m-%d’) ————–>oracle中的to_char(); str_to_date(date,’%Y-%m-%d’) ————–>oracle中的to_date();
%Y:代表4位的年份 %y:代表2为的年份
%m:代表月, 格式为(01……12) %c:代表月, 格式为(1……12)
%d:代表月份中的天数,格式为(00……31) %e:代表月份中的天数, 格式为(0……31) %H:代表小时,格式为(00……23) %k:代表 小时,格式为(0……23) %h: 代表小时,格式为(01……12) %I: 代表小时,格式为(01……12) %l :代表小时,格式为(1……12)
%i: 代表分钟, 格式为(00……59) 【只有这一个代表分钟,大写的I 不代表分钟代表小时】
%r:代表 时间,格式为12 小时(hh:mm:ss [AP]M) %T:代表 时间,格式为24 小时(hh:mm:ss) %S:代表 秒,格式为(00……59) %s:代表 秒,格式为(00……59) 2.例子: select str_to_date(‘09/01/2009’,’%m/%d/%Y’)
select str_to_date(‘20140422154706’,’%Y%m%d%H%i%s’)
select str_to_date(‘2014-04-22 15:47:06’,’%Y-%m-%d %H:%i:%s’)
转自:http://blog.csdn.net/jeamking/article/details/5953986
这两天在学springMVC,写了个商品管理系统demo。
遇到一个难点,日期时间是private Timestamp createtime;所以AJAX请求会报400参数错误,因为传createtime有问题,
后来想了下,前端做个处理,将时间戳转为Timestamp格式,下面贴JS代码:
/** * 格式化显示时间日期 * @param time Unix时间戳格式, 如:1393579588 * @param format 希望的时间格式,如:"yyyy-MM-dd hh:mm:ss" * @returns string 格式化后的时间字符串 */ function toDateTime (time, format) { var x = new Date(parseInt(time)), y = format; var z = {M: x.getMonth() + 1, d: x.getDate(), h: x.getHours(), m: x.getMinutes(), s: x.getSeconds()}; y = y.replace(/(M+|d+|h+|m+|s+)/g, function (v) { return ((v.length > 1 ? "0" : "") + eval('z.' + v.slice(-1))).slice(-2) }); var formatDateTime = y.
方式一 父文件夹上右键–New Folder–点击Advanced 然后关联文件系统上已有文件夹即可。
方式二 直接将文件夹拖入Eclipse Package Explorer下的某个父文件夹下,然后在弹出的窗口中选择:link to folder。
电磁场专业学校 在国内,电磁场专业比较厉害的学校不多。主要就是东南大学、上海交大、西安电子科技大学、成都电子科技大学。几个学校的电磁场与微波技术二级学科属于国家重点学科。
比较厉害的牛人:
东南大学的洪伟,他对于计算电磁学具有较高的造诣,在IEEE上发表过不少论文,现在是长江学者特聘教授,名气很大。
电子科技大学的文舸一教授名气也很大的。
上海交大的金荣洪教授对于MoM和MEI方法都有较高的造诣。
老一辈 林为干院士 是最杰出人物。 主要有:
东南的 洪伟、崔铁军 (目前主要在散射计算和3G技术)
成电的 王秉中 (FDTD)、聂在平(快速多极子算法)
北航的 王宝发 (散射高频算法<Greco 》)
西电的 龚书喜 (散射和天线)、葛德彪(FDTD)
北理工的高本庆 (FDTD)
香港城市大学梅冠香(K.K.Mei)教授也是很有名的大牛,IEEE会士,其贡献不小于R.F.Harrington,几乎同一时期提出矩量法;
东南大学章文勋教授,国内搞矩量法的大牛,也是天线界的大牛之一,也是IEEE会士;
南京理工大学方大纲教授,复镜像理论的提出者之一,对谱域矩量法、FDTD和微带天线都有深入研究,也是IEEE会士;还有南邮曹伟教授、西电梁昌洪教授,80年代初都曾师从人人皆知的矩量法大牛 Harrington,属于国内最早搞矩量法的人物。
中科院电子所的盛新庆研究员也在计算电磁学上有些造诣呀,我看过他最近出的一本关于这方面的书,至于成电的王秉中论文是发了不少 还是要看他们怎么带学生的,我想很多人都读研究生了,知道研究生怎么回事了,王秉中老师水平中上(在国内),去过香港城市大学做的博士后,两年前我肯定象你推荐读他的研究生,因为:
聂在平,是电子科大的付校长,平时行政比较忙,经常在学校里见到他推着一个破自行车,学术水平比较高,对学生要求比较严,听说过关于他严的故事。具体的不是很清楚了。
矩量法是梅冠香(K.K.Mei)首次在其博士论文中提出来的,梅冠香(K.K.Mei)当时并没有在重视自己提出的新方法,而被R.F.Harrington发扬光大了。
清华也有一个做FDTD的, 是王长青教授把, 跟我老板关系很好
国内比较牛的还是集中在成电,西电,东南,清华,北理工,南理工,北航,还有就是一些国防研究所。西电他们原来的校长梁昌洪,搞散射的吴振森,搞FDTD的葛德彪。东大的微波也是很强的,他又三个长江特聘学者,一个院士,一个IEEE Fellow,洪伟是系主任,在计算电磁学方面有很高成就,崔铁军业主要是计算电磁学,它是从Illinois大学回来的,那儿可是国际计算电磁学的中心,有C.W.Chow,金健铭(以前是南大毕业的)。吴柯,加拿大科学院最年轻的院士,也是东大的兼职教授。这几个都是比较有名的牛人。
什么是负载均衡(LB)
常规的软件部署:
单机部署:
用户请求直接打到服务器上面。比如说一些常见的管理系统,部署在tomcat里面。此时并发请求不是很多基本没什么问题。此时用户只需需要记住一个IP地址即可访问。
多机部署:
一个应用部署在多个服务器上面,目的就是请求如果很多的话,多个服务器同时提供服务,单机的并发请求量就会减少。这种场景就是典型的负载均衡。但是多机部署,用户如何访问?
由于是多机部署,存在多个IP,这样用户访问就会出现,使用那个IP访问,用户自己决定,但是这样明显不合适,所以就需要单独放置一台负载均衡器,用户只需要服务负载均衡器即可。
负载均衡器的IP我们称之为VIP。
名字解释:
流量:
用户的请求我们称之为流量,如果一个网站的每天的访问量很大,我们就说流量很大。
负载均衡:
将流量均匀的分散到多个应用服务器上面。
VIP:
负载均衡器的IP我们称之为VIP,而它后端的服务器的IP我们称之为:RIP。
VIP与RIP:
VIP和RIP是一对多的关系,就是一个VIP后面挂载多个RIP。
IDC:
多机房,在部署应用的时候,一般为了容灾,都是多个机房部署,每个机房部署一个负载均衡器,后面挂载多个应用服务器。这样的话就存在多个VIP,也每个机房一个VIP。
域名:
一个域名最终会解析成IP地址,这个解析的IP地其实就是负载均衡器的IP,也就是VIP地址,但是多机房部署,一个应用会有多个VIP地址,域名如何解析到一个VIP?、
DNS解析就会按照规则解析出一个访问最快的VIP
切流量:
多机房部署,有时候用户机房的可能会出现问题,此时用户请求提高负载均衡器就会将请求解析到出问题的机房,此时我们就要切换,也就是动态修改负载均衡器后面挂载的RIP。
切流量和高可用的区别:
高可用:一般是对关键节点做的,比如说负载均衡器,而应用服务器数量一般很多,没必要做高可用,如果出现问题,我们之需要告诉负载均衡器不要把请求转发到这台服务器即可。
切流量:就是告诉负载均衡器,不要把请求转发到用户不想转发的RIP应用服务器上面。
目的: 把用户流量均匀的分摊都后端的服务器上面就是负载均衡,所以支持并发tcp连接数越多,内存占用率以及进程占用率越低,同时支持多种负载均衡算法。
所以对于网卡的性能要求很高,因为并发连接是网卡实现的。 总结起来:
用户请求 -- 前端负载均衡---后端服务器
名词解释:
VIP: 前端负载均衡器的IP
RIP:后端服务器的IP地址
IDC:机房(多机房部署)
所以:用户通过域名访问,DNS解析成IP地址,这个IP地址就是负载均衡器的IP,也就是一个VIP,负载均衡器将请求转发的后端服务器IP,进而达到一次完成的请求流程,域名挂载VIP,VIP下面挂载RIP。
===============================================================================================
1.nginx 七层的负载均衡开源解决方案
2.haproxy
四层和七层负载均衡开源方案
3.lvs
四层的负载均衡方案
CUDA中使用多个流并行执行数据复制和核函数运算可以进一步提高计算性能。以下程序使用2个流执行运算:
#include "cuda_runtime.h" #include <iostream> #include <stdio.h> #include <math.h> #define N (1024*1024) #define FULL_DATA_SIZE N*20 __global__ void kernel(int* a, int *b, int*c) { int threadID = blockIdx.x * blockDim.x + threadIdx.x; if (threadID < N) { c[threadID] = (a[threadID] + b[threadID]) / 2; } } int main() { //获取设备属性 cudaDeviceProp prop; int deviceID; cudaGetDevice(&deviceID); cudaGetDeviceProperties(&prop, deviceID); //检查设备是否支持重叠功能 if (!prop.deviceOverlap) { printf("No device will handle overlaps. so no speed up from stream.
1、CHAR。CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充,所以在读取的时候可能要多次用到trim()。
2、VARCHAR。存储变长数据,但存储效率没有CHAR高。如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么“+1”呢?这一个字节用于保存实际使用了多大的长度。从空间上考虑,用varchar合适;从效率上考虑,用char合适,关键是根据实际情况找到权衡点。
3、TEXT。text存储可变长度的非Unicode数据,最大长度为2^31-1(2,147,483,647)个字符。
4、NCHAR、NVARCHAR、NTEXT。这三种从名字上看比前面三种多了个“N”。它表示存储的是Unicode数据类型的字符。我们知道字符中,英文字符只需要一个字节存储就足够了,但汉字众多,需要两个字节存储,英文与汉字同时存在时容易造成混乱,Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。nchar、nvarchar的长度是在1到4000之间。和char、varchar比较起来,nchar、nvarchar则最多存储4000个字符,不论是英文还是汉字;而char、varchar最多能存储8000个英文,4000个汉字。可以看出使用nchar、nvarchar数据类型时不用担心输入的字符是英文还是汉字,较为方便,但在存储英文时数量上有些损失。
所以一般来说,如果含有中文字符,用nchar/nvarchar,如果纯英文和数字,用char/varchar
它们的区别概括成:
CHAR,NCHAR 定长,速度快,占空间大,需处理
VARCHAR,NVARCHAR,TEXT 不定长,空间小,速度慢,无需处理
NCHAR、NVARCHAR、NTEXT处理Unicode码 但在mysql5.6中,char,varchar被默认为了nchar,nvarchar(猜测可能跟设置的默认数据库编码为utf-8有关)。 varchar: CUprivilege列是varchar(4)字符类型,却可以插入四个汉子“铜牌会员” nvarchar: nvarchar是存储两个字节的UNICODE字符 在varchar中插入五个英文字符, 在nvarchar中插入五个英文字符, 综上所述,在mysql5.6中将varchar自动转换为nvarchar字符数据。
CUDA流表示一个GPU操作队列,该队列中的操作将以添加到流中的先后顺序而依次执行。可以将一个流看做是GPU上的一个任务,不同任务可以并行执行。使用CUDA流,首先要选择一个支持设备重叠(Device Overlap)功能的设备,支持设备重叠功能的GPU能够在执行一个CUDA核函数的同时,还能在主机和设备之间执行复制数据操作。
支持重叠功能的设备的这一特性很重要,可以在一定程度上提升GPU程序的执行效率。一般情况下,CPU内存远大于GPU内存,对于数据量比较大的情况,不可能把CPU缓冲区中的数据一次性传输给GPU,需要分块传输,如果能够在分块传输的同时,GPU也在执行核函数运算,这样的异步操作,就用到设备的重叠功能,能够提高运算性能。
以下程序演示单个流的使用步骤,对比使用流操作的性能提升,不使用流的情况:
#include "cuda_runtime.h" #include <iostream> #include <stdio.h> #include <math.h> #define N (1024*1024) #define FULL_DATA_SIZE N*20 __global__ void kernel(int* a, int *b, int*c) { int threadID = blockIdx.x * blockDim.x + threadIdx.x; if (threadID < N) { c[threadID] = (a[threadID] + b[threadID]) / 2; } } int main() { //启动计时器 cudaEvent_t start, stop; float elapsedTime; cudaEventCreate(&start); cudaEventCreate(&stop); cudaEventRecord(start, 0); int *host_a, *host_b, *host_c; int *dev_a, *dev_b, *dev_c; //在GPU上分配内存 cudaMalloc((void**)&dev_a, FULL_DATA_SIZE * sizeof(int)); cudaMalloc((void**)&dev_b, FULL_DATA_SIZE * sizeof(int)); cudaMalloc((void**)&dev_c, FULL_DATA_SIZE * sizeof(int)); //在CPU上分配可分页内存 host_a = (int*)malloc(FULL_DATA_SIZE * sizeof(int)); host_b = (int*)malloc(FULL_DATA_SIZE * sizeof(int)); host_c = (int*)malloc(FULL_DATA_SIZE * sizeof(int)); //主机上的内存赋值 for (int i = 0; i < FULL_DATA_SIZE; i++) { host_a[i] = i; host_b[i] = FULL_DATA_SIZE - i; } //从主机到设备复制数据 cudaMemcpy(dev_a, host_a, FULL_DATA_SIZE * sizeof(int), cudaMemcpyHostToDevice); cudaMemcpy(dev_b, host_b, FULL_DATA_SIZE * sizeof(int), cudaMemcpyHostToDevice); kernel << <FULL_DATA_SIZE / 1024, 1024 >> > (dev_a, dev_b, dev_c); //数据拷贝回主机 cudaMemcpy(host_c, dev_c, FULL_DATA_SIZE * sizeof(int), cudaMemcpyDeviceToHost); //计时结束 cudaEventRecord(stop, 0); cudaEventSynchronize(stop); cudaEventElapsedTime(&elapsedTime, start, stop); std::cout << "
写NIO程序经常使用ByteBuffer来读取或者写入数据,那么使用ByteBuffer.allocate(capability)还是使用ByteBuffer.allocteDirect(capability)来分配缓存了?第一种方式是分配JVM堆内存,属于GC管辖范围,由于需要拷贝所以速度相对较慢;第二种方式是分配OS本地内存,不属于GC管辖范围,由于不需要内存拷贝所以速度相对较快。
我们肯定想选择比较快的,但问题是直接内存不属于GC管辖范围,需要弄清楚这部分内存如何管理,否则造成内存泄露就麻烦了。本地内存在JAVA中有一个对应的包装类DirectByteBuffer,该类属于Java类,适当的时候会被GC回收,当它被回收前会调用本地方法把直接内存给释放了,所以本地内存可以随DirectByteBuffer对象被回收而自动回收,貌似没有问题;但如果不断分配本地内存,堆内存很少使用,那么JVM就不需要执行GC,DirectByteBuffer对象们就不会被回收,这时候堆内存充足,但本地内存可能已经使用光了,再次尝试分配本地内存就会出现OutOfMemoryError,那程序就直接崩溃了。
有没有解决方案?自动释放不靠谱,我们是否可以手动释放本地内存,把握主动权?果然DirectByteBuffer持有一个Cleaner对象,该对象有一个clean()方法可用于释放本地内存,所以需要的时候我们可以调用这个方法手动释放本地内存。
以下代码与测试场景帮助理解与证实以上描述。
代码1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.stevex.app.nio; import java.nio.ByteBuffer; import java.util.concurrent.TimeUnit; public class DirectByteBufferTest { public static void main(String[] args) throws InterruptedException{ //分配128MB直接内存 ByteBuffer bb = ByteBuffer.allocateDirect( 1024 * 1024 * 128 ); TimeUnit.SECONDS.sleep( 10 ); System.out.println( "ok" ); } } 测试用例1:设置JVM参数-Xmx100m,运行异常,因为如果没设置-XX:MaxDirectMemorySize,则默认与-Xmx参数值相同,分配128M直接内存超出限制范围。
1 2 3 4 5 Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory at java.
最近有业务需求,需要模拟键盘输入,所以了解了一下C#中keybd_event函数的用法。该函数能够产生WM_KEYUP或WM_KEYDOWN消息,即可以触发键盘事件。
函数引用如下:
[DllImport("user32.dll", EntryPoint = "keybd_event")] public static extern void keybd_event( byte bVk, byte bScan, int dwFlags, //0: DOWN, 2: UP int dwExtraInfo //Default: 0 ); } Keybd_event()共有四个参数。 第一个为按键的虚拟键值,可以使用枚举值System.Windows.Forms.Keys。 第二个参数为扫描码,一般不用设置,用0代替就行。 第三个参数为选项标志,如果为keydown则置"0",如果为keyup则设成"2"。 第四个参数一般也是置0即可。
'A'的虚拟键值为65,所以可以用如下代码实现模拟单击'A'键。 keybd_event(65, 0, 0, 0); keybd_event((byte)Keys.A, 0, 2, 0); 转载于:https://www.cnblogs.com/LiangShanCamp/p/6393966.html
iOS中关联对象的简单使用
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) 1.被关联的对象,下面举的例子中关联到了UIAlertView 2.要关联的对象的键值,一般设置成静态的,用于获取关联对象的值 3.要关联的对象的值,从接口中可以看到接收的id类型,所以能关联任何对象 4.关联时采用的协议,有assign,retain,copy等协议,具体可以参考官方文档 下面就以UIAlertView为例子简单介绍一下使用方法。 使用场景:在UITableView中点击某一个cell,这时候弹出一个UIAlertView,然后在UIAlertView消失的时候获取此cell的信息,我们就获取cell的indexPath好了。 第一步: #import <objc/runtime.h> static char kUITableViewIndexKey; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ...... UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"这里是xx楼" delegate:self cancelButtonTitle:@"好的" otherButtonTitles:nil]; //然后这里设定关联,此处把indexPath关联到alert上 objc_setAssociatedObject(alert, &kUITableViewIndexKey, indexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [alert show]; } 第二步: - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex == 0) { NSIndexPath *indexPath = objc_getAssociatedObject(alertView, &kUITableViewIndexKey); NSLog(@"%@", indexPath); } }
sleep() sleep()方法需要指定等待的时间,它可以让当前正在执行的线程在指定的时间内暂停执行,进入阻塞状态,该方法既可以让其他同优先级或者高优先级的线程得到执行的机会,也可以让低优先级的线程得到执行机会。但是sleep()方法不会释放“锁标志”,也就是说如果有synchronized同步块,其他线程仍然不能访问共享数据。 wait() wait()方法需要和notify()及notifyAll()两个方法一起介绍,这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用,也就是说,调用wait(),notify()和notifyAll()的任务在调用这些方法前必须拥有对象的锁。注意,它们都是Object类的方法,而不是Thread类的方法。 wait()方法与sleep()方法的不同之处在于,wait()方法会释放对象的“锁标志”。当调用某一对象的wait()方法后,会使当前线程暂停执行,并将当前线程放入对象等待池中,直到调用了notify()方法后,将从对象等待池中移出任意一个线程并放入锁标志等待池中,只有锁标志等待池中的线程可以获取锁标志,它们随时准备争夺锁的拥有权。当调用了某个对象的notifyAll()方法,会将对象等待池中的所有线程都移动到该对象的锁标志等待池。 除了使用notify()和notifyAll()方法,还可以使用带毫秒参数的wait(long timeout)方法,效果是在延迟timeout毫秒后,被暂停的线程将被恢复到锁标志等待池。 此外,wait(),notify()及notifyAll()只能在synchronized语句中使用,但是如果使用的是ReenTrantLock实现同步,该如何达到这三个方法的效果呢?解决方法是使用ReenTrantLock.newCondition()获取一个Condition类对象,然后Condition的await(),signal()以及signalAll()分别对应上面的三个方法。
yield() yield()方法和sleep()方法类似,也不会释放“锁标志”,区别在于,它没有参数,即yield()方法只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行,另外yield()方法只能使同优先级或者高优先级的线程得到执行机会,这也和sleep()方法不同。
join() join()方法会使当前线程等待调用join()方法的线程结束后才能继续执行,例如:
package concurrent; public class TestJoin { public static void main(String[] args) { Thread thread = new Thread(new JoinDemo()); thread.start(); for (int i = 0; i < 20; i++) { System.out.println("主线程第" + i + "次执行!"); if (i >= 2) try { // t1线程合并到主线程中,主线程停止执行过程,转而执行t1线程,直到t1执行完毕后继续。 thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } } class JoinDemo implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { System.
我们从其他模块接收到一个JSON串,数据格式如下:
{"videos":[{"vid":26975741,"pid":0,"mid":61733563,"name":"《乐高大电影:蝙蝠侠》新曝预告 蝙蝠侠成"熊孩子"爹"}]} 对获取到的json进行string转object的时候,采用eval()、JSON.parse()均无法解析,原因为name的value值中存在英文双引号。 解决方案: 保存数据的时候,用正则表达式把英文双引号替换为中文双引号
var reg=new RegExp("\"", "g"); objectJson.name = objectJson.name.replace(reg, "”"); 这个问题的解决思路为:规范保存到数据库的数据,而不是想办法解析value值存在英语双引号的json。
首先,构造器是不能被继承的,因为每个类的类名都不相同,而构造器名称与类名相同,所以根本谈不上继承。 又由于构造器不能继承,所以就不能被重写。但是,在同一个类中,构造器是可以被重载的。
使用Callable和FutureTask,可以实现有返回值的线程创建,并且可以抛出异常:
package concurrent; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; class CallableDemo implements Callable<Integer> { @Override public Integer call() throws Exception { // 计算1-100的和 int sum = 0; for (int i = 1; i <= 100; i++) sum += i; return sum; } } public class TestCallable { public static void main(String[] args) { CallableDemo cd = new CallableDemo(); // 使用Callable方式创建线程,需要FutureTask类的支持,用于接收运算结果,可以使用泛型指定返回值的类型 FutureTask<Integer> result = new FutureTask<>(cd); new Thread(result).start(); int sum = 0; // 接收运算结果 // 只有当该线程执行完毕后才会获取到运算结果,等同于闭锁的效果 try { sum = result.
面向对象编程介绍 1.什么是面向对象 面向将系统看成通过交互作用来万恒特定功能的对象的集合。每个对象用自己的方法来管理数据。也就是说只有对象内部的代码能够操作对象内部的数据 2.面向对象的优点 通过,继承、封装、多态降低程序的耦合度,并结合设计模式让程序更容易修改和扩展,并且易于复用。 3.面向对象的特点
① 封装——维护性 ② 继承——复用性 ③ 多态——扩展性 ④ 抽象
类与对象 1.类的声明
class Test { public: 公有成员(外部接口):对外可以访问 private: 私有成员:不能在类外访问 protect: 保护成员:不能在类外访问 }; 2.成员函数 类内实现的方法默认为inline函数 Test.h
#ifndef _TEST_H_ #define _TEST_H_ class Test { pubilc: int x_; void initXYZ(int x, int y, int z); void displayXYZ(); protected: int y_; private: int z_; }; Test.cpp
#include “Test.h” #include <iostream> void Teat::initXYZ(int x, int y, int z) { x_=x; y_=y; z_=z; } void Test:display() { cout x_<<”\ny_”<<”\nz_”<<endl; } Main.
常用PS技能 怎么把一个图层变透明怎么把一个图片变透明 [#2]怎么调整画布大小 让画布自动适应图像大小怎么快速隐藏工具栏和浮动面板 #1怎么修改背景色 [#3] 符号说明 例如: xxxx1 xxxx2 [#1,#2] xxxx3 [#1,#链接中的第几条说明] 1,2,3表示的是解决这个问题的1,2,3种办法 [#1,#2]表示的是解决这个问题用到了链接中#1,#2项
说明 KMP算法看懂了觉得特别简单,思路很简单,看不懂之前,查各种资料,看的稀里糊涂,即使网上最简单的解释,依然看的稀里糊涂。 我花了半天时间,争取用最短的篇幅大致搞明白这玩意到底是啥。 这里不扯概念,只讲算法过程和代码理解:
KMP算法求解什么类型问题 字符串匹配。给你两个字符串,寻找其中一个字符串是否包含另一个字符串,如果包含,返回包含的起始位置。 如下面两个字符串:
char *str = "bacbababadababacambabacaddababacasdsd"; char *ptr = "ababaca"; str有两处包含ptr 分别在str的下标10,26处包含ptr。
“bacbababadababacambabacaddababacasdsd”;\ 问题类型很简单,下面直接介绍算法
算法说明 一般匹配字符串时,我们从目标字符串str(假设长度为n)的第一个下标选取和ptr长度(长度为m)一样的子字符串进行比较,如果一样,就返回开始处的下标值,不一样,选取str下一个下标,同样选取长度为n的字符串进行比较,直到str的末尾(实际比较时,下标移动到n-m)。这样的时间复杂度是O(n*m)。
KMP算法:可以实现复杂度为O(m+n)
为何简化了时间复杂度: 充分利用了目标字符串ptr的性质(比如里面部分字符串的重复性,即使不存在重复字段,在比较时,实现最大的移动量)。 上面理不理解无所谓,我说的其实也没有深刻剖析里面的内部原因。
考察目标字符串ptr: ababaca 这里我们要计算一个长度为m的转移函数next。
next数组的含义就是一个固定字符串的最长前缀和最长后缀相同的长度。
比如:abcjkdabc,那么这个数组的最长前缀和最长后缀相同必然是abc。 cbcbc,最长前缀和最长后缀相同是cbc。 abcbc,最长前缀和最长后缀相同是不存在的。
**注意最长前缀:是说以第一个字符开始,但是不包含最后一个字符。 比如aaaa相同的最长前缀和最长后缀是aaa。** 对于目标字符串ptr,ababaca,长度是7,所以next[0],next[1],next[2],next[3],next[4],next[5],next[6]分别计算的是 a,ab,aba,abab,ababa,ababac,ababaca的相同的最长前缀和最长后缀的长度。由于a,ab,aba,abab,ababa,ababac,ababaca的相同的最长前缀和最长后缀是“”,“”,“a”,“ab”,“aba”,“”,“a”,所以next数组的值是[-1,-1,0,1,2,-1,0],这里-1表示不存在,0表示存在长度为1,2表示存在长度为3。这是为了和代码相对应。
下图中的1,2,3,4是一样的。1-2之间的和3-4之间的也是一样的,我们发现A和B不一样;之前的算法是我把下面的字符串往前移动一个距离,重新从头开始比较,那必然存在很多重复的比较。现在的做法是,我把下面的字符串往前移动,使3和2对其,直接比较C和A是否一样。
代码解析 void cal_next(char *str, int *next, int len) { next[0] = -1;//next[0]初始化为-1,-1表示不存在相同的最大前缀和最大后缀 int k = -1;//k初始化为-1 for (int q = 1; q <= len-1; q++) { while (k > -1 && str[k + 1] !
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <unistd.h> #include <arpa/inet.h> #include <openssl/ssl.h> #include <openssl/err.h> #define MAXBUF 1024 /************关于本文档******************************************** *filename: ssl-server.c *purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是服务器端例子 *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com) Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言 *date time:2007-02-02 19:40 *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途 * 但请遵循GPL *Thanks to:Google *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力 * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献! *********************************************************************/ int main(int argc, char **argv) { int sockfd, new_fd; socklen_t len; struct sockaddr_in my_addr, their_addr; unsigned int myport, lisnum; char buf[MAXBUF + 1]; SSL_CTX *ctx; if (argv[1]) myport = atoi(argv[1]); else myport = 7838; if (argv[2]) lisnum = atoi(argv[2]); else lisnum = 2; /* SSL 库初始化 */ SSL_library_init(); /* 载入所有 SSL 算法 */ OpenSSL_add_all_algorithms(); /* 载入所有 SSL 错误消息 */ SSL_load_error_strings(); /* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */ ctx = SSL_CTX_new(SSLv23_server_method()); /* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */ if (ctx == NULL) { ERR_print_errors_fp(stdout); exit(1); } /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */ if (SSL_CTX_use_certificate_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stdout); exit(1); } /* 载入用户私钥 */ if (SSL_CTX_use_PrivateKey_file(ctx, argv[5], SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stdout); exit(1); } //载入私钥密码,否则终端提示用户手动输入密码 /*或者 #include <openssl/ssl.
一、简介 SSL(Secure Socket Layer)是netscape公司提出的主要用于web的安全通信标准,分为2.0版和3.0版.TLS(Transport Layer Security)是IETF的TLS 工作组在SSL3.0基础之上提出的安全通信标准,目前版本是1.0,即RFC2246.SSL/TLS提供的安全机制可以保证应用层数据在互联网络传输 不 被监听,伪造和窜改.
openssl(www.openssl.org) 是sslv2,sslv3,tlsv1的一份完整实现,内部包含了大量加密算法程序.其命令行提供了丰富的加密,验证,证书生成等功能,甚至可以用其建立 一个完整的CA.与其同时,它也提供了一套完整的库函数,可用开发用SSL/TLS的通信程序. Apache的https两种版本 mod_ssl和apachessl均基于它实现的.openssl继承于ssleay,并做了一定的扩展,当前的版本是0.9.5a.
openssl 的缺点是文档太少,连一份完整的函数说明都没有,man page也至今没做完整:-(,如果想用它编程序,除了熟悉已有的文档(包括 ssleay,mod_ssl,apachessl的文档)外,可以到它的maillist上找相关的帖子,许多问题可以在以前的文章中找到答案.
编程: 程序分为两部分,客户端和服务器端,我们的目的是利用SSL/TLS的特性保证通信双方能够互相验证对方身份(真实性),并保证数据的完整性, 私密性.
对程序来说,openssl将整个握手过程用一对函数体现,即客户端的SSL_connect和服务端的SSL_accept.而后的应用层数据交换则用SSL_read和 SSL_write来完成.
二、证书文件生成 除将程序编译成功外,还需生成必要的证书和私钥文件使双方能够成功验证对方,步骤如下:
1.首先要生成服务器端的私钥(key文件): openssl genrsa -des3 -out server.key 1024 运行时会提示输入密码,此密码用于加密key文件(参数des3便是指加密算法,当然也可以选用其他你认为安全的算法.),以后每当需读取此文 件(通过openssl提供的命令或API)都需输入口令.如果觉得不方便,也可以去除这个口令,但一定要采取其他的保护措施! 去除key文件口令的命令: openssl rsa -in server.key -out server.key
2.openssl req -new -key server.key -out server.csr 生成Certificate Signing Request(CSR),生成的csr文件交给CA签名后形成服务端自己的证书.屏幕上将有提示,依照其指示一步一步输入要 求的个人信息即可.
3.对客户端也作同样的命令生成key及csr文件: openssl genrsa -des3 -out client.key 1024 openssl req -new -key client.key -out client.csr
4.CSR文件必须有CA的签名才可形成证书.可将此文件发送到verisign等地方由它验证,要交一大笔钱,何不自己做CA呢. 首先生成CA的key文件: openssl -des3 -out ca.
直播的火爆带来了海量的用户,也带来了海量的服务器并发。全国在线直播平台数量接近200家,网络直播平台用户数量已经达到2亿,大型直播平台每日高峰时段同时在线人数接近400万,这一数据还在以极快的速度向上攀升。直播火没火,看用户就知道,但是直播有没有前景,就要看科技巨头们对它的态度了。
如此大的用户体量下,直播类的应用对于服务器的要求要高过一般的应用,我们来看看直播类的应用对服务器有哪些更多的挑战?
更大的数据量
视频数据和文本数据完全是两个量级的概念,假设一个直播房间有5000人,视频1s的数据60K,那么就需要5000*60=300000KB=292.97MB,基本已经达到了2-3三个手游的大小了,而这只是一个房间产生的流量。当前某著名网络直播APP日活跃用户超过了800W,服务器将承受458Gbps的带宽压力。
更高的并发量
不同于普通应用和游戏,直播类应用的使用时间段非常的集中,一般来说,社交类的直播app时间集中在晚饭后时间至睡前20点~23点,游戏类App活跃时间集中在下班后18~20点间,秀场类App集中在13点和18(午休及下班时间),因此在这短短几小时之间,会涌入大量的用户,一次大V的直播通常就会造成百万级的用户登录,APP需要有详尽的限流、分流和负载均衡策略,保证服务器不会被冲垮。
更真实的用户登录场景
直播应用与普通应用相比,交互的功能异常多,除了直播视频流的服务器压力之外,还要包括用户消息推送、聊天、礼物、支付以及统计系统带来的数据交互压力,服务器进行需要识别不同的业务字段,才能精确判定用户的行为是否成功完成,从交互频率的角度上来说,直播类的应用,与其说更像应用,不如说更像游戏。
更低的延迟
直播需要一个很强的即时性,如果主播的行为和用户的评论无法同步的时候,会给用户非常不好的体验,如果一个用户发现其他用户在欢呼鼓掌,但是屏幕中的主播什么动静都没有的时候,这个直播应用基本可以不要再用了,因此直播类应用不仅需要面对更大的数据量和更高的并发,还要保证更低的延迟。通常可以要保证服务器的处理数据速度要快,要有足够强大的带宽;另外则是通过P2P算法保证数据分享的合理性,保证服务器的数据和P2P的数据可以达到平衡。
不同于一般app测试,更倾向兼容性或功能测试,对于直播应用来说,服务器的测试需求就越来越大。而服务器最难处理的环节就是视频流量和用户交互等高频率高带宽的场景,用户的行为是难以预测的,经常会出现突发性的暴涨,一般在进行活动的时候,流量可能是平时的几十倍。多场景的压测,要完全模拟真实用户行为,测试结果才能更接近现实。
IntWritable是 Hadoop 中实现的用于封装 Java 数据类型的类,它的原型是public IntWritable(int value)和public IntWritable()两种。所以new IntWritable(1)是创建了这个类的一个对象,而数值1这是参数。在Hadoop中它相当于java中Integer整型变量,为这个变量赋值为1.
转自:http://jingyan.baidu.com/article/54b6b9c0e0ea172d583b4725.html
Apache http启动正常。但是访问不了http共享出来的目录。页面403报错,同时http日志也报错。
问题解决步骤:
1:页面报错
2:http日志报错
3:查看Directory / 是否配置错误
4:查看Directory "/var/www/html" 是否配置错误
5:查看/etc/selinux/config文件是否配置错误
6:最终定位问题并解决
1:页面报错
输入http://172.30.x.x 出现http欢迎界面。
但是输入http:172.30.x.x/kk01 页面403报错:
Forbidden
You don't have permission to access /kk01 on this server.
2:http日志报错
[root@localhost ~]# cd /var/log/httpd/
[root@localhost httpd]# ls
access_log error_log
[root@localhost httpd]# ll
?荤.?.20
-rw-r--r--. 1 root root 7310 11?.19 21:47 access_log
-rw-r--r--. 1 root root 8645 11?.19 21:47 error_log
[root@localhost httpd]#
[root@localhost ~]# cat /var/log/httpd/error_log
报错:Permission denied: access to /kk01/ denied
官网写的比较具体,可以查看以下的网站:
http://www.mybatis.org/mybatis-3/zh/configuration.html
另外,实际用到标准的CRUD的操作和查询列表,
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.iteye.tom.dao.AuthItemRecordDao"> <sql id="requestAllFields"> <![CDATA[ id, record_time AS recordTime, source_code AS sourceCode, userid, auth_item_id AS authItemId, isvalid, last_status_time AS lastStatusTime ]]> </sql> <sql id="whereClause"> <where> <if test="null!=id">AND id = #{id}</if> <if test="null!=sourceCode and ''!=sourceCode">AND source_code = #{sourceCode}</if> <if test="null!=userid and ''!=userid">AND userid = #{userid}</if> <if test="null!=authItemId and ''!=authItemId">AND auth_item_id = #{authItemId}</if> <if test="null!=isvalid and ''!=isvalid">AND isvalid = #{isvalid}</if> <include refid="
在虚拟机下安装ubuntu提示:“没有定义根文件系统,请回到分区菜单以修正此错误”
解决办法:设置三个分区(ext4,swap,ext4),分别对应三个挂载点(\, swap, \home),问题解决。
简单总结一句,Spring提供的计时器StopWatch对于秒、毫秒为单位方便计时的程序,尤其是单线程、顺序执行程序的时间特性的统计输出支持比较好。也就是说假如我们手里面有几个在顺序上前后执行的几个任务,而且我们比较关心几个任务分别执行的时间占用状况,希望能够形成一个不太复杂的日志输出,StopWatch提供了这样的功能。而且Spring的StopWatch基本上也就是仅仅为了这样的功能而实现。
实际中用到的代码:
public void run() { LOGGER.info("[" + taskName + "]开始执行"); StopWatch stopWatch = new StopWatch(); stopWatch.start(taskName); try { doTask(); } catch (Exception e) { LOGGER.error("[" + taskName + "]执行失败", e); } finally { stopWatch.stop(); LOGGER.info("[" + taskName + "]执行结束,耗时:" + stopWatch.getTotalTimeMillis() + "毫秒"); } } 另外,还可以使用一些其他的方法:
import org.springframework.util.StopWatch; public class StopWatchDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub StopWatch clock = new StopWatch(); clock.
Acitivty的四中启动模式与特点。 standard:默认的启动模式singleTop:适合那种接受通知启动的页面,比如新闻客户端之类的,可能会给你推送好几次 ,但是每次都是打开同一张页面调用onNewIntentsingleTask:适合作为程序入口点,例如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空浏览器主界面上面的其他页面。而之前打开过的页面不再新建singleInstance:适合需要与程序分离开的页面。例如闹铃,将闹铃提醒与设置分离,使得闹铃提醒成为系统范围内的唯一实例 Acitivity后台闲置退出或异常退出,如何保存数据
通过 onSaveInstanceState() 和 onRestoreInstanceState() 保存和重启非持久化数据。
Service的生命周期,两种启动方法,有什么区别 Service的第一种启动方式 采用start的方式开启服务
使用Service的步骤:
1.定义一个类继承Service 2.在Manifest.xml文件中配置该Service 3.使用Context的startService(Intent)方法启动该Service 4.不再使用时,调用stopService(Intent)方法停止该服务
使用这种start方式启动的Service的生命周期如下:
** onCreate()--->onStartCommand()(onStart()方法已过时) ---> onDestory()**
** 说明:**
如果服务已经开启,不会重复的执行onCreate(), 而是会调用onStart()和onStartCommand()。 服务停止的时候调用 onDestory()。服务只会被停止一次。
** 特点:**
一旦服务开启跟调用者(开启者)就没有任何关系了。 开启者退出了,开启者挂了,服务还在后台长期的运行。 开启者不能调用服务里面的方法。
Service的第二种启动方式 采用bind的方式开启服务
使用Service的步骤:
1.定义一个类继承Service 2.在Manifest.xml文件中配置该Service 3.使用Context的bindService(Intent, ServiceConnection, int)方法启动该Service 4.不再使用时,调用unbindService(ServiceConnection)方法停止该服务
使用这种start方式启动的Service的生命周期如下:
** onCreate() --->onBind()--->onunbind()--->onDestory()**
** 注意:**绑定服务不会调用onstart()或者onstartcommand()方法
** 特点:**bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。 绑定者可以调用服务里面的方法。
绑定者如何调用服务里的方法呢? 首先定义一个Service的子类。
public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { //返回MyBind对象 return new MyBinder(); } private void methodInMyService() { http://www.
book[]数组对元素进行标记,进行判断遍历
#include<stdio.h> #include<windows.h> int a[10], book[10], n; void dfs(int step) { int i; if (step == n + 1) { for (i = 1; i <= n; i++) { printf("%d ", a[i]); } printf("\n"); //return; } for (i = 1; i <=n; i++) { if (book[i] == 0) { a[step] = i; book[i] = 1; dfs(step + 1); book[i] = 0; } } } int main() { scanf_s("%d", &n); dfs(1); system("
程序代码:GuessBirthDate.cpp /** * 运行程序,做5次选择,就能知道你的生日是哪一天。 */ #include <iostream> using namespace std; int main() { int date = 0; // Date to be determind char answer; // Prompt the user for Set 1 cout << "Is your birth date in this set ?" << endl; cout << "16 17 18 19\n" << "20 21 22 23\n" << "24 25 26 27\n" << "28 29 30 31" << endl; cout << "Enter N for No and Y for Yes: "
我们在.net编程时,有时候会出现在App_Code里的类,其他地方不能调用它。提示未找到类型或命名空间名称。
App_Code里的类,我们在引用它的时候是不需要引入命名空间的。那么为什么还是不能直接调用呢?
问题出在它的生成操作的方式上。具体解决方法如下:
首先找到不能引用的类文件,右击,属性,把“生成操作”属性值由“内容”改为“编译”。
转自:http://www.elecfans.com/yuanqijian/jingzhen/20170122477665.html 32.768KHZ含意 32.768KHZ是一个很有意义的数字,我们每天都要用到它,它给我们带来太多的好处。只是生活中太少有人去关注了,只关注着它给我们带来的演变数字。32.768khz比较容易分频以便于产生1秒的时钟频率,因为32768等于2的15次方(15次分频后就是1Hz的秒信号)。我们每天用的手表、手机、电脑上显示作用的钟就是由它演变过来的。
32.768KHZ晶振的发展 32.768KHZ晶振最初在日本开始它的大量发展,并形成全球之势。人们利用晶体的独特物理特性,加工成一个标准的时钟晶振。从而应用到各种电子行业,给电子行业带来了一个历史的变革;随着人们技术水平的提高,晶振的精度和性能越来越高,体积也越来越小,现在有很多的IC集成电路公司己将这小小的晶振放在里面,更加的精密度。
在模型中连接查询方式
$query = new \Phalcon\Mvc\Model\Query("SELECT A.id, A.name, A.age, A.address, B.name as bname FROM UserTest as A INNER JOIN robots B ON A.id=B.id WHERE A.id=:id:", $this->getDI()); $data = $query->execute(['id' => 1])->toArray(); 在控制器中查询方式
$this->modelsManager->executeQuery("SELECT * FROM UserTest")->toArray(); 使用查询构建器创建查询
NOIP 复赛 NOI 上机 机试 评测系统 Arbiter
Mac VMWare Fusion 安装 NOIP 复赛 NOI 上机 机试 评测系统 Arbiter 姐妹篇 详见Mac VMWare Fusion 安装 NOIP 复赛 NOI 上机 机试 评测系统 Arbiter_mrcrack的博客-CSDN博客 2018-8-14 12:53
复赛,最终成绩是要到linux下测评的,很多选手(windows,linux环境)对此感到很神秘,
自个安装一个官方测评系统,使用,消除神秘感,为windows下编程树立信心,
在复赛中取得好成绩打下基础。笔者写下此文。读者遵循笔者思路,耗时半天,即可见到效果。
关键字:不要简易安装 一定要全屏
1.windows系统下安装vmware,虚拟机。
2.载入http://www.noi.cn下载的noilinux-1.4.1.iso。
3.在虚拟机中安装ubuntu。
4.安装过程中,两次采用简易安装,均获失败,浪费时间2小时。
5.用VMware安装ubuntu防止简易安装,请参考http://jingyan.baidu.com/article/54b6b9c0f8890f2d583b47c8.html,成败在此一举。
部分引用如下:
用vmware安装时很多时候会被简易安装,无法自己选择语言等问题
趁着2018-11-12 在台式机上安装 noi linux ,赶紧将安装过程,抓图保存。以下为安装过程。2018-11-13
1点击 文件 新建虚拟机 弹出如下窗口 在窗口中 点击 下一步
2选择 稍后安装操作系统 点击 下一步
3选择 Linux,选择 Ubuntu 点击 下一步
4可更改 适合自己的 合适的 位置(L): 点击 下一步
MethodHandle类的实质是将某个具体的方法映射到MethodHandle上,通过MethodHandle直接调用该句柄所引用的底层方法,实际就是对可执行方法的引用。接着我们对MethodHandle类中的方法进行详细解析。
1. asCollector方法 asCollector(Class
MethodHandles.Lookup publicLookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(String.class, int[].class); MethodHandle deepToString = publicLookup.findStatic(AsCollector.class, "deepToString", mt); MethodHandle ts1 = deepToString.asCollector(int[].class, 3); System.out.println(ts1); 2. asFixedArity和asVarargsCollector方法 asFixedArity()方法,返回固定参数数量的方法句柄。 asVarargsCollector(Class
public static String deepToString(int a[]) { return (a[0]) + "";} public static String deepToString(int a) { return a + "";} public static void main(String[] args) throws Throwable { MethodHandles.Lookup publicLookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(String.class, int[].class); MethodHandle deepToString = publicLookup.
idea的主题可以自定义,也可从网上下载 http://www.riaway.com/theme.php 喜欢的主题,保存到本地。
主题是一个jar的包。导入到idea的方法如下:
file –> import setttings –>主题jar文件 –> 确认 –> 重启
这样就导入主题了。
同样的,自定义的主题也可以保存起来。什么时候想用就再导入。导出的方法如下:
file –> Export setttings –> 选中保存路径--> 确认
现有如下场景,需要根据A表的check_code字段和B表的store_code、check_result字段组合查询,A表与B表的关联关系为一对多。 为了简化查询参数,我们对查询参数进行了封装,抽出了公共的QueryCondition:
public class QueryCondition<T> { protected int page = 1; protected int limit = 10; public QueryCondition() { }; public QueryCondition(int page, int limit) { this.page = page; this.limit = limit; } public Specification<T> getWhereClause() { return new Specification<T>() { @Override public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> list = new ArrayList<Predicate>(); list.add(cb.equal(root.get("status"), Status.STATUS_ACTIVE)); return cb.and(list.toArray(new Predicate[list.size()])); } }; } public Pageable getPageRequest() { if (page < 1) { page = 1; } return new PageRequest(page - 1, limit); } public Criteria buildPageableCriteria(Criteria c) { int start = (this.
1. jstat
http://blog.csdn.net/fenglibing/article/details/6411951
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
2. 分析栈内存(stack)
jstack/kill -3
http://jameswxx.iteye.com/blog/1041173
3. 分析堆内存(heap)
jmap + jhat。
http://www.cnblogs.com/diyunpeng/archive/2011/06/10/2077369.html
4. Dump JAVA堆
由于出现问题时,往往是不能够重启服务器时,这时需要我们以最快的速度将dump文件拿到。
最快速方法:
1、通过ps aux | grep java找到java的pid。
2、gcore pid
3、将core文件转化为dump文件
jmap -dump:format=b,file=dump.hrof /opt/jdk1.7.0_55/bin/java core.22687
传统方法:
1、运行命令jmap -dump:live,format=b,file=heap.bin pid 将内存dump下来。
2、找到可疑对象
将dump文件导入到mat工具里,并分析可疑对象,运气好的时候往这一步就可以找到项目里的异常对象。
3、详细分析
通过dominator视图过滤关心的对象。
4、通过OQL语句分析,并将可疑类的所有对象内存导出并计算。
背景:利用爬虫,爬取网站页面广告元素,监控爬取元素的数目,定时发送监控邮件
#!/usr/bin/env python2.7 # -*- coding: utf-8 -*- ''' @xiayun @896365105@qq.com #爬取网站内容,利用phantomjs:IP代理+修改UA+动态页面执行JS ''' from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities import time import urllib,urllib2 import smtplib import re from email.mime.text import MIMEText from email.header import Header import sys def reptile(): global result, data #proxy_ip.txt为IP代理池,可以自己爬IP,也可以买,不过都不稳定, #需要在前面再加一个IP验证程序。 IPS = [i for i in open("./proxy_ip.txt", 'r').readline().split('\n') if i] print IPS for i in IPS: service_args = [] service_args = ['--proxy-type=HTTP',] IP_str = ''.
原文位置:http://www.cnblogs.com/freeblues/p/5754158.html 介绍一个非常好用的跨平台C++开源框架:openFrameworks 简介 首先需要说明的一点是: openFrameworks 设计的初衷不是为计算机专业人士准备的, 而是为艺术专业人士准备的, 就像 Processing 一样.
概述 openFrameworks 是一个功能强大, 上手超级简单的 C/C++ 开源框架. 它集成封装了很多常用的库, 诸如:
OpenGL、GLEW、GLUT、libtess2、cairo - 用于处理图形;rtAudio、PortAudio、OpenAL、Kiss FFT、FMOD - 用于音频的输入、输出和分析;FreeType - 用于字体显示;FreeImage - 用于图像存储和载入;Quicktime、GStreamer、videoInput - 用于视频播放和截取;Poco - 用于开发网络应用;OpenCV - 用于计算机视觉;Assimp - 用于读入 3D 模型。 openFrameworks 为这些库提供了一个统一的接口, 使得使用它们变得异常容易.
跨平台 另外值得一提的就是 openFrameworks 的跨平台特性, 从桌面系统到移动终端, openFrameworks 目前支持:
WindowsOSXLinuxAndroidiOS 最新的 0.9.0 版本还支持运行 Linux 系统的 arm 开发板, 例如树莓派.
支持发布为WEB形式 openFrameworks 集成了 Emscripten 作为插件, 我们的 openFrameworks 程序可以通过它很容易地转换成 javascript 的格式, 这样非常方便就把本地项目转换成了 WEB 项目, 可以直接发布到网络上.
HTML:
<body>
<form id="form1" runat="server">
<div>
<div class="text-tabs">/*导航栏*/
<a class="text-tab" data-target="/" href="javascript:void(0);" οnclick="skipto(this);"><span>首页</span></a>
</div>
<div id="login" style=" width:200px; height:400px; float:left;">default.aspx</div>
<iframe src="/head.html?parame=head_introduce" frameBorder="0" width="100%" scrolling="no" height="61px"></iframe>
</div>
</form>
</body>
JQ:
$(function() {
//在iframe中查找父页面元素
alert($('#default', window.parent.document).html());
//在iframe中调用父页面中定义的方法
parent.getHelloWorld();
//在iframe中调用父页面中定义的变量
alert(parent.hello);
//从父页面中打开网页
parent.location.href = '/index.html';
var login = request('login');
var token = request('access_token');
var parame = request('parame');
function skipto(obj){
if(token!=''){
parent.location.href=$(obj).attr('data-target')+'?login=' + login + '&access_token=' + token + '';
}
else{
1、IF语句 IF search_condition THEN statement_list [ELSEIF search_condition THEN statement_list] ... [ELSE statement_list] END IF 2、CASE语句 CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement_list] ... [ELSE statement_list] END CASE Or:
CASE WHEN search_condition THEN statement_list [WHEN search_condition THEN statement_list] ... [ELSE statement_list] END CASE 3、LOOP语句 [begin_label:] LOOP statement_list END LOOP [ end_label] LOOP允许某特定语句或语句群的重复执行,实现一个简单的循环构造。在循环内的语句一直重复直循环被退出,退出通常伴随着一个LEAVE 语句。 LOOP语句可以被标注。除非 begin_label存在,否则 end_label不能被给出,并且如果两者都出现,它们必须是同样的。 4、LEAVE语句 LEAVE label 这个语句被用来退出任何被标注的流程控制构造。它和BEGIN ... END或循环一起被使用。 5、ITERATE语句 ITERATE label ITERATE只可以出现在LOOP, REPEAT, 和WHILE语句内。ITERATE意思为:“再次循环。”
对于IE6到9的兼容,我们一般用HTML自带的检测,追加CSS样式就可以了。如下:
<!--[if IE 6]> <link charset="utf-8" type="text/css" rel="stylesheet" href="css/index-ie6.css"/> <![endif]--> <!--[if IE 7]> <link charset="utf-8" type="text/css" rel="stylesheet" href="css/index-ie7.css"/> <![endif]--> 对于IE10以上的兼容,我们用HTML自带的检测无法检测到,所以我们需要用JS来做一个判断,追加CSS样式就可以了。如下: <script type="text/javascript"> $(function() { var userAgent = window.navigator.userAgent.toLowerCase(); var version = $.browser.version; if(version == 10.0){ $("head").append("<link charset='utf-8' type='text/css' rel='stylesheet' href='css/index-ie10.css'/>"); } alert(version); }); </script> Ps:如果能用HTML检测就别用JS了,这样效果以及性能会好一些!希望能帮到跟我一样在路上的攻城狮们!同学们!
* java8 新增的@Repeatable注解,其实只是语法糖而已. * java8 注解的 {@link RepeatAnn} 类与 {@link Annotations}是等价的. * 新注解讲语法糖转化为注解值为数组形式. package com.github.jdk8.ebook.java8_recipes2nd_edition; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Arrays; /** * java8 新增的@Repeatable注解,其实只是语法糖而已. * java8 注解的 {@link RepeatAnn} 类与 {@link Annotations}是等价的. * 新注解讲语法糖转化为注解值为数组形式. * @author doctor * * @since 2015年2月3日 下午8:33:43 */ public class Chapter2Code { public static void main(String[] args) { Annotation[] annotations = RepeatAnn.class.getAnnotations(); System.out.println(annotations.length); //1 Arrays.stream(annotations).forEach(System.out::println);//@com.github.jdk8.ebook.java8_recipes2nd_edition.Chapter2Code$Roles(value=[@com.github.jdk8.ebook.java8_recipes2nd_edition.Chapter2Code$Role(name=doctor), @com.
一:基本知识 keychain在ios中是保存在sqlite数据库中的。 这个数据库文件的位置: 真机: /private/var/Keychains/keychain-2.db 虚拟机: /Users/USER-HOME/Library/Developer/CoreSimulator/Devices/26DCA62C-B516-4DEA-A601-5C2D0EA07710/data/Library/Keychains/keychain-2-debug.db 在虚拟机中,这个数据库考出来就不能读了,很奇怪,不过也可以打开MAC上的keychain-2-debug.db文件看看表结构。 下面的每一项都代表一张表。每张表的字段是不同的。 kSecClassGenericPassword 对应的表:genp kSecClassInternetPassword 对应的表:inet kSecClassCertificate 对应的表:cert CFTypeRef kSecClassKey 对应的表:keys CFTypeRef kSecClassIdentity 对应的表:没找到,应该是cert和key这两个表联起来用,各放一部分。 每个表拥有的字段都是以 kSecAttr开头定义的。 表中有些字段是系统自己维护的,如cdate:创建时间,mdate:修改时间还有创建者等。 这些字段都指定了数据类型,所以什么字段放什么类型的值都是字段定死的。 比如,kSecClassGenericPassword下的kSecAttrService就只能保存字符串。 因为有些字段的值是枚举类型的,比如 kSecClassInternetPassword下的kSecAttrProtocol字段,就是一个枚举类型,所以定义了很多kSecAttrProtocol开头的常量。 最常用的kSecClassGenericPassword表:genp 这三个常量都对应表的data字段,但在从数据库取出后,会转为不同的数据类型。 这个字段是会加密保存的。 kSecValueData kSecValueRef kSecValuePersistentRef kSecClassGenericPassword item attributes: kSecAttrAccessible kSecAttrAccessControl kSecAttrAccessGroup 对应字段:agrp kSecAttrCreationDate 对应字段:cdat kSecAttrModificationDate 对应字段:mdat kSecAttrDescription 对应字段:desc kSecAttrComment kSecAttrCreator 对应字段:crtr kSecAttrType 对应字段:type kSecAttrLabel 对应字段:labl kSecAttrIsInvisible 对应字段:invi kSecAttrIsNegative 对应字段:nega kSecAttrAccount 对应字段:acct kSecAttrService 对应字段:svce kSecAttrGeneric 对应字段:gena 使用到的api: SecItemAdd 增 SecItemDelete 删 SecItemUpdate 改 SecItemCopyMatching 查 首先使用kSecReturnAttributes = kCFBooleanTrue;查找属性值是否存在。若属性存在,则使用kSecReturnData = kCFBooleanTrue;获取data即密码字段,并转换称NSString返回。属性存在,而密码不存在时返回特殊的错误码。 需要共享数据的应用,要保证AppIdentifierPrefix(也叫teamid, 一个appId账号对应一个teamid)相同。
为什么80%的码农都做不了架构师?>>> 作者:汪娇娇
时间:2017年1月17日
问题其实很简单,就是h5的video视频如何在iPhone上不全屏显示,并且自动播放。
测过就知道,只要在video上加一个autoplay属性,就可以在iPad或者Browser上自动播放;给video加一个宽高,就可以在iPad或者Browser上不全屏播放。但在iPhone上用这方法简直免谈。
话不多说,直接说方法。
HTML(加webkit-playsinline和autoplay属性)
<video id="player" width="480" height="320" webkit-playsinline autoplay> Obj-C
webview.allowsInlineMediaPlayback = YES; //允许内屏播放 webview.mediaPlaybackRequiresUserAction = NO; //自动播放 这样就OK啦,不过仅支持ios10及以上。
注:video的src最好写绝对路径,不然视频播放不了,大家可以去测测。
转载于:https://my.oschina.net/jojo76/blog/826719
使用Connector/J连接MySQL数据库,程序运行较长时间后就会报以下错误:
Communications link failure,The last packet successfully received from the server was *** millisecond ago.The last packet successfully sent to the server was *** millisecond ago。
其中错误还会提示你修改wait_timeout或是使用Connector/J的autoReconnect属性避免该错误。
后来查了一些资料,才发现遇到这个问题的人还真不少,大部分都是使用连接池方式时才会出现这个问题,短连接应该很难出现这个问题。这个问题的原因:
MySQL服务器默认的“wait_timeout”是28800秒即8小时,意味着如果一个连接的空闲时间超过8个小时,MySQL将自动断开该连接,而连接池却认为该连接还是有效的(因为并未校验连接的有效性),当应用申请使用该连接时,就会导致上面的报错。
修改MySQL的参数,wait_timeout最大为31536000即1年,在my.cnf中加入:
[mysqld]
wait_timeout=31536000
interactive_timeout=31536000
重启生效,需要同时修改这两个参数。
本文主要记载修改数据库链接的等待时间,源文章地址:http://blog.csdn.net/xuzhuang2008/article/details/8129204
仅工作中使用到,现查现用,理解不到位,请持怀疑态度查看本文。如有问题请联系邮件:tyut_lb@163.com; 以便交流。
导出插件 参考文章:http://www.th7.cn/Program/java/201308/147987.shtml 文章讲解三种方式导出插件。
因为在安装插件的时候有一种直接安装zip包的方式,这种方式管理插件方便,有效,所以我在导出插件的时候按照这个zip这个方式导出,安装也按照这个方式安装。
导出方式上面有完整的步骤,很详细。但是对于每一步的原理我不清楚。
大致过程在这里记录一下:
1、首先准备好插件项目工程
2、新建 Feature Project 工程,这个工程中需要选择上面准备好的插件工程
3、再新建 Category Definition ,新建的东西会在 上面Feature Project 工程下出现个.xml文件
4、配置上面的.xml文件,需要新建 New Category 和 Add Feature. 在Add Feature 的时候需要选择上面新建好的Feature Project 工程
5、导出工作。export 导出选择 Deployable features。
在Destination中配置导出路径。
在Option中配置Category repository,选择Category Definition 新建的那个.xml.
这样完成后会生成 features , plugins, 还有content.jar , artifacts.jar 这四个东西。
这样就可以安装了。
6、接着在这个基础上生成zip包安装的方式
新建 Update Site Project 工程,新建完后会有一个site.xml文件。编辑这个文件 New Category 和 Add Feature。 在 Add Feature的时候选择上面新建的 Feature Project 工程。
7、点击build,工程下需要打包成zip的东西都就都有了,然后手动把features , plugins, 还有content.
微信小程序-API
框架提供丰富的微信原生API,可以方便的调起微信提供的能力,如获取用户信息,本地存储,支付功能等。
说明:
wx.on 开头的 API 是监听某个事件发生的API接口,接受一个 CALLBACK 函数作为参数。当该事件触发时,会调用 CALLBACK 函数。 如未特殊约定,其他 API 接口都接受一个OBJECT作为参数。 OBJECT中可以指定success, fail, complete来接收接口调用结果。
参数名 类型 必填 说明 success Function 否 接口调用成功的回调函数 fail Function 否 接口调用失败的回调函数 complete Function 否 接口调用结束的回调函数(调用成功、失败都会执行) API列表:
网络 API 列表:
API 说明
wx.request 发起网络请求 wx.uploadFile 上传文件 wx.downloadFile 下载文件 wx.connectSocket 创建 WebSocket 连接 wx.onSocketOpen 监听 WebSocket 打开 wx.onSocketError 监听 WebSocket 错误 wx.sendSocketMessage 发送 WebSocket 消息 wx.onSocketMessage 接受 WebSocket 消息 wx.closeSocket 关闭 WebSocket 连接 wx.
题目链接
真的很想说这道题读懂题意比解决题目本身要难。。。然而题目本身的意思又很简单就是求最长递增子序列。但这道题有点特殊的地方就是要优化,常规的两个for的方法会超时,然后在《挑战程序设计竞赛》这本书上给了另一个nlogn的方法——就是定义dp[i]:=长度为i+1的上升子序列中末尾元素的最小值(不存在的话就是INF),初始化对dp[]数组全部赋值成INF,也就是+∞,然后对每个 aj 如果 i = 0 或者 dp[i-1] < aj 的话,就用dp[i] = min(dp[i],aj)进行更新。最终找出使得dp[i]<INF的最大的i+1就是结果。
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define INF 99999999 int s[40005]={0}; int dp[40005]={0}; int main() { //freopen("in.in","r",stdin); int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=0;i<=n;i++) dp[i]=INF; for(int i=0;i<n;i++) scanf("%d",&s[i]); for(int i=0;i<n;i++) *lower_bound(dp,dp+n,s[i])=s[i]; printf("%d\n",lower_bound(dp,dp+n,INF)-dp); } return 0; }
转自:http://www.taidous.com/thread-41942-1-3.html
程序:
1.可维护性 2.可复用性 3.可扩展性 4.灵活性好 通过封装、继承、多态把程序的耦合度降低 简单工厂模式: 用一个独立的类来做这个创造实例的过程 聚合表示一种弱的"拥有关系",体现的是A对象可以包含B对象,但B对象不是A对象的一部分。 合成表示一种强的"拥有关系", 体现了严格的部分和整体的关系,部分和整体的生命周期一样。 优点:工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类。,对于客户端来说,去除了与具体产品的依赖。 策略模式: 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的用户。 装饰模式: 动态地给对象添加一些额外的职责(为功能动态添加更多功能的一种方式),就增加功能来说,装饰模式比生成子类更加的灵活。 好处:有效的把类的核心职责和装饰功能区分开了。 装饰模式将每个要装饰的功能都放在单独的类中,并让这个类包装它所要装饰的对象,一次,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。 有效的把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。 代理模式: (双方不需要知道对方的存在,通过中间人进行代码的调用) 为其他对象提供一种代理以控制对这个对象的访问 远程代理:也就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。 虚拟代理:是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象[DP]。 安全代理:用来控制真实对象访问的权限[DP]。 智能指引:是指当调用真实的对象时,代理处理另外一些事[DP]。 工厂方法模式: 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 原型模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 (一般在初始化的信息不发生变化的情况下, 克隆是最好的方法。这即隐藏了对象的创建细节,又对性能是大大的提高) 浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。 深复制:把引用对象的变量都指向复制过的新对象,而不是原有的被引用的对象。 简单来说:浅复制复制值类型,引用类型赋值的是引用的地址 深复制引用类型复制的是引用类型的对象,就是在需要改变的值的基类中声明一个克隆方法并在具体类中调用 模版方法模式: 定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 当我们要完成在某一细节层次一致的一个过程或一个系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们同城考虑使用模版方法。 通过把不变行为搬移到超类,去除子类中的重复代码来提现它的优势。模版方法模式提供了一很好的代码复用平台。 外观模式: 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 简单来说:就是将你一次需要调用的方法整理在一个接口里面,调用接口,直接就调用了方法。 建造者模式(生成器模式): 用户只需制定需要建造的类型就可以得到它们,而具体建造过程和细节就不需知道了。 将一个复杂对象的构造与它的表示分离,使得同样的构建过程可以创建不同的表示。 简单来说:我们需要建造一样东西,客户端不需要知道建造过程,只需要知道要造什么就可以了。 观察者模式: 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自己更新自己。 抽象工厂模式: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 好处:易于交换产品系列。具体的创建实例过程与客户端分离。客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。 状态模式: 当一个对象的内在状态改变时允许改变其作为,这个对象看起来是像是改变了其类。 将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所有通过定义新的子类可以很容易地增加新的状态和转换。 简单来说“对象的行为取决于它的状态,并且需要在运行时改变它的状态。那么就应该用状态模式。 当你有大量的判断语句,那么将每一个判断写成一个方法。当达到某一个要求的时候,提供另外一个且只有一个方法,减少了相互之间的耦合性。 适配器模式: 当系统的数据和行为都正确,但结构不符时,我们应该考虑用适配器,目的就是使控制范围之外的一个原有对象和某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。 简单来说:当两个类需要互相调用,但是接口不符合的时候,就用适配器模式,讲接口适配成相同的,进行匹配。(当然,只有当无法改变原有设计和代码的情况下,才考虑适配模式) 备忘录模式: 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。这样以后就可将该对象恢复到原先保存的状态。 用于功能比较复杂的,但需要维护和记录属性历史的类。 缺点:会非常消耗内存 组合模式: 将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 当你发现需求中是体现部分与整体层次的结构时,以及你希望用于可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式。 组合模式的体现方式有点像树状结构,不断的细分下去。 迭代器模式: 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。 类似于foreach循环 这样做的目的就是不让外部访问到内部的结构,但是可以访问到内部的数据。 单例模式: 保证一个类仅有一个实例,并提供一个访问它的全局的访问点。 通常我们可以让一个全局变量使得一个对象的被访问,但它不能放置你实例化对个对象。所以我们需要然各类自身负责保存它的唯一实例。这个类可以爆照没有其他实例可以被创建,并且它可以提供一个额访问该实例的方法。 简单来说:就是对唯一实例的受控访问。 多线程的单例模式:在多个线程中,我们需要同时访问某一个类的时候,这样就会同时创建多个实例,所以 我们需要加一把锁来处理(lock),如果有一个线程已经处在代码的临界区内的时候,另外一个线程就需要等待,直到临界区内的线程被释放。 桥接模式: 将抽象部分与它的实现部分分离,使他们都可以独立地变化。 简单来说:我们需要多角度分类的时候,可以用桥接模式,让它们各自变化。这部分变化不会影响到其他实现。从而达到应对变化的目的,减少他们之间的耦合性。 命令模式: 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。 职责链模式: 当多个对象都有机会处理这个事件的时候,就将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 中介者模式: 用一个中介者对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而降低耦合性。而且可以独立地改变它们之间的交互。(缺点是:不容易维护) 享元模式: 运用共享技术有效地支持大量细粒度的对象。(当一个程序使用大量的对象的时候,就应该考虑享元模式) 简单来说:就是在程序的开发过程中,有许多实例大部分内容都是相同的,那么我们就需要通过享元模式大幅度的减少单个实例的数目,从而降低服务器的占用资源。 解释器模式: 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 简单来说:就是语言翻译器的功能,当输入一段文字后,通过返回得到一段固定不变的文字。 访问器模式(GoF中最复杂的模式): 表示一个作用与某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用与这个元素的新操作。 访问器模式适用于数据结构相对稳定的系统,因为它的作用是把数据结构和作用于结构上的操作之间的耦合性解脱开,使得操作集合可以相对自由地演化。(假设如果你需要增加一个新的操作的时候,就要增加一个新的访问者,那么访问器模式就是讲有关的行为集中到一个访问者对象中,) 单一职责原则 就一个类而言,应该仅有一个引起它变化的原因(如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多一个的职责,就应该考虑类的职责分离) 开放-封闭原则 对扩展是开放的。对更改是关闭的。 依赖倒转原则 抽象不应该依赖细节,细节应该依赖于抽象 高层模块不应该依赖低层模块。两个都应该依赖抽象 里氏代换原则 子类型必须能够替换它们的父类型 只有当子类可以替换掉父类,软在·件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。 真是因为子类的可替换性才使得使用父类类型的模块在无需修改的情况下就可以扩展。 如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的射击,反之那就是过程化的设计。 迪米特原则 如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。 合成/聚合复用原则 如果新对象的某些功能在别的已经创建好的对象里面已经实现,那么尽量使用别的对象提供的功能,使之成为新对象的一部分,而不要自己再重新创建。新对象通过向这些对象的委派达到复用已有功能的。 简而言之,要尽量使用合成/聚合,尽量不要使用继承。 接口隔离原则 不需要将所有的东西都放在一个接口里面,应该是定义多个功能专一的接口。过于臃肿的接口只会强迫客户依赖于不需要的方法。
1、获取当前行
var row = $('#dg').datagrid('getSelected'); 2、获取所有选中行
var rows = $('#dg').datagrid('getSelections'); 3、获取所有行
var rows = $("#dg").datagrid("getRows"); 4、获取行中间的某列数据
ar rows = $('#dg'').datagrid('getRows'); for (var i = 0; i < rows.length; i++) { alert(rows[i]['SCORE']); //获取指定列 }
安装小米助手和MiPhone刷机工具时,使用Windows 10的朋友可能遇到小米驱动安装不上或者遇到驱动程序签名问题,下载官方的驱动包有可能无法解决!!! 我之前遇到过,今天又遇到了,现在写下这个问题,供以后遇到的朋友查看。 下面,我们开始: 1, 依次打开-Windows 10 设置-更新和安全-恢复-高级启动-立即重启-疑难解答-高级选项-启动设置-重启 2, 待重启后选择“禁用驱动程序强制签名”对应的数字选项。开机后重新安装MiPhone刷机工具或者直接在设备管理器当中利用现在的驱动程序进行安装。即会安装成功。 3, 重新启动电脑。正常使用!
#文件名是 .***_history 例如 cat .mysql_history cd ~/ cat .***_history
GDB - 暂停/恢复程序执行 在使用GDB调试程序的时候,经常需要暂停程序,以查看程序执行情况和上下文。GDB 提供了多种暂停程序的方式,包括 break point, watch point, catch point, signals 和 thread stop. 在此这些概念直接饮用,不作翻译。 1. 设置暂停点 # set breakpoint usage: break file:function # 在文件file 中 function函数入口处暂停 break *<addr> # 在addr地址位置暂停 break file:line # 在文件file 中 行line处暂停 break class::function # 在 c++ 中使用 break class::function(type,type,...) # 在 c++ 中使用 # breakpoint with condition usage:break ... if <condition> # 设置条件断点,'...'可以是上面任意类型,condition是条件表达式 -------------------------------------------------------------- # set watchpoints usage: wacth <expr> # 设置变更 watchpoint,即当表达式值发生变化时暂停 rwatch <expr> # 设置'读' watchpoint,即当有对表达式的读取访问时暂停 awatch <expr> # 设置 '读写' watchpoint, 无论读写都暂停,注写时表达式也不一定变化 ------------------------------------------------------------------- # set catchpoints usage:catch <event> # 设置捕捉点,捕捉运行时事件 tcatch <event> # 设置临时捕捉点 #event 可以是以下关键字 # throw - C++ 抛出异常事件 # catch - 捕捉到C++异常事件 # 这些功能很有用,有没有遇到过C++程序运行退出,但又没任何core文件产生,让你找不到原因的时候,试一下这个命令吧。(后面还会有一个有帮助的命令) 2.
转自:http://www.mianfeidianhua.net/threading.html
先来看这段代码:
import threading
import time
def worker():
print “worker”
time.sleep(1)
return
for i in xrange(5):
t = threading.Thread(target=worker)
t.start()
这段代码就使用了多线程,但是没法传递参数,而实际使用多线程,往往是需要传递参数的,于是问了一位群里的网友后,知道可以这么写实现传递参数的多线程:
import threading
import time
def worker(number):
print “worker”
time.sleep(number)
return
for i in xrange(5):
t = threading.Thread(target=worker,args=(i,))
t.start()
第一个参数是线程函数变量,第二个参数args是一个数组变量参数,如果只传递一个值,就只需要i, 如果需要传递多个参数,那么还可以继续传递下去其他的参数,其中的逗号不能少,元组中只包含一个元素时,需要在元素后面添加逗号。
1. 背景
最近在工作中,需要实现网页端图片上传到FTP服务器的功能。上传文件是用Form表单提交数据的方法向后台传输文件流,在此遇到了一个问题:后台在处理完图片上传功能后,需要向前台回传是否上传成功的状态码、上传失败的错误信息和上传成功后的图片URL。但是,用普通Form表单提交的话,没有办法实现回调函数。后来在小伙伴的介绍下,发现可以用ajaxSubmit()方法来实现此功能。
2. ajaxSubmit()方法简介
(1)ajaxSubmit()依赖
ajaxSubmit()方法是JQuery Form表单插件中的方法,要想使用该插件,可以直接去官网http://jquery.malsup.com/form/下载。使用时,需要在jsp或者html页面上,引入JQuery库和Form插件。
(2)ajaxSubmit()用法简介
ajaxSubmit()方法接受0个或者1个参数,当为单个参数时,该参数既可以是一个回调函数,也可以是一个options对象。回调函数比较简单,下面主要介绍一下options的用法。options对象可以设置的参数如下:
var options = { target: ‘#output1’, //把服务器返回的内容放入id为output1的元素中 beforeSubmit: showRequest, //提交前的回调函数 success: showResponse, //提交后的回调函数 url: url, //默认是form的action,如果声明,则会覆盖 type: type, //默认是form的method,如果声明,则会覆盖 dataType: json , //接受服务端返回的类型 clearForm: true, //成功提交后,清除所有表单元素的值 resetForm: true, //成功提交后,重置所有表单元素的值 timeout: 3000 //限制请求的时间,当请求大于3秒后,跳出请求 }; 这些参数里,比较常用的就是提交前的回调函数beforeSubmit和提交后的回调函数success。beforeSubmit主要是用来提交表单前,校验数据的。示例代码:
function validate(formData, jqForm, options) { /* 在这里需要对表单元素进行验证,如果不符合规则, 直接返回false来阻止表单提交。 */ var queryString = $.param(formData); //组装数据 return true; } 这个回调函数有三个参数,formData是数组对象,jqForm是一个JQuery对象,它封装了表单的元素,options参数就是options对象。在这个回调函数中,只要不返回false,表单都将被允许提交;如果返回false,则会阻止表单提交。
success是提交后的回调函数,有4个参数responseText,statusText,xhr,和$form。其中,比较常用的是前两个。statusText只是一个返回状态,例如success,error等。responseText携带着服务器返回的数据内容,它会根据设置的options对象中的dataType属性来返回相应格式的内容。
3. ajaxSubmit()方法代码示例
下面是ajaxSubmit()方法使用的一个模板。
$(function(){ var options = { type: 'POST', url: '提交路径', success:showResponse, dataType: 'json', error : function(xhr, status, err) { alert("
""" 中介者模式 用一个中介对象封装一系列对象的交互,使各对象不再需要显示互相引用,减少了对象间的耦合 把对象的交互抽象到了一个中介对象中,我们可以把注意力从对象行为转移到对象的交互上,可以更宏观的看待对象问题 从网状结构变成星型结构 应用场景:各对象已定义良好,但是对象间有复杂的通讯 """ from abc import ABCMeta, abstractmethod class Unit(object): __metaclass__ = ABCMeta def __init__(self): pass @abstractmethod def declare(self, count, message): pass class Nations(Unit): def __init__(self): super(Nations, self).__init__() self._china = None self._american = None def set_china(self, china): self._china = china def set_american(self, american): self._american = american def declare(self, country, message): if self._china.name == country.name: self._american.get_message(message) elif self._american.name == country.name: self._china.get_message(message) class Country(object): __metaclass__ = ABCMeta def __init__(self, name, nations): self.
现象:
1并发运行5分钟,脚本全部执行成功,所有指标正常,并发设置为20脚本运行一段时间后TPS突然下降为0,响应时间线条无打点记录,过段时间后相关指标又恢复正常,查看报错信息为连接不上服务器,如图所示:
Error信息:连接服务器失败:
定位分析:
根据图中曲线走势和报错信息,“连接不上服务器,连接超时”,查看应用服务器的资源使用情况,内存,CPU,NET几乎没任何消耗,压力并发到达服务器,有可能程序阻塞或者负载机到服务器之间存在问题,先查看负载机资源及网络情况,发现资源充足,但是网络出现大量阻塞,延时现象严重,到这里可确定为负载机到服务器的网络资源出现延时问题导致,如图负载机网络资源延时现象:
在做tuxedo和socket脚本的过程中,经常会碰到发送的报文是十六进制字符串。而往往我们又需要针对十六进制报文中的某些数据进行参数化。比如pos机交易,银行方面数据交易,几乎使用socket协议。比如需要对交易流水号进行参数化,此类数据参数化方法有两种(推荐第一种):
①:需要参数化的流水号数据为:"\x00\x00\x01"
Ø 新建一个参数化文件,且为File类型,如图:
Ø 在外部对数据进行加“\”进行转义,外部生成的大量流水号数据copy到Loadrunner的参数化文件中,如图:转义后的字符正好为loadrunner所识别
Ø 需要参数化的地方替换使用就便可
②:使用loadrunner自带的C函数memcpy、memset、lr_eval_string进行处理,处理较麻烦,需要对十六进制数据进行转换,长度计算及拼接,使用第一种方法简单方便。
手里项目需要通过网络实时传输图像信息,但是由于图像分辨率太高,所以在传输的时候,每一帧图像的传输都需要很长时间,再到客户端解析。拖泥带水的感觉真的非常不好。而使用的ARM芯片本身是能够支持H.264格式硬编码的,所以尝试一下,看看能不能解决点问题。
源代码是这个兄弟的:点击打开链接,但是因为Linux内核版本不同,导致使用的Android系统的版本也不一样,所以下载下来的东西并不能直接使用,需要把SsbSipMfcApi.h SsbSipMfcEncApi.c mfc_interface.h和mfc_error.h,重新替换成所使用的Linux内核版本对应的,Android系统版本的相应的文件。文件目录再Android源码根目录/device/samsung/multimedia/codecs/video/exynos4/mfc/enc下。然后需要稍微修改一下SsbSipMfcEncApi.c文件。如下
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <math.h> #include "mfc_interface.h" #include "SsbSipMfcApi.h" #if 0 #include <utils/Log.h> /* #define LOG_NDEBUG 0 */ #undef LOG_TAG #define LOG_TAG "MFC_ENC_APP" #endif #define _MFCLIB_MAGIC_NUMBER 0x92241001 void LOGE(char *m, ...) { printf(m); } void LOGV(char *m, ...) { printf(m); } void LOGI(char *m, ...) { printf(m); } void *SsbSipMfcEncOpen(void) { int hMFCOpen; _MFCLIB *pCTX = NULL; unsigned int mapped_addr; int mapped_size; struct mfc_common_args CommonArg; //LOGI("
在Ubuntu中,进入vi命令的编辑模式,发现按方向键不能移动光标,而是会输出ABCD,以及退格键也不能正常删除字符。这是由于Ubuntu预装的是vim-tiny,而我们需要使用vim-full,解决方法很简单,只需要以下两步: 步骤一,输入下述命令以卸载vim-tiny:
sudo apt-get remove vim-common 步骤二,输入下述命令以安装vim-full:
sudo apt-get install vim 现在在vi命令的编辑模式即可正常使用方向键和退格键。
我在出初学spring boot时,用idea启动项目没问题,但是用maven启动项目时报错信息如下:
[ERROR] No plugin found for prefix 'spring-boot' in the current project and in t he plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from th e repositories [local (C:\Users\Administrator\.m2\repository), alimaven (http:// maven.aliyun.com/nexus/content/groups/public/)] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e swit ch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please rea d the following articles: [ERROR] [Help 1] http://cwiki.
Test Flight 测试使 说明 TestFlight提供的管 办法是将测试者分为内部成员和外部成员。 论上说,这 两种测试者都可以在测试阶段使 你的App, 过所谓的内部主要是指iTunesConnect上在你的开发团队 参与技术开发或者管 的成员。你最多可以邀请25个内 部成员, 与之相对的外部成员, 然就是指那些 属于你的团队或者公司的测试者, 外部测试 员的上限是2000 。这 有 点需要注意的是,在你邀请外部成员参与 测试之前,需要先通过苹果的审核。 这 限制在内部成员上就没有,也就是说 旦 你把你的App上传到iTunesConnect上之后内部成员就可以开始进 测试 , 需审 核。 在进 TestFighting测试之前,需要在iTunesConnected中新建一个待审核的App版本,并上传IPA 件, 上传大家应该都会,这里不做说明 ,上传后截图如下:
1. 点击菜单栏中的Test Fighting。 2. 填写测试信息。测试信息中,“反馈电 邮件”与“营销 址(URL)”可以选 择 填写,但是在添加外部测试版本时需要再次填写, 且为必填项。
“反馈电 邮件”是接收测试员反馈结果的邮箱。 3. 添加内部测试,内部测试 员只能添加开发 员,AppleID管 者等可以登 录iTunesConnected的 员。 注意:内部测试只适于开发者以及iTunesConnected的相关成员,这做详细介绍。
4. 添加外部测试, 先添加外部测试的构建版本。下 是具体步骤: 5. 构建版本添加成功后,开始添加外部测试 员。 6. 添加新测试员。添加电 邮件地址(可以 是AppleID的邮箱),以及测试 员信息即可。 添加外部测试 员成功后,如下图:
1.首先需要有一个淘宝账户,一般实名认证支付宝之后就可以入住开发者平台。 2.首先确定自己要对接的接口在哪一个应用下面,因为需要下载对应应用的sdk用来调用。确定好是哪一个应用之后创建相对应的应用。 3.创建好应用之后点击前面的sdk小图标会弹出sdk的下载页面,下载sdk保存到本地。在应用管理界面获取到appkey和appSrecet 4.获取code 获取code地址: response_type = code(必填) client_id = *(创建应用所对应的appkey) redirect_uri(创建应用写的回调地址) https://oauth.taobao.com/authorize?response_type=code&client_id=23580296&redirect_uri=http://www.baidu.com 回调成功之后 5.获取access_token 第一种通过代码获取
import java.io.IOException; import java.util.HashMap; import java.util.Map; import com.taobao.api.internal.util.WebUtils; //引用top sdk public class Access { public static void main(String[] args) { String url="https://oauth.taobao.com/token"; Map<String,String> props=new HashMap<String,String>(); props.put("grant_type","authorization_code"); /*测试时,需把test参数换成自己应用对应的值*/ props.put("code","F8qjHTLNqsDrmBAvWJFoVTID66409"); props.put("client_id","23580296"); props.put("client_secret","56bd3eef5b57bc793b1ca862c0655472"); props.put("redirect_uri","http://www.baidu.com"); props.put("view","web"); String s=""; try{s=WebUtils.doPost(url, props, 30000, 30000); System.out.println(s); }catch(IOException e){ e.printStackTrace();} } } 回示例:
{ “taobao_user_nick”: “%E4%B8%AD%E5%9B%BD%E9%80%9F%E5%B0%94%E7%89%A9%E6%B5%81”, “re_expires_in”: 0, “expires_in”: 86400, “expire_time”: 1482909750088, “r1_expires_in”: 1800, “w2_valid”: 1482823350088, “w2_expires_in”: 0, “taobao_user_id”: “1065192055”, “w1_expires_in”: 1800, “r1_valid”: 1482825150088, “r2_valid”: 1482823350088, “w1_valid”: 1482825150088, “r2_expires_in”: 0, “token_type”: “Bearer”, “refresh_token”: “6200905426610ZZ4db9b00010469dba88bac4b493d2ca8b1065192055”, “refresh_token_valid_time”: 1482823350088, “access_token”: “6200b052e5b48ZZ0669262fb573a0c47a7bf0aa708639a01065192055” }
一、C#获取对象的类类型方式
方式1.所有类隐式继承自Object,然而Object类中的GetType()就可以获取当前对象的类,对应的类型
// // 摘要: // 获取当前实例的 System.Type。 // // 返回结果: // 当前实例的准确运行时类型。 [SecuritySafeCritical] public Type GetType(); 方式2,使用typeof关键词 System.Type type3 = typeof(Student); 特别说明: 1.一个类的类型在进程内是唯一的。
2.可以用作线程锁使用
lock (this.GetType()) { } 实例验证: public static void TestOne() { Student stu1 = new Student() { ID = 1 }; Student stu2 = new Student() { ID = 2 }; //1.获取对象的类的类型 Type type1 = stu1.GetType(); Type type2 = stu2.GetType(); Console.WriteLine(Object.Equals(type1, type2));//输出:True Console.WriteLine(type1 == type2); //输出:True Console.
原文地址:http://www.linuxidc.com/Linux/2016-09/135521.htm
由于Linux目前很热门,越来越多的人在学习Linux,但是买一台服务放家里来学习,实在是很浪费。那么如何解决这个问题?虚拟机软件是很好的选择,常用的虚拟机软件有VMware Workstations和VirtualBox等。在使用虚拟机软件的时候,很多初学者都会遇到很多问题,而VMware的网络连接问题是大家遇到最多问题之一。在学习交流群里面,几乎每天都会有同学问到这些问题,写这篇详解也是因为群里童鞋网络出故障,然后在帮他解决的过程中,对自己的理解也做一个总结。接下来,我们就一起来探讨一下关于VMware Workstations网络连接的三种模式。
vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式)、NAT(网络地址转换模式)、Host-Only(仅主机模式)。
打开vmware虚拟机,我们可以在选项栏的“编辑”下的“虚拟网络编辑器”中看到VMnet0(桥接模式)、VMnet1(仅主机模式)、VMnet8(NAT模式),那么这些都是有什么作用呢?其实,我们现在看到的VMnet0表示的是用于桥接模式下的虚拟交换机;VMnet1表示的是用于仅主机模式下的虚拟交换机;VMnet8表示的是用于NAT模式下的虚拟交换机。
同时,在主机上对应的有VMware Network Adapter VMnet1和VMware Network Adapter VMnet8两块虚拟网卡,它们分别作用于仅主机模式与NAT模式下。在“网络连接”中我们可以看到这两块虚拟网卡,如果将这两块卸载了,可以在vmware的“编辑”下的“虚拟网络编辑器”中点击“还原默认设置”,可重新将虚拟网卡还原。
小伙伴看到这里,肯定有疑问,为什么在真机上没有VMware Network Adapter VMnet0虚拟网卡呢?那么接下来,我们就一起来看一下这是为什么。
一、Bridged(桥接模式) 什么是桥接模式?桥接模式就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。在桥接的作用下,类似于把物理主机虚拟为一个交换机,所有桥接设置的虚拟机连接到这个交换机的一个接口上,物理主机也同样插在这个交换机当中,所以所有桥接下的网卡与网卡都是交换模式的,相互可以访问而不干扰。在桥接模式下,虚拟机ip地址需要与主机在同一个网段,如果需要联网,则网关与DNS需要与主机网卡一致。其网络结构如下图所示:
接下来,我们就来实际操作,如何设置桥接模式。
首先,安装完系统之后,在开启系统之前,点击“编辑虚拟机设置”来设置网卡模式。
点击“网络适配器”,选择“桥接模式”,然后“确定”
在进入系统之前,我们先确认一下主机的ip地址、网关、DNS等信息。
然后,进入系统编辑网卡配置文件,命令为vi /etc/sysconfig/network-scripts/ifcfg-eth0
添加内容如下:
编辑完成,保存退出,然后重启虚拟机网卡,使用ping命令ping外网ip,测试能否联网。
能ping通外网ip,证明桥接模式设置成功。
那主机与虚拟机之间的通信是否正常呢?我们就用远程工具来测试一下。
主机与虚拟机通信正常。
这就是桥接模式的设置步骤,相信大家应该学会了如何去设置桥接模式了。桥接模式配置简单,但如果你的网络环境是ip资源很缺少或对ip管理比较严格的话,那桥接模式就不太适用了。如果真是这种情况的话,我们该如何解决呢?接下来,我们就来认识vmware的另一种网络模式:NAT模式。
在开发中有时候我们需要导出MS word文档。最近因为需要做一个生成word文件的功能。就将这块拿出来和大家分享。
生成word文件和我们写word文档是相同的概念,只不过在这里我们换成了用代码来操作。下面的例子中主要有添加页眉,页脚,正文(段落,表格)。在正文中,段落包含文字字体和背景的设置。表格主要是数据的填充和样式(有无边框)。这里写的例子给出的内容只是Java POI 方式生成word文件的极少数的一些方法,需要使用更多方法的还是要自己根据自己的需求去查看API。
看到很多小伙伴反应不能用的问题,这里我又重新把代码下载下来生成了一次试试。确实是没有问题。以前使用的是jdk6,最后一个版本使用的是jdk8.我再把我的maven导包情况贴出来。供大家参考,生成的文件MS office 和wps打开均没有问题。
<dependency> <groupId>org.apache.poi</groupId> <artifactId>ooxml-schemas</artifactId> <version>1.1</version> </dependency> <!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/org.apache.poi.xwpf.converter.core --> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>org.apache.poi.xwpf.converter.core</artifactId> <version>1.0.6</version> </dependency> 那就直接先上代码吧:
package com.seawater.controller; import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; import java.io.File; import java.io.FileOutputStream; import java.math.BigInteger; /** * Created by zhouhs on 2017/1/9. */ public class WordExportController { public static void main(String[] args)throws Exception { //Blank Document XWPFDocument document= new XWPFDocument(); //Write the Document in file system FileOutputStream out = new FileOutputStream(new File("
软交换是一种功能实体,为下一代网络NGN提供具有实时性要求的业务的呼叫控制和连接控制功能,是下一代网络呼叫与控制的核心。 简单地看,软交换是实现传统程控交换机的“呼叫控制”功能的实体,但传统的“呼叫控制”功能是和业务结合在一起的,不同的业务所需要的呼叫控制功能不同,而软交换是与业务无关的,这要求软交换提供的呼叫控制功能是各种业务的基本呼叫控制。 IMS即IP Multimedia Subsystem,中文意义为IP多媒体子系统,IMS解决方案相对于软交换的解决方案有着非常多的优势,在NGN市场正占据越来越重要的角色。截至2003年,国际权威标准组织普遍将IMS作为NGN网络融合以及业务和技术创新的核心标准。对于大规模商用部署而言,IMS从技术本身已足够成熟。IMS不仅可以实现最初的VoIP业务,更重要的是IMS将更有效地对网络资源、用户资源及应用资源进行管理,提高网络的智能,使用户可以跨越各种网络并使用多种终端,感受融合的通信体验。IMS作为一个通信架构,开创了全新的电信商业模式,拓展了整个信息产业的发展空间。 软交换是指利用把呼叫控制功能与媒体网关分开的方法来沟通公用电话交换网(PSTN)与IP电话(VoIP)的一种交换技术。
IMS在3GPPRelease 5版本中提出,是对IP多媒体业务进行控制的网络核心层逻辑功能实体的总称。3GPP R5主要定义IMS的核心结构,网元功能、接口和流程等内容:R6版本增加了部分IMS业务特性、IMS与其他网络的互通规范和无线局域网(WLAN)接入特性等;R7版本加强了对固定、移动融合的标准化制订,要求IMS支持数字用户线(xDSL)、电缆调制解调器等固定接入方式。
区别与联系:
软交换技术从1998年就开始出现并且已经历了实验、商用等多个发展阶段,目前已比较成熟。全球范围早已有多家电信运营商开展了软交换试验,发展至今,软交换技术已经具备了替代电路交换机的能力,并具备一定的宽带多媒体业务能力。在软交换技术已发展如此成熟的今天,IMS的出路在何方?又该如何发展和定位呢?首先需要对IMS和软交换进行较为全面的比较和分析。
如果从采用的基础技术上看,IMS和软交换有很大的相似性:都是基于IP分组网;都实现了控制与承载的分离;大部分的协议都是相似或者完全相同的;许多网关设备和终端设备甚至是可以通用的。
IMS和软交换最大的区别在于以下几个方面。
(1)在软交换控制与承载分离的基础上,IMS更进一步的实现了呼叫控制层和业务控制层的分离;
(2)IMS起源于移动通信网络的应用,因此充分考虑了对移动性的支持,并增加了外置数据库——归属用户服务器(HSS),用于用户鉴权和保护用户业务触发规则;
(3)IMS全部采用会话初始协议(SIP)作为呼叫控制和业务控制的信令,而在软交换中,SIP只是可用于呼叫控制的多种协议的一种,更多的使用媒体网关协议(MGCP)和H.248协议。
总体来讲,IMS和软交换的区别主要是在网络构架上。软交换网络体系基于主从控制的特点,使得其与具体的接入手段关系密切,而IMS体系由于终端与核心侧采用基于IP承载的SIP协议,IP技术与承载媒体无关的特性使得IMS体系可以支持各类接入方式,从而使得IMS的应用范围从最初始的移动网逐步扩大到固定领域。此外,由于IMS体系架构可以支持移动性管理并且具有一定的服务质量(QoS)保障机制,因此IMS技术相比于软交换的优势还体现在宽带用户的漫游管理和QoS保障方面。
转载于:https://www.cnblogs.com/yuhuameng/p/6264686.html
开始在使用Maven时,总是会听到nexus这个词,一会儿maven,一会儿nexus,当时很是困惑,nexus是什么呢,为什么它总是和maven一起被提到呢? 我们一步一步来了解吧。
一、了解Maven,Maven用来干什么呢 1. 优秀的构建工具 通过简单的命令,能够完成清理、编译、测试、打包、部署等一系列过程。同时,不得不提的是,Maven是跨平台的,无论是在Windows、还是在Linux或Mac上,都可以使用同样的命令。
2. 依赖管理工具 项目依赖的第三方的开源类库,都可以通过依赖的方式引入到项目中来。代替了原来需要首先下载第三方jar,再加入到项目中的方式。从而更好的解决了合作开发中依赖增多、版本不一致、版本冲突、依赖臃肿等问题。
具体是怎么实现的呢?Maven通过坐标系统准确的定位每一个构件,即通过坐标找到对应的Java类库。
3. 项目信息管理工具 能够管理项目描述、开发者列表、版本控制系统地址、许可证等一些比较零散的项目信息。除了直接的项目信息,通过Maven自动生成的站点,以及一些已有的插件,还能够轻松获得项目文档、测试报告、静态分析报告、源码版本、日志报告等非常具有价值的项目信息。
二、 Maven与Nexus 这个问题从Maven的第二个用处说起,依赖管理,通过在Pom中指定坐标的形式将jar引入到项目中。那这个过程,要经历怎样一个流程呢?从哪里寻找jar?下载的jar放到哪里?
将这个问题顺下来,就知道nexus和maven的关系了。
从哪里找到jar?项目用到的jar又存放在哪里?这引出了仓库的概念,maven通过仓库来统一管理各种构件。Maven的仓库分为本地仓库和远程仓库。
当Maven根据坐标寻找构件时,它首先会查看本地仓库,如果本地仓库存在此构件,则直接使用;如果本地仓库不存在此构件,或者需要查看是否有更新的构件版本,Maven会去远程仓库查找,发现需要的构件之后,下载到本地仓库再使用。
到了这里,问题的答案也就出来了。
首先,Nexus是一种远程仓库,根据上段的介绍,我们已经知道远程仓库的作用。在远程仓库中,默认的是中央仓库,中央仓库是Maven核心自带的远程仓库。那就使用中央仓库不就得了吗,为什么我们要安装Nexus呢?
我们从项目实际开发来看:
1.一些无法从外部仓库下载的构件,例如内部的项目还能部署到私服上,以便供其他依赖项目使用。
2. 为了节省带宽和时间,在局域网内架设一个私有的仓库服务器,用其代理所有外部的远程仓库。当本地Maven项目需要下载构件时,先去私服请求,如果私服没有,则再去远程仓库请求,从远程仓库下载构件后,把构件缓存在私服上。这样,及时暂时没有Internet链接,由于私服已经缓存了大量构件,整个项目还是可以正常使用的。同时,也降低了中央仓库的负荷。
Nexus仅仅是私服的一种。
Maven的pom.xml介绍 6.1 简介 pom.xml文件是Maven进行工作的主要配置文件。在这个文件中我们可以配置Maven项目的groupId、artifactId和version等Maven项目必须的元素;可以配置Maven项目需要使用的远程仓库;可以定义Maven项目打包的形式;可以定义Maven项目的资源依赖关系等等。对于一个最简单的pom.xml的定义必须包含modelVersion、groupId、artifactId和version这四个元素,当然这其中的元素也是可以从它的父项目中继承的。在Maven中,使用groupId、artifactId和version组成groupdId:artifactId:version的形式来唯一确定一个项目。
6.2 pom.xml的继承、聚合与依赖 我们知道Maven在建立项目的时候是基于Maven项目下的pom.xml进行的,我们项目依赖的信息和一些基本信息都是在这个文件里面定义的。那如果当我们有多个项目要进行,这多个项目有些配置内容是相同的,有些是要彼此关联的,那如果按照传统的做法的话我们就需要在多个项目中都定义这些重复的内容。这无疑是非常耗费时间和不易维护的。好在Maven给我们提供了一个pom的继承和聚合的功能。
对于使用java的人而言,继承这个词大家应该都不陌生。要继承pom就需要有一个父pom,在Maven中定义了超级pom.xml,任何没有申明自己父pom.xml的pom.xml都将默认继承自这个超级pom.xml。
先来看一下这个超级pom.xml的定义:
Xml代码 <project> <modelVersion>4.0.0</modelVersion> <name>Maven Default Project</name> <repositories> <repository> <id>central</id> <name>Maven Repository Switchboard</name> <layout>default</layout> <url>http://repo1.maven.org/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>central</id> <name>Maven Plugin Repository</name> <url>http://repo1.maven.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> <releases> <updatePolicy>never</updatePolicy> </releases> </pluginRepository> </pluginRepositories> <build> <directory>${project.basedir}/target</directory> <outputDirectory>${project.build.directory}/classes</outputDirectory> <finalName>${project.artifactId}-${project.version}</finalName> <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory> <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory> <!-- TODO: MNG-3731 maven-plugin-tools-api < 2.4.4 expect this to be relative... --> <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory> <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory> <resources> <resource> <directory>${project.basedir}/src/main/resources</directory> </resource> </resources> <testResources> <testResource> <directory>${project.
一、线索二叉树原理 前面介绍二叉树原理及特殊二叉树文章中提到,二叉树可以使用两种存储结构:顺序存储和二叉链表。在使用二叉链表的存储结构的过程中,会存在大量的空指针域,为了充分利用这些空指针域,引申出了“线索二叉树”。回顾一下二叉链表存储结构,如下图: 通过观察上面的二叉链表,存在着若干个没有指向的空指针域。对于一个有n个节点的二叉链表,每个节点有指向左右节点的2个指针域,整个二叉链表存在2n个指针域。而n个节点的二叉链表有n-1条分支线,那么空指针域的个数=2n-(n-1) = n+1个空指针域,从存储空间的角度来看,这n+1个空指针域浪费了内存资源。 从另外一个角度来分析,如果我们想知道按中序方式遍历二叉链表时B节点的前驱节点或者后继节点时,必须要按中序方式遍历二叉链表才能够知道结果,每次需要结果时都需要进行一次遍历,是否可以考虑提前存储这种前驱和后继的关系来提高时间效率呢? 综合以上两方面的分析,可以通过充分利用二叉链表中的空指针域,存放节点在某种遍历方式下的前驱和后继节点的指针。 我们把这种指向前驱和后继的指针成为线索,加上线索的二叉链表成为线索链表,对应的二叉树就成为“线索二叉树(Threaded Binary Tree)” 。 二、构建线索二叉树过程 1、我们对二叉树进行中序遍历(不了解二叉树遍历请参考二叉树及特殊二叉树介绍),将所有的节点右子节点为空的指针域指向它的后继节点。如下图: 通过中序遍历我们知道H的right指针为空,并且H的后继节点为D(如上图第1步),I的right指针为空,并且I的后继节点为B(如上图第2步),以此类推,知道G的后继节点为null,则G的right指针指向null。 2、接下来将这颗二叉树的所有节点左指针域为空的指针域指向它的前驱节点。如下图: 如上图,H的left指针域指向Null(如第1步),I的前驱节点是D,则I的left指针指向D,以此类推。 通过上面两步完成了整个二叉树的线索化,最后结果如下图: 通过观察上图(蓝色虚线代表后继、绿色虚线代表前驱),可以看出,线索二叉树,等于是把一棵二叉树转变成了一个“ 特殊的双向链表“(后面会解释为什么叫特殊的双向链表),这样对于我们的新增、删除、查找节点带来了方便。所以我们对二叉树以某种次序遍历使其变为线索二叉树的过程称做是线索化。如下图: 仔细分析上面的双向链表,与线索化之后的二叉树相比,比如节点D与后继节点I,在完成线索化之后,并没有直接线索指针,而是存在父子节点的指针;节点A与节点F,在线索化完成之后,节点A并没有直接指向后继节点F的线索指针,而是通过父子节点遍历可以找到最终的节点F,前驱节点也存在同样的问题,正因为很多节点之间不存在直接的线索,所以我将此双向链表称做“ 特殊的双向链表”,再使用过程中根据指针是线索指针还是子节点指针来分别处理,所以在每个节点需要标明当前的左右指针是线索指针还是子节点指针,这就需要修改节点的数据结构。修改后的数据结构如下: class Node { String data; //数据域 Node left; //左指针域 Node right; //右指针域 byte leftType; //左指针域类型 0:指向子节点、1:前驱或后继线索 byte rightType; //右指针域类型 0:指向子节点、1:前驱或后继线索 } 最终的二叉链表修改为如下图的样子: 三、线索二叉树的代码(Java版) 下面是中序线索化二叉树的实现代码:
/** * @Title: 二叉树相关操作 * @Description: * @Author: Uncle Ming * @Date:2017年1月6日 下午2:49:14 * @Version V1.0 */ public class ThreadBinaryTree { private Node preNode; //线索化时记录前一个节点 //节点存储结构 static class Node { String data; //数据域 Node left; //左指针域 Node right; //右指针域 boolean isLeftThread = false; //左指针域类型 false:指向子节点、true:前驱或后继线索 boolean isRightThread = false; //右指针域类型 false:指向子节点、true:前驱或后继线索 Node(String data) { this.
int4 和 int8 分享一个小知识 看别人视频时听到int4就是一个四字节的int 遂心生疑惑 难道int8就是8字节吗 所以仔细查了一下 int4其实时默认四位 不足四位 补零 。for example 表示一个1 为 0001 。当然 同样表示一个1 加上FILL ZERO之后 int4和int8无区别 。
回调函数应该和设计相关而不是和语言相关。
在分层设计中,高层次的模块会叫低层次的模块做一些事情,通常是通过函数调用。 从设计上来说,低层次的模块不应该直接调用高层次模块的函数。
所以高层次模块在叫低层模块做事的时候会注册一个回调函数给低层模块,然后低层模块做完了就调用这个函数。表现在C语言上是个函数指针
调用(calling)机制从汇编时代起已经大量使用:准备一段现成的代码,调用者可以随时跳转至此段代码的起始地址, 执行完后再返回跳转时的后续地址。 CPU为此准备了现成的调用指令,调用时可以压栈保护现场,调用结束后从堆栈中弹出现场地址,以便自动返回。借堆栈保护现场真是一项绝妙的发明,它使调用者和被调者可以互不相识,于是才有了后来的函数和构件,使吾辈编程者如此轻松愉快。若评选对人类影响最大之发明,在火与车轮之后,笔者当推压栈调用。 话虽这样说,此调用机制并非完美。回调函数就是一例。 函数之类本是为调用者准备的美餐,其烹制者应对食客了如指掌,但实情并非如此。 例如,写一个快速排序函数供他人调用,其中必包含比较大小。麻烦来了: 此时并不知要比较的是何类数据--整数、浮点数、字符串?于是只好为每类数据制作一个不同的排序函数。 更通行的办法是在函数参数中列一个回调函数地址,并通知调用者:君需自己准备一个比较函数,其中包含两个指针类参数,函数要比较此二指针所指数据之大小,并由函数返回值说明比较结果。 排序函数借此调用者提供的函数来比较大小,借指针传递参数,可以全然不管所比较的数据类型。被调用者回头调用调用者的函数(够咬嘴的),故称其为回调(callback)。 回调函数使程序结构乱了许多。Windows API 函数集中有不少回调函数,尽管有详尽说明,仍使初学者一头雾水。恐怕这也是无奈之举。无论何种事物,能以树形结构单向描述毕竟让人舒服些。如果某家族中孙辈又是某祖辈的祖辈,恐怕无人能理清其中的头绪。但数据处理之复杂往往需要构成网状结构,非简单的客户/服务器关系能穷尽。 Windows 系统还包含着另一种更为广泛的回调机制,即消息机制。消息本是 Windows 的基本控制手段,乍看与函数调用无关,其实是一种变相的函数调用。发送消息的目的是通知收方运行一段预先准备好的代码,相当于调用一个函数。 消息所附带的 WParam 和 LParam 相当于函数的参数,只不过比普通参数更通用一些。应用程序可以主动发送消息,更多情况下是坐等 Windows 发送消息。一旦消息进入所属消息队列,便检感兴趣的那些,跳转去执行相应的消息处理代码。 操作系统本是为应用程序服务,由应用程序来调用。而应用程序一旦启动,却要反过来等待操作系统的调用。这分明也是一种回调,或者说是一种广义回调。其实,应用程序之间也可以形成这种回调。假如进程 B 收到进程 A 发来的消息,启动了一段代码,其中又向进程 A 发送消息,这就形成了回调。这种回调比较隐蔽,弄不好会搞成递归调用,若缺少终止条件,将会循环不已,直至把程序搞垮。若是故意编写成此递归调用,并设好终止条件,倒是很有意思。但这种程序结构太隐蔽,除非十分必要,还是不用为好。 利用消息也可以构成狭义回调。上面所举排序函数一例,可以把回调函数地址换成窗口handle。如此,当需要比较数据大小时,不是去调用回调函数,而是借 API 函数 SendMessage 向指定窗口发送消息。收到消息方负责比较数据大小,把比较结果通过消息本身的返回值传给消息发送方。所实现的功能与回调函数并无不同。当然,此例中改为消息纯属画蛇添脚,反倒把程序搞得很慢。但其他情况下并非总是如此,特别是需要异步调用时,发送消息是一种不错的选择。 假如回调函数中包含文件处理之类的低速处理,调用方等不得,需要把同步调用改为异步调用,去启动一个单独的线程,然后马上执行后续代码,其余的事让线程慢慢去做。一个替代办法是借 API 函数 PostMessage发送一个异步消息,然后立即执行后续代码。这要比自己搞个线程省事许多,而且更安全。 如今我们是活在一个 object 时代。只要与编程有关,无论何事都离不开 object。但 object 并未消除回调,反而把它发扬光大,弄得到处都是,只不过大都以事件(event)的身份出现,镶嵌在某个结构之中,显得更正统,更容易被人接受。应用程序要使用某个构件,总要先弄清构件的属性、方法和事件,然后给构件属性赋值,在适当的时候调用适当的构件方法,还要给事件编写处理例程,以备构件代码来调用。何谓事件?它不过是一个指向事件例程的地址,与回调函数地址没什么区别。 不过,此种回调方式比传统回调函数要高明许多。首先,它把让人不太舒服的回调函数变成一种自然而然的处理例程,使编程者顿觉气顺。再者,地址是一个危险的东西,用好了可使程序加速,用不好处处是陷阱,程序随时都会崩溃。现代编程方式总是想法把地址隐藏起来(隐藏比较彻底的如 VB 和 Java),其代价是降低了程序效率。事件例程使编程者无需直接操作地址,但并不会使程序减速。更妙的是,此一改变,本是有损程序结构之奇技怪巧变成一种崭新设计理念,不仅免去被人抨击,而且逼得吾等凡人净手更衣,细细研读,仰慕至今。只是偶然静心思虑,发觉不过一瓶旧酒而已,故引得此番议论,让诸君见笑了。 事件驱动程序设计是围绕着消息基础形成的,发生一个事件,伴随着一大堆的消息。我理解“回调机制”是window 在执行某个API函数的过程中,调用指定的一个函数。我们可以模拟一下: 假设 ms 提供一个函数叫做 EnumFont ,该函数是得到所有的字体,假设它的实现是 EnumFont() { while ( (f =FindNextFont()) !=NULL) { printf("fontname: "
日常工作中用到的一些常规的性能优化方式总结。希望对大家有用!欢迎学习交流!
一、App启动优化 App启动简单流程 1 . 加载并启动app 2 . 创建空白窗口,为了让用户感觉秒开(默认为白色) 3 . 创建app进程 4 . 创建主activity 5 . 加载布局、绘制 APP执行时长检测方式 方式一 、 app启动时长检测 – adb 命令检测 // 启动一次 adb shell am start -W -n com.package/.activity.MyActivity // 启动多次 adb shell am start -S -R 10 -W com.package/.activity.MyActivity(启动十次) Activity: com.mediatek.wwtv.tvcenter/.nav.TurnkeyUiMainActivity ThisTime: 678 (表示一连串启动Activity 的最后一个 Activity 的启动耗时) TotalTime: 678 (一系列activity启动时间,一般只关注这项) WaitTime: 915 (总的耗时,包括app冷启动时加载进程的时候) 方式二、 代码执行时长检测 – MethodTracing 第一步、在项目代码里埋下需要追踪的代码块
@Override protected void onCreate(Bundle savedInstanceState) { super.
前台页面:
<div id="search01" style="padding:2px 5px;">
合同编号: <input class="easyui-textbox" style="width:80px" id="key_CCode"> 单位名称: <input class="easyui-textbox" style="width:80px" id="key_JiGouMingChen"> 健康顾问: <input class="easyui-textbox" style="width:90px" id="key_jkgw">
体检日期: <input class="easyui-datebox" style="width:90px" id="key_tjrqA">—<input class="easyui-datebox" style="width:90px" id="key_tjrqB">  <br /> 收款日期: <input class="easyui-datebox" style="width:90px" id="key_skrqA">—<input class="easyui-datebox" style="width:90px" id="key_skrqB">   <a href="#" class="easyui-linkbutton" iconCls="icon-sum" style="width:120px" OnClick="$('#list_gd_02').datagrid('load');">查询</a> <a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-redo',plain:true" style="float:right;" οnclick="exportPDF();">导出到PDF</a> <br/>
<font style="line-height:32px;">
应收金额(所有工单之和):<input class="easyui-numberbox" style="width:90px" id="ysMoney" value="0.00" data-options="precision:2" readonly> 元
已收金额(所有已收):<input class="easyui-numberbox" style="width:90px" id="ssMoney" value="0.00" data-options="precision:2" readonly> 元
一,老样子先给出效果对比图 可以看出,滚动条控制canny算子的阈值来达到边缘检测的目的 二,再贴出代码 #include<opencv2\opencv.hpp>
using namespace cv;
//需求:创建滚动条,边缘检测
IplImage* src;
IplImage* dst;
const char* winname;
const char* stackbarname;
void stackbar(int threshold)
{
cvCanny(src, dst, threshold, threshold * 2, 3);
cvShowImage(winname, dst);
}//注意:回调函数要写在主函数之前,不然就会报错:cvCreateTrackbar函数的参数stackbar未标识
int main()
{
src = cvLoadImage("D:\\111.jpg", 0);
dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
winname = "我是创建的窗口";
stackbarname = "滚动条";
cvNamedWindow(winname, CV_WINDOW_AUTOSIZE);
//滚动条函数
int value = 33;
cvCreateTrackbar(stackbarname, winname, &value, 150, stackbar);
stackbar(33);
cvWaitKey(0); return 0;
} 三,中流砥柱 难点在几个函数 (1)cvCreateTrackbar(滚动条名称, 窗口名称, &当前位置, 总长度, 回调函数); 说明:滚动条每一次被挪动,就会调用一次回调函数stackbar(); (2)cvCanny(输入图像, 输出图像, 低阈值, 高阈值, 模板大小); 四,仍然不理解之处 我在cvWaitKey(0);后,加入了cvReleaseImage(&src);却出现下图的情况, 但是我加入cvDestroyAllWindows();,却是ok的,希望有大神给我讲讲!
前言: mybatis-generator是根据配置文件中我们配置的数据库连接参数自动连接到数据库并根据对应的数据库表自动的生成与之对应mapper映射(比如增删改查,选择性增删改查等等简单语句)文件、对应的dao接口文件以及对应的entity实体(bean) 问题解决:1、如果遇到“不能有前言”的错误,请将配置文件重新保存为UTF-8(不包含BOM)文字编码的文件 一、首先,我们需要引入所需要的jar包 1、mybatis-generator所需的jar包 mybatis-generator-core-1.3.5.jar (mybatis-generator-core的版本可以自行选择)
mybatis-generator下载地址:https://github.com/mybatis/generator/releases
2、数据库连接jar包 根据自己的需要选择数据库驱动
oracle的驱动:ojdbc6.jar
mysql驱动:mysql-connector-java.jar
postgre驱动:postgresql-9.3-1102.jdbc4.jar
使用postgre进行举例
二、Mybatis-Generator配置文件详解 1、xml配置文件头 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!--这里写配置--> </generatorConfiguration> 2、指定数据库驱动包位置 以ojdbc6.jar为例,支持zip和jar两种文件格式 <!-- 指定数据连接驱动jar地址 --> <!-- <classPathEntry location="${classPath}" /> --> <classPathEntry location="D:\Repository\Publish\ojdbc6.jar" /> 3、数据库连接参数和自动生成参数配置 一个完整的配置实例: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- 指定数据连接驱动jar地址 --> <classPathEntry location="E:\mybatis-generator\postgresql-9.3-1102.jdbc4.jar" /> <context id="SqlTables" targetRuntime="MyBatis3"> <!-- 注释 --> <commentGenerator> <property name="
集合 A 的内部是A的最大开子集,同样地,我们也能构造一个包含 A 的最小闭集,这个集合就成为A的闭包(closure)并用 cl(A) 或 A¯ 表示。
定义5 令 A⊂Rn ,集合 cl(A) 定义成所有包含 A 的闭集之交(所以根据定理3(ii)可得 cl(A) 也是闭的)。
例如 R1 中, cl((0,1])=[0,1] ,另外注意 A 是闭集当且仅当cl(A)=A,
定理5 令 A⊂Rn ,那么 cl(A) 由 A 加上所有A的聚点组成。
换句话说,,为了求出集合 A 的闭包,我们需要A加上所有不在 A 中的聚点,根据前面给出的实例,定理5在直观上比较明显。
例1:找出 R 中A=[0,1)∪{2}的闭包。
解: 该集合的聚点是[0,1],所以闭包是 [0,1]∪{2} ,这很明显是包含 A 的最小闭集。
例2:对于任意 A⊂Rn ,说明 Rn∖cl(A) 是开集。
解: cl(A) 是闭集,那么它的补是开集。
例3: cl(A∩B)=cl(A)∩cl(B) 成立吗?
解: 答案为否。例如令 A=[0,1],B=(1,2] ,那么 A∩B=∅ 并且 cl(A)∩cl(B)={1} 。
# html中 # 增加这个div,用来提示。你可以设置自己想要的样式 <div id="doing"></div> // js 中 $.ajax({ url:url, type:'post', data:{'type':b_type,'moneyCount':moneyCount,'shoplen':shoplen}, timeout:15000, // 请求发送之前(发送请求前可修改XMLHttpRequest对象的函数,如添加自定义HTTP头。)。 beforeSend:function(XMLHttpRequest){ $("#doing").html("正在处理,请稍后···"); }, // 请求成功后的回调函数 success:function(data,textStatus){ var result = JSON.parse(data); if(result.code == 1){ $('#qr_code').show(1500); $('#qr_code').attr('src',result.data); $('.payment_but').hide(); }else{ alert(result.msg); } }, // 请求完成后的回调函数 (请求成功或失败之后均调用) complete:function(XMLHttpRequest,textStatus){ $("#doing").empty(); }, // 请求失败时调用此函数。 error:function(XMLHttpRequest,textStatus,errorThrown){ $("#doing").empty(); } }); 参考: http://www.w3school.com.cn/jquery/ajax_ajax.asp w3school
scrapy-redis安装及配置
scrapy-redis 的安装 pip install scrapy-redis
easy_install scrapy-redis
下载
http://redis.io/download
版本推荐
stable 3.0.2
运行redis
redis-server redis.conf
清空缓存
redis-cli flushdb
scrapy配置redis settings.py配置redis(在scrapy-redis 自带的例子中已经配置好)
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderPriorityQueue'
REDIS_URL = None # 一般情况可以省去
REDIS_HOST = '127.0.0.1' # 也可以根据情况改成 localhost
REDIS_PORT = 6379
在scrapy中使用scrapy-redis spider 继承RedisSpider
class tempSpider(RedisSpider) name = "temp"
redis_key = ''temp:start_url"
启动redis 在redis的src目录下,执行 ./redis-server启动服务器
执行 ./redis-cli 启动客户端
设置好setting.py的redis 的ip和端口 启动scropy-redis的代码;
如启动name= "lhy",start_urls="lhy:start_urls" 的spider。
如果在redis中没有 主键为lhy:start_urls 的list,则爬虫已只监听等待。
VS默认设置下编写jQuery代码是这样的:
解决办法:
1、在项目的“管理NuGet程序包”中安装JQuery:
2、打开:工具 -> 选项 -> 文本编辑器 -> JavaScript -> IntelliSence -> 引用;会弹出如下窗口:
3、将 “引用组” 设置为:Implicit(Web);默认是:Implicit(Windows),在该引用组下设置无效,必须在Web引用组下设置。
4、然后点击 “将引用添加到当前组” 右边的按钮,会弹出一个文本选择框,将之前安装好的JQuery文件拷贝到打开的文件夹下(在VS的安装路径下)【其实随便找个jQuery拷贝到References目录即可,不一定需要通过第一步来安装】。注意,要拷贝完整.js文件,不要拷贝.min.js文件。然后点击“打开”。
5、此时,JQuery文件已经添加到“包含的文件”中。最后点击“确定”就OK了。
转载于:https://www.cnblogs.com/Arlar/p/6248345.html
原来的eclipse转换到android studio上使用,并且需要调用第三方的aar库。编译apk能成功,但是运行时调用aar库创建对象的时候出现了class no found异常,提示aar库中的类找不到。由于aar库已经在另外一个工程中调用成功过,初步判断可能是编译参数的问题。但是对比sdk版本、编译版本都一致。只能重新创建一个demo,测试调用aar库成功,再把原工程的build.gradle配置同步过去,看看是哪个配置项导致出错。最终定位到时调用一个class.jar库导致的,而aar库中同样有一个class.jar文件,调用的接口就在class.jar文件中。应该是由于库文件重名导致调用的时候调用了外部的class.jar,而没有调用aar库中的class.jar。
翻译源址:http://commons.apache.org/proper/commons-math/userguide/index.html
1、math包版本3.6
2、commons-math包解决哪些问题
math包由一组数据和统计的包组成,用于解决列表中列出的问题。列表虽不能覆盖math包全部的功能,但可以基本说明math包所能提供的方法。
计算一组数据的均值、方差,还有其他统计类指标。使用线性回归将线拟合到一组数据点
将曲线拟合到一组数据点
找到通过点集合的平滑曲线(插值)
使用最小二乘法将参数模型拟合到一组测量
求解涉及实值函数的方程(即根查找)
求解线性方程组
求解常微分方程
最小化多维函数
生成具有比使用JDK的可能性更多的限制(例如分布,范围)的随机数
生成跟输入文件中的数据相似的随机样本或数据集
统计检验其他数学函数如阶乘,二项式系数和“特殊函数”(例如伽马,β函数) 3、commons-math包讲解 org.apache.commons.math3.analysis---根查找,积分,插值,多项式
org.apache.commons.math3.complex---复数
org.apache.commons.math3.dfp---十进制浮点数
org.apache.commons.math3.distribution---概率分布
org.apache.commons.math3.fitting---曲线拟合
org.apache.commons.math3.fraction---有理数
org.apache.commons.math3.genetics---遗传算法
org.apache.commons.math3.geometry---何(欧几里德空间和二进制空间分区)
org.apache.commons.math3.linear---矩阵,求解线性系统
org.apache.commons.math3.ml---机器学习
org.apache.commons.math3.ode---普通微分方程积分
org.apache.commons.math3.optim---函数最大化还是最小化
org.apache.commons.math3.random---随机数,字符串和数据生成
org.apache.commons.math3.special---特殊函数(Gamma,Beta)
org.apache.commons.math3.stat---统计,统计检验
org.apache.commons.math3.transform---变换(傅立叶)
org.apache.commons.math3.util---通用数据或统计函数