SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
会话已更改。
SQL> SELECT TO_DATE('2006-05-01 19:25:34', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
TO_DATE('2006-05-01 ------------------- 2006-05-01 19:25:34
SQL> SELECT TO_DATE('2006-05-01 19:25', 'YYYY-MM-DD HH24:MI') FROM DUAL;
TO_DATE('2006-05-01 ------------------- 2006-05-01 19:25:00
SQL> SELECT TO_DATE('2006-05-01 19', 'YYYY-MM-DD HH24') FROM DUAL;
TO_DATE('2006-05-01 ------------------- 2006-05-01 19:00:00
SQL> SELECT TO_DATE('2006-05-01', 'YYYY-MM-DD') FROM DUAL;
TO_DATE('2006-05-01 ------------------- 2006-5-1
SQL> SELECT TO_DATE('2006-05', 'YYYY-MM') FROM DUAL;
TO_DATE('2006-05',' ------------------- 2006-5-1
SQL> SELECT TO_DATE('2006', 'YYYY') FROM DUAL;
个人感受 天下代码为我所用. 有时网上会有各种各样实现的代码,如Java,PHP,C++, 开发的一种快速的境界便是拿来主义. 现在看看如何在C#中调用Java的方法吧。 总得来说,就是把Java的打包文件,变成Dll, 然后为 C#所用。 牛! ================== C#调用Java类的方法 博客分类: 其它 C C++ C# Java Linq 一、将已经编译后的java中Class文件进行打包;打包命令JAR 如:将某目录下的所有class文件夹全部进行打包处理;
使用的命令:jar cvf test.jar -C com/ .
其中test.jar为要生成的jar包;com/ . 为指定的当前目录下的文件夹,该文件夹包括子文件夹及class文件;
二、到IKVM官方网站下载IKVM需要的组件 http://www.ikvm.net/ ikvm-0.42.0.3.zip ikvmbin-0.42.0.3.zip openjdk6-b16-stripped.zip 三、设置路径 解压ikvm-0.42.0.3.zip,并将%IKVM_HOME%\bin添加到path中。此处的%IKVM_HOME%是指解压后ikvm的主目录。
四、将java的jar包转换为.dll控件 使用的命令:ikvmc -out:IKVM.dll test.jar
其中IKVM.dll为将要生成的.dll控件文件名;test.jar为之前打包好的jar包文件。
五、在C#项目中添加所需的控件 1、新建一个C#.NET项目,首先添加一下必须的DLLs %IKVM_HOME%\bin\IKVM.OpenJDK.Core.dll %IKVM_HOME%\bin\IKVM.Runtime.dll %IKVM_HOME%\bin\IKVM.Runtime.JNI.dll 2、添加已生成的.dll文件
将之前生成好的.dll文件加载到C#项目中
六、测试 在C#项目中使用java类,其方法同java。但对包的引用使用C#的语法using
源代码: Java源代码: package com.zht;
//要调用的Java类 public class Test {
//要调用的Java方法 public String returnString() {
return "Hello, zht!";
}
}
在Android系统中,Activity和Service是应用程序的核心组件,它们以松藕合的方式组合在一起构成了一个完整的应用程序,这得益于应用程序框架层提供了一套完整的机制来协助应用程序启动这些Activity和Service,以及提供Binder机制帮助它们相互间进行通信。在前面的文章Android进程间通信(IPC)机制Binder简要介绍和学习计划和Android系统在新进程中启动自定义服务过程(startService)的原理分析中,我们已经系统地介绍了Binder机制和Service的启动过程了,在本文中,简要介绍Activity的启动过程以及后续学习计划。
《Android系统源代码情景分析》一书正在进击的程序员网(http://0xcc0xcd.com)中连载,点击进入!
在Android系统中,有两种操作会引发Activity的启动,一种用户点击应用程序图标时,Launcher会为我们启动应用程序的主Activity;应用程序的默认Activity启动起来后,它又可以在内部通过调用startActvity接口启动新的Activity,依此类推,每一个Activity都可以在内部启动新的Activity。通过这种连锁反应,按需启动Activity,从而完成应用程序的功能。
这里,我们通过一个具体的例子来说明如何启动Android应用程序的Activity。Activity的启动方式有两种,一种是显式的,一种是隐式的,隐式启动可以使得Activity之间的藕合性更加松散,因此,这里只关注隐式启动Activity的方法。
首先在Android源代码工程的packages/experimental目录下创建一个应用程序工程目录Activity。关于如何获得Android源代码工程,请参考在Ubuntu上下载、编译和安装Android最新源代码一文;关于如何在Android源代码工程中创建应用程序工程,请参考在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务一文。这里,工程名称就是Activity了,它定义了一个路径为shy.luo.activity的package,这个例子的源代码主要就是实现在这里了。下面,将会逐一介绍这个package里面的文件。
应用程序的默认Activity定义在src/shy/luo/activity/MainActivity.java文件中:
package shy.luo.activity; import shy.luo.activity.R; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private final static String LOG_TAG = "shy.luo.activity.MainActivity"; private Button startButton = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); startButton = (Button)findViewById(R.id.button_start); startButton.setOnClickListener(this); Log.i(LOG_TAG, "Main Activity Created."); } @Override public void onClick(View v) { if(v.equals(startButton)) { Intent intent = new Intent("
产品负责人PO与团队的互动一直是一个难题。典型的问题在于:敏捷开发倡导“迭代期内无变更”以换取“团队承诺”,而实际上产品负责人却会不断地来提变更,打乱开发计划了。我们应该怎么办呢?产品负责人说“敏捷就是拥抱变化,我现在来提变化了,你们却关门了。”团队说“如果你总是变,下次我们怎么给你承诺。”
敏捷开发中的计划跟踪生态II大致如此(黑体字即图片中的元素):
产品负责人(PO)与团队的正确互动是自组织团队正常运转的核心机制之一。
☺ 产品负责人的权利是统一管理和讲解需求以及需求优先级排序,而义务则是接受开发团队的估算,并承诺迭代期内不变更。
☺ 团队的权利在于开发人员自己估算,而义务则是接受产品负责人所设定的需求内容、实现标准、优先级排序,并对自己的估算做出团队承诺,这种承诺会造成整个团队受到激励。
☺ 产品负责人不能干预团队的估算,却可以挑战估算。挑战估算可以通过对比两个团队处理同类任务、对比以往同类任务与本次任务等方式进行。团队的荣誉感会令团队产生团队间的同行压力(与其他团队及与自己的过去相比),并进而产生受激励的个体。
☺ 作为自组织团队,产品负责人与团队互相没有领导关系,却通过分权与承诺管理,使得两者互相管理,从而产生更高的工作效率。
需求优先级排序-迭代期内无变更-团队承诺是这个生态的主线之一。
让我们重新看一下前面变与不变的例子。
简单粗暴的方法包括“一个强制性的变更或不变更制度”。即在高层领导的支持下(如果他们不支持,大家就放弃敏捷开发,你们说怎么办就怎么办,但别再提敏捷开发了!),团队坚持每个迭代都不变更。这个听起来很简单,但实际操作是有难度的。毕竟变更经常来自客户,团队怕产品负责人,所以搬出高层领导;产品负责人怕高层领导,会搬出客户。
另一种细腻一点的方法是制定一个“何为需求变更何为需求细化”的指南。毕竟有时候提前想的是一件事情,但具体做的时候才发现应该做成另外一个样子。难道大家真的应该二话不说先把错误的东西做出来,到下一个迭代再变更?这不是纯粹和自己较劲么。所以兴许我们不会把任务扔掉,但是却可以把任务的描述改动一下,作为“细化”来接受。这种指南有其现实意义,但万勿当作法律条文来办,因为很快就会发现有处于模糊状态的东西会引发争议。
其实终极解决方案,是顺着图中的线条向下看:团队承诺-迭代期内无变更-需求优先级排序。最后一个才是重点。
有几种原因会导致迭代期内变更,一种是发现了紧急的需求,一种是发现了更重要的需求,另外一种是发现需求和以前想的不一样。
第一种在MoSCoW中提到过,可以通过优先级分级的方法来容纳之;另外事先商定只有比如70%的时间可用,也可提供额外时间来处理,这里不多说了。
另外两种,则都是与优先级排序工作不到位有关的变更。
1. “来了更重要的需求”其实等同于“我们之前在做不重要的需求”。
尽管人们难以准确预测哪些需求真的最重要,但当我们从众多需求中挑选了极其有限的自然也是极其重要的需求放在迭代中,却能在短短的一个月内跳出一个更重要的需求(这个需求多半不在已知的“众多需求”中),就应该意识到之前的需求收集和排序工作肯定出了问题。原因或许是我们挑选了不称职的产品负责人,或产品负责人采用了错误的需求分析方法,或产品负责人工作在极端苛刻的环境中(比如客户拒绝透露需求)等等。这些问题看似可怕,但一旦摆上台面,解决它们比不知道原因地解决“迭代期内到底变更还是不变更”要容易得多。因为事关细节和具体环境,以后会有博文解决(部分已经计划在《火星人敏捷开发手册》的章节中)。
2. “需求和以前想的不一样”听起来是一种无法避免的问题,但其实我们有很多工作可做。
尽管人们难以准确预测所有需求的实际内容,但却可以就部分内容做深入了解。具体实践包括:
在纵观大局的同时,产品负责人应时刻注意最重要的需求是否弄清楚了,应多就这些问题与客户探讨,防止被迫讲不清楚的需求发放给团队的情况。应建立故事群的概念(在之一中有提到),即当零散的需求极难与客户沟通和获得反馈的时候,应就一组故事与客户反馈。这样不容易遗漏故事,也不容易对故事的排序疑惑,因为故事之间有可比性和依赖性。客户可能很难决定“一周节目单”重要还是“地区访问码”重要,但是却很容易判断“一周节目单”比“当月节目单”重要。 在具体工作时,团队不应该彻底放弃对优先级排序工作的思考,而是应该配合产品负责人做好这个工作,尤其是团队中高层次的对业务有所了解的人。
与之相对应的,是产品负责人也不应该彻底放弃对计划工作的思考,这就是下一篇将描述的开发团队自己估算-PO挑战估算-同行压力的生态线。
转载于:https://blog.51cto.com/cheny/1100226
SCP协议本身打开SSH通道时指定的是scp命令,而是用SFTP时指定的sftp。以下是一些具体的介绍,详细内容需要参考对应的RFC文件。
下面是目前整理的使用的一份:
1) 协议中数据包格式
通过安全通道传输的所有包的格式如下:
uint32 length
byte type
uint32 request-id
... 具体类型域 ...
length:整个包的长度,不包括长度域本身。因此,例如一个不包含具体类型域的包的长度域是5个字节,那么将有9个字节发送到路线上。实际上包的最大尺寸由客户端决定(它发送的读写请求包最大尺寸,外加一些字节的包开销)。所有服务器应当支持至少34000字节的包(这里的包尺寸是指全长,包括上述头部)。也就是允许读写最多32768个字节。
type:包的类型码。
request-id:从客户端来的每一个请求包含一个请求ID域,从服务端返回的每个响应也包含和服务器应答的请求一样的请求ID。一个可能的是实现是客户提供给我们一个单调递增的序号(模除2^32)。然而没有特殊的要求请求ID域是唯一的。
SFTP协议中只有两个包,INIT和VERSION,不需要使用请求ID。
2) 协议中各种包具体格式和响应
包的类型type如下:
SSH_FXP_INIT 1
SSH_FXP_VERSION 2
SSH_FXP_OPEN 3
SSH_FXP_CLOSE 4
SSH_FXP_READ 5
SSH_FXP_WRITE 6
SSH_FXP_LSTAT 7
SSH_FXP_FSTAT 8
SSH_FXP_SETSTAT 9
SSH_FXP_FSETSTAT 10
SSH_FXP_OPENDIR 11
SSH_FXP_READDIR 12
SSH_FXP_REMOVE 13
SSH_FXP_MKDIR 14
SSH_FXP_RMDIR 15
SSH_FXP_REALPATH 16
SSH_FXP_STAT 17
SSH_FXP_RENAME 18
SSH_FXP_READLINK 19
SSH_FXP_LINK 21
SSH_FXP_BLOCK 22
SSH_FXP_UNBLOCK 23
SSH_FXP_STATUS 101
SSH_FXP_HANDLE 102
2012-12-25:新增松结对编程4页。
预告:下一更新日期:2013-03-01(实际未发布)。
致歉:因误以为新版本发布是4.1日,所以错过了发布期。
作为普及读物,已经达到70页的上一版本版本已经基本满足需求。下一步计划可能是整合博客中的文章内容,出一本免费电子读物,把博客分门别类放整齐,以方便大家阅读。不过此事工程浩大,会不定期抽时间完成。感谢大家支持。
您可以在非商业场合免费使用(详见文档最后的授权页面):
作为培训前的预习阅读。打印并张贴在公司走廊上。作为企业内部小组培训教材使用。 请大家跟帖多提意见和要求,以便及时更新。
下载请点击(无需积分):
2012-12-25版
CSDN下载,无需积分,需要注册:http://download.csdn.net/detail/cheny_com/4945867
其中CSDN下载时,下图绿色框中这个巨大但是隐藏很好的按钮 就是下载按钮:
部分预览图:
更新历史
2012-08-15:用户故事分类及语法示例6页。
2012-06-30:火星人博客索引4页,使用手册更加紧凑地把博客中分散的知识体系汇集于一处;火星人产品预告2页。
2012-04-30:新版本发布,新增敏捷日常跟进4页。
2012-02-24:新版本发布,新增敏捷计划5页。
2011-12-31:新版本发布,新增办公环境1页,智慧敏捷3页,目录结构进行了调整。
2011-10-31 新增目录及用户故事共6页;目录中标出了哪些是预习材料(即入门级别的材料)。
2011-09-12 新增敏捷绩效管理2页,去除了水印中的链接(自己从来不去按,有读者告知才发现原来水印中的链接也起作用)。
2011-08-18 新增Scrum概述1页,敏捷生态系统4页,中英文对照表1页。
2011-07-21 根据读者意见,降低了水印和页眉的对比度,阅读更加方便。
已知缺陷:第8/9页右上角的文字应该相同,但实际不同,将在下一版本修改。
2011-07-19 第一版草稿发布,15P。
本人正在参加CSDN博客之星评选,如果您经常来本博客阅读或曾经下载《火星人敏捷开发手册》,欢迎投票(需要登录):
http://vote.blog.csdn.net/item/blogstar/cheny_com
每人可以为10个博主投票,所以如果看到其他常去拜访的博主,也请投上一票!
2012-12-25:新增松结对编程4页。
预告:下一更新日期:2013-03-01(实际未发布)。
致歉:因误以为新版本发布是4.1日,所以错过了发布期。
作为普及读物,已经达到70页的上一版本版本已经基本满足需求。下一步计划可能是整合博客中的文章内容,出一本免费电子读物,把博客分门别类放整齐,以方便大家阅读。不过此事工程浩大,会不定期抽时间完成。感谢大家支持。
您可以在非商业场合免费使用(详见文档最后的授权页面):
作为培训前的预习阅读。打印并张贴在公司走廊上。作为企业内部小组培训教材使用。 请大家跟帖多提意见和要求,以便及时更新。
下载请点击(无需积分):
2012-12-25版
CSDN下载,无需积分,需要注册:http://download.csdn.net/detail/cheny_com/4945867
其中CSDN下载时,下图绿色框中这个巨大但是隐藏很好的按钮就是下载按钮:
部分预览图:
更新历史
2012-08-15:用户故事分类及语法示例6页。
2012-06-30:火星人博客索引4页,使用手册更加紧凑地把博客中分散的知识体系汇集于一处;火星人产品预告2页。
2012-04-30:新版本发布,新增敏捷日常跟进4页。
2012-02-24:新版本发布,新增敏捷计划5页。
2011-12-31:新版本发布,新增办公环境1页,智慧敏捷3页,目录结构进行了调整。
2011-10-31 新增目录及用户故事共6页;目录中标出了哪些是预习材料(即入门级别的材料)。
2011-09-12 新增敏捷绩效管理2页,去除了水印中的链接(自己从来不去按,有读者告知才发现原来水印中的链接也起作用)。
2011-08-18 新增Scrum概述1页,敏捷生态系统4页,中英文对照表1页。
2011-07-21 根据读者意见,降低了水印和页眉的对比度,阅读更加方便。
已知缺陷:第8/9页右上角的文字应该相同,但实际不同,将在下一版本修改。
2011-07-19 第一版草稿发布,15P。
本人正在参加CSDN博客之星评选,如果您经常来本博客阅读或曾经下载《火星人敏捷开发手册》,欢迎投票(需要登录):
http://vote.blog.csdn.net/item/blogstar/cheny_com
每人可以为10个博主投票,所以如果看到其他常去拜访的博主,也请投上一票!
在PHP网站开发建设中经常需要对日期、时间进行处理,PHP提供了多种日期、时间函数方便PHP开发者对日期、时间进行计算、格式转换。掌握PHP日期函数非常必要,也为处理PHP日期函数与Mysql数据库日期之间的格式转换打下基础。作为PHP日期函数的开篇教程,我以PHP实例教程介绍PHP基础日期函数date和Unix时间戳函数以及相互间日期格式的转换方法。
PHP日期时区设定
在启用PHP日期函数之前,首先需要确保设定的时区是正确的,否则显示出的日期可能会有出入。在PHP环境搭建时只需要在PHP.INI配置文件中设定date.timezone为相应的时区即可。如果你没有操作PHP.INI配置文件的权利,可通过PHP时区函数date_default_timezone_get(void)获取当前PHP运行环境的时区,再使用date_default_timezone_set(string $timezone_identifier)函数设定相应的时区,更多PHP支持的时区可查询http://www.php.net/manual/en/timezones.php。
PHP格式化日期函数Date
1 2 3 4 原型 string date(string $format[,int $timestamp]) $format - PHP日期函数date的格式代码 $timestamp - Unix时间戳,默认为当前时间戳(可选) 格式化字符 ———- 说明 ——— 返回值描述
日(Day)
d —— 月份中的第几天,返回2位数字 —— 01 到 31
j —— 月份中的第几天,1至9不带零 ——1 到 31
S —— 每月天数的英文后缀 —— 2个字符st,nd,rd或者th。可以和j一起用
z —— 年份中的第几天 —— 0 到 366
星期(Week)
l —— 星期几 —— Sunday 到 Saturday
D —— 英文星期几,文本表示 —— 3个字母 Mon 到 Sun
N —— 以数字表示星期几(PHP 5.
首先通过界面卸载OpenJDK.然后卸载默认的jdk1.42
rpm -qa | grep gcj ← 确认gcj的版本号
libgcj-devel-3.4.6-3
java-1.4.2-gcj-compat-1.4.2.0-27jpp ← 根据版本号卸载gcj
libgcj-3.4.6-3
# yum -y remove java-1.4.2-gcj-compat
一、下载JDK
自己下载吧,步骤不用写了吧;我下载的是jdk-1.6.0_01-linux-i586.bin
二、安装
(1)在usr下新建一个java文件夹
#mkdir /usr/java
(2)我用的WinSCP将JDK文件放入到/usr/java文件夹下
放入后,执行下面这个命令:
#cd /usr/java
#chmod a+x jdk-1.6.0_01-linux-i586.bin
使当前用户拥有对jdk-1.6.0_01-linux-i586.bin的执行权限;
(3)执行安装
#./jdk-1.6.0_01-linux-i586.bin
运行jdk-1.6.0_01-linux-i586.bin,这时会显示出JDK的安装许可协议,按空格翻页,最后程序会问你是不是同意上面的协议,当然同意啦,输入“yes”之后开始解压JDK到当前目录。此时屏幕上会显示解压的进度。
解压完成后 /opt/java目录下会新建一个名为“jdk-1.6”的目录,至此我们已经在CentOS下安装好了JDK。
三、配置
理论上来说JDK装好了以后就可以正常使用了,但是为了我们日后使用的方便,我们还要对它设置一下。与Windows下的JDK设置一样,我们通常需要设置一下环境变量。
我习惯修改/etc/profile来添加环境变量,/etc/profile中设置的环境变量就像Windows下环境变量中的系统变量一样,所有用户都可以使用。
用文本编辑器打开/etc/profile
# vi /etc/profile
在最后加入以下几行:
export JAVA_HOME=/opt/java/jdk-1.6
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
这样我们就设置好了JDK,在centos下 source /etc/profile 就可以生效了.
四、删除/卸载
用#rm -fr jdk-1.6命令即可删除JDK,别忘了把配置文件的相关内容也清空啊
My Scripts:
[root@localhost ~]# useradd -u 100 -g ftp -d /tmp/upload/ -c "Upload user" -m -s /sbin/nologin vendor [root@localhost ~]# service vsftpd restart [root@localhost vsftpd]# setsebool -P ftpd_disable_trans 1
[root@localhost vsftpd]# service vsftpd restart
一、FTP的安装
1、检测是否安装了FTP :[root@localhost ~]# rpm -q vsftpd
如果安装了会显示版本信息:
[root@localhost ~]# vsftpd-2.0.5-16.el5_5.1
否则显示:[root@localhost ~]# package vsftpd is not installed
2、如果没安装FTP,运行yum install vsftpd命令
具体的细节如下:(如果无法更新,你先配置能访问互联网,我有文档叫 CentOS 在 VMware下,如何联网到Internet的解决办法 可以解决无法上网的问题)
[root@localhost ~]# yum install vsftpd
3、完成ftp安装后,将 /etc/vsftpd/user_list文件和/etc/vsftpd/ftpusers文件中的root这一行注释掉
# root
我们在使用Linux/UNIX的时候会遇到单网卡配置多个ip地址的问题,现在我那CentOS介绍一下如何给单网卡设置多IP:
1.使用root用户登录,打开终端:
#ifconfig eth0 192.168.115.145 netmask 255.255.255.0 up 说明:up是表示立即激活
现在想给单网卡eth0配置多个IP,只需要修改eth0,将eth0改为eth0:x(x为0-255),eth0:x称为虚拟网络接口,是建立在网络接口上边。
所以给单网卡配置多IP的方法就是使用命令:
#ifconfig eth0:0 192.168.115.147 netmask 255.255.255.0 up
#ifconfig eth0:1 192.168.115.148 netmask 255.255.255.0 up.
这样就完成了单网卡配置多IP的功能,但是reboot以后IP地址就会变回去,所以要设置启动自动激活IP设置。办法如下:
就是仿照/etc/sysconfig/network-scripts/ifcfg-eth0增加一文件根据网络虚拟接口的名字进行命名,例如ifcfg-eth0:0或者ifcfg-eth0:1等等
下边看下ifcfg-eth0:0文件里面的配置信息
DEVICE=eth0:0 #网络虚拟接口eth0:0
ONBOOT=yes #启动的时候激活
BOOTPROTO=static #使用静态ip地址
IPADDR=192.168.0.1 #分配ip地址
NETMASK=255.255.255.0 #子网掩码
关闭一个ip呢则使用
#ifconfig eth0:0 down
1.软件架构设计
作者: 温昱
内容简介:本书紧紧围绕“软件架构设计”这一主题,立足实践解析了软件架构的概念、阐述了切实可行的软件架构设计方法、提供了可操作性极强的完整的架构设计过程。另外,本书从思维方式的突破、面向对象设计、UML建模、过程与管理等关键过渡环节,为广大程序员的成长提供了切中肯綮的指导。本书可作为计算机软件专业本科生、研究生和软件工程硕士的软件架构设计教材,也可作为软件开发高级培训、软件开发管理培训的培训教材,更是第一线高级开发人员和开发管理人员的必备参考书。
作译者介绍
温昱,资深咨询顾问,CSAI特聘高级顾问,软件架构专家,软件架构思想的传播者和积极推动者。十年系统规划、架构设计和研发管理经验,在金融、航空、多媒体、网络管理、中间件平台等领域负责和参与多个大型系统的规划、设计、开发与管理。在《程序员》杂志、IBM DeveloperWorks等媒体发表了《图论思想与UML应用》、《敏捷设计从理论到实践》、《随需而变的RUP》等文章数十篇。译著有《应用框架的设计与实现——NET平台》等。
作者: 温昱 温昱 资深咨询顾问,CSAI特聘高级顾问,软件架构专家。软件架构思想的传播者和积极推动者,中国软件技术大会杰出贡献专家。千年系统规划、架构设计和研发管理经验,在金融、航空、多媒体、电信、中间件平台等领域负责和参与多个大型系统的规划、设计、开发与管理。作为资深咨询顾问,已为众多知名企业提供了卓有成效的架构培训与咨询服务。 同作者作品
软件架构设计(09年度畅销榜TOP50) SQL语言艺术 (china-pub首发) (08年度畅销榜TOP50) 一线架构师实践指南(中大型系统架构设计指南) 2. 架构实战—软件架构设计的过程 原书名: The Process of Software Architecting 作者: (英)Peter EelesPeter Peter Cripps 译者: 蔡黄辉 马文涛 内容简介:本书从基本原理入手,介绍软件架构设计过程中涉及的一些概念、流程、方法、用到的工作产品及可重用的资源,从第6章开始,通过介绍一个具体的案例来阐述如何定义需求、创建逻辑架构、创建物理架构。在第10章“进阶”中,作者补充说明了架构师和软件开发项目其他方面的关系,后面又说明了各种软件开发项目可能存在的困难及相应的处理方法。
本书理论结合实践,介绍了一些可以应用到整个或部分的架构设计流程中的最佳方法。不管你是一位资深的架构师还是一位有志于成为架构师的初级使用者,通过阅读本书都能从中获益。 作译者介绍
Peter Eeles 是IBM的高级IT架构师,他就职于IBM的Rational品牌软件组。在这个职位上,他帮助组织提高软件开发能力,尤其关注和致力于改进架构流程。Peter从1985年开始从事软件行业,其主要工作是进行架构设计和实现大规模、分布式的系统。Peter是《Building J2EE Applications with the Rational Unified Process》(Addison?Wesley,2002)和《Building business Objects》(John Wiley & Sons,1998)的合著者。他还是英国计算机协会高级会员(FBCS)、工程技术协会(FIET)会员、IBM技术人员、Open Group 3. 面向模式的软件架构.第4卷,分布式计算的模式语言(经典POSA系列的第4卷) 原书名: Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing 作者: (德)Frank Buschmann (英) Kevlin Henney (美)Douglas C.
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from t where num=0 3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num=10 or num=20 可以这样查询: select id from t where num=10 union all select id from t where num=20 5.in 和 not in 也要慎用,否则会导致全表扫描,如: select id from t where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了: select id from t where num between 1 and 3 6.
[b]此分栏列表会从指定文本文件中读取数据显示出来 文本文件中的内容是这样[/b] 张三:男人:哈哈:哈哈 张三:男人:哈哈:哈哈 张三:男人:哈哈:哈哈 张三:男人:哈哈:哈哈 张三:男人:哈哈:哈哈 张三:男人:哈哈:哈哈 张三:男人:哈哈:哈哈 张三:男人:哈哈:哈哈 #include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_LINE_SIZE 400
int main(int argc,char *argv[])
{
GtkWidget *window;
GtkWidget *clist;
GtkWidget *image;
gint i;
FILE *fp;
gchar *line;
gchar *token;
gchar *row[4];
gtk_init(&argc,&argv);
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_signal_connect(GTK_OBJECT(window),"delete_event",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
gtk_widget_set_size_request(window,500,500);
gtk_container_set_border_width(GTK_CONTAINER(window),1);
clist=gtk_clist_new(4);
gtk_clist_set_column_width(GTK_CLIST(clist),0,100);
gtk_clist_set_column_width(GTK_CLIST(clist),1,100);
gtk_clist_set_column_width(GTK_CLIST(clist),2,100);
gtk_clist_set_column_width(GTK_CLIST(clist),3,100);
gtk_clist_set_column_justification(GTK_CLIST(clist),3,GTK_JUSTIFY_CENTER);
gtk_clist_set_row_height(GTK_CLIST(clist),28);
gtk_clist_set_column_title(GTK_CLIST(clist),0,"姓名");
gtk_clist_set_column_title(GTK_CLIST(clist),1,"性别");
gtk_clist_set_column_title(GTK_CLIST(clist),2,"年龄");
gtk_clist_set_column_title(GTK_CLIST(clist),3,"年1龄");
//gtk_clist_column_title_passive(GTK_CLIST(clist),1);/*设置编号为1的列标题为不活动的列标题*/
//image=gtk_image_new_from_file("1"); /*创建图片构件,大家可以把参数改为自己的图片文件名*/
//gtk_clist_set_column_widget(GTK_CLIST(clist),0,image);/*设置标题按钮构件*/
gtk_clist_column_titles_show(GTK_CLIST(clist));
line = (char*)malloc( MAX_LINE_SIZE * sizeof(char) );
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim sbfm As MsgboxForm
sbfm = New MsgboxForm()
sbfm.ShowDialog()
End Sub
End Class
'MsgboxForm警告窗体
Imports WinFromHook.FormHook
Imports Microsoft.Win32
Public Class MsgboxForm
Dim hhkLowLevelKybd As Long
Public KeyBoardHookProcedure As HookProc
Dim fh As FormHook
Private Sub MsgboxForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
FormBorderStyle = Windows.Forms.FormBorderStyle.None
Me.WindowState = FormWindowState.Maximized
Button1.Text = "退出"
选中树节点,多出一个按钮,可以用tree.iconsComponentsFunction(用法参考AlarmMappingDemo)。 菜单用Menu.createMenu(用法参考Flex如何定制Menu的Icon) 如果右键点击树节点时,让此节点选中最好,不过现在还没有通过ContextMenuEvent或者MouseEvent获得TreeData的方法,可以考虑先自己继承twaver.Tree,添加如下方法(TWaver Flex 1.5版本将添加): 代码: public function getTreeDataByContextMenuEvent(event:ContextMenuEvent):TreeData{ var itemRenderer:IListItemRenderer; var target:DisplayObject = event.mouseTarget; while (target && target != this) { if (target is IListItemRenderer && target.parent == listContent) { if (target.visible) { itemRenderer = IListItemRenderer(target); } break; } if (target is IUIComponent){ target = IUIComponent(target).owner; } else { target = target.parent; } } if(itemRenderer != null){ return this.getTreeDataByIndex(this.itemRendererToIndex(itemRenderer)); } return null; } public function getTreeDataByMouseEvent(event:MouseEvent):TreeData{ var itemRenderer:IListItemRenderer = this.
network.sendtotoponselected =false; 上面那个机柜的图片里面的每个设备都是一个对象可以拖放,有没有办法控制这些设备对象的可拖动范围,比如只能在某一范围内上下拖动,还有就是拖动这些设备时有一个问题,点击一个对象后,它总是覆盖在其它对象的上面,这样如果两个设备比较接近时下层的设备就覆盖了上层的设备,有没有办法固定它的层次关系 这里面也是有两个小技巧 1.就是每个设备作图的时候,注意满足电话中跟你说的那个构图技巧 2.给这些设备加上个location监听,当设备拖拽的时候,不允许将设备拖动超出一个范围即可.这个范围可以由几个相关的参数来共同制定,比如某个设备位于机架的第三层(当成这个设备的一个属性), 第三层的 y 坐标根据我们的底图应该是在 levelY 处,我们定义这个范围是 levelY+/- 20. ok,现在开始编码.(1)添加属性变化监听器,专门监听这种设备的location变化(2)这类设备的location发生变化后,在监听器中判断这类设备处于机架的哪一层,例如第三层,当前设备的location是否满足了Math.abs(location.y - level3)>20的条件,如果一旦满足,那么就重新设置该设备location回到指定位置 element.location = new Point(location.x,level3-element.height); 基本的思路大概如此,你看看根据实际情况变通一下 Re: 请问如何给TWaver中的Node对象加右键菜单项 如果右键点击树节点时,让此节点选中最好,不过现在还没有通过ContextMenuEvent或者MouseEvent获得TreeData的方法,可以考虑先自己继承twaver.Tree,添加如下方法(TWaver Flex 1.5版本将添加): view plaincopy to clipboardprint?
代码: public function getTreeDataByContextMenuEvent(event:ContextMenuEvent):TreeData{ var itemRenderer:IListItemRenderer; var target:DisplayObject = event.mouseTarget; while (target && target != this) { if (target is IListItemRenderer && target.parent == listContent) { if (target.visible) { itemRenderer = IListItemRenderer(target); } break; } if (target is IUIComponent){ target = IUIComponent(target).
感谢 http://www.iteye.com/topic/544765;http://www.iteye.com/topic/566605
首先看一下iBatis的分页代码是怎么执行的
iBatis中,具体负责执行sql的类是 com.ibatis.sqlmap.engine.execution.SqlExecutor。
负责分页查询的方法是executeQuery —>handleMultipleResults —> handleResults。handleResults方法的源码如下:
private void handleResults(RequestScope request, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException { try { request.setResultSet(rs); ResultMap resultMap = request.getResultMap(); if (resultMap != null) { // Skip Results if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) { if (skipResults > 0) { rs.absolute(skipResults); } } else { for (int i = 0; i < skipResults; i++) { if (!rs.next()) { return; } } } // Get Results int resultsFetched = 0; while ((maxResults == SqlExecutor.
转自:http://www.cn-java.com/www1/?579036/viewspace-61273
关键字: jstl <%@ page contentType="text/html; charset=GBK" %> <%@ page import="java.util.*" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head> <title>JSTL测试1--c:forEach循环</title> </head>
<body> 一、整数 <c:forEach var="i" begin="1" end="10" step="1"> <c:out value="${i}" />, </c:forEach><p> 二、计算x的平方 <table> <tr><th>Value</th> <th>Square</th></tr> <c:forEach var="x" begin="0" end="10" step="2"> <tr><td><c:out value="${x}"/></td> <td><c:out value="${x * x}"/></td></tr> </c:forEach> </table> <p> 三、字符串"47,52,53,55,46,22,16,2" 分隔. <table border="1"> <c:forTokens items="47,52,53,55,46,22,16,2" delims="," var="dailyPrice"> <tr><td><c:out value="${dailyPrice}"/></td></tr> </c:forTokens> </table><p> 四、使用步长 <table> <tr><th>second</th> <th>second</th></tr> <c:forEach var="seconds" begin="0" end="
1、利用Api函数计算Windows从启动后所运行的总时间 Function long GetTickCount() Library "kernel32.dll" //获取windows从启动开始的总微秒数
窗口w_example的open事件:
timer(0.05)//触发timer事件
窗口的timer事件:
long hour , minute ,second hour = GetTickCount() / 1000 / 60 / 60//获取小时数
st_1.text = String(hour) + "小时"
minute = (GetTickCount() - hour * 60 * 60 * 1000) / 1000 / 60//获取分钟数
st_2.text = Str(minute) + "分钟"
second = (GetTickCount() - long(st_1.text) * 60 * 60 * 1000 - long(st_2.text) * 60 * 1000) / 1000//获取总秒数
st_3.text = String(second) + "
network.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, function(e:ContextMenuEvent):void{
//右键选中网元
var p:Point = new Point(e.mouseTarget.mouseX / network.zoom, e.mouseTarget.mouseY / network.zoom);
var datas:ICollection = network.getElementsByLocalPoint(p);
if (datas.count > 0) {
network.selectionModel.setSelection(datas.getItemAt(0));
}else{
network.selectionModel.clearSelection();
}
//定制右键菜单
var flexVersion:ContextMenuItem = new ContextMenuItem(DemoUtils.FLEX_SDK_VERSION, false, false);
var playerVersion:ContextMenuItem = new ContextMenuItem(DemoUtils.FLASH_PLAYER_VERSION, false, false);
if(network.selectionModel.count == 0){
network.contextMenu.customItems = [flexVersion, playerVersion];
}else{
var item1:ContextMenuItem = new ContextMenuItem("Add New Alarm", true);
item1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handler);
var item2:ContextMenuItem = new ContextMenuItem("Add Acked Alarm");
item2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handler);
var item3:ContextMenuItem = new ContextMenuItem("
parse_git_branch() { git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(git::\1)/' } export PS1="\[\033[00m\]\u@\h\[\033[01;34m\] \w \[\033[31m\]\$(parse_git_branch) \[\033[00m\]$\[\0 33[00m\] " 把上面的代码放到 ~/.bash_profile中 到项目的目录下 输入 source ~/.bash_profile
图像的剪切有多种方法,其中一种是使用ROI的方法
第一步:将需要剪切的图像图像不部分设置为ROI
cvSetImageROI(src , cvRect(x,y,width,height));
第二步:新建一个与需要剪切的图像部分同样大小的新图像
cvCreateImage(cvSize(width,height),IPL_DEPTH,nchannels);
第三步:将源图像复制到新建的图像中
cvCopy(src,dst,0);
第四步:释放ROI区域
cvResetIamgeROI(src);
完整程序实例:
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <stdio.h>
IplImage* src;
IplImage* dst;
int main(int argc , char** argv )
{
if(argv[1] == NULL)
return 0;
else {
src = cvLoadImage(argv[1],1);
if(!src)
fatal_error("unable to load image from %s", argv[1]);
cvNamedWindow("源图像",1);
cvShowImage("源图像",src);
cvSetImageROI(src,cvRect(0,0,0.5*src->width,0.5*src->height));
dst = cvCreateImage(cvSize(0.5*src->width,0.5*src->height),
IPL_DEPTH_8U,
src->nChannels);
cvCopy(src,dst,0);
cvResetImageROI(src);
cvNamedWindow("操作后的图像",1);
cvShowImage("操作后的图像",dst);
cvDestroyWindow("操作后的图像");
cvDestroyWindow("源图像");
}
cvReleaseImage(&src);
cvReleaseImage(&dst);
return 0;
}
Sift算法-----part2
前言:
在上一个步骤中,我们创建了图像的尺度空间,即逐步模糊图片,缩小它然后依次类推。现在,我们将使用模糊的图片去创建一系列的图片--高斯差(DOG)。这些DOG对找出图像的关键点十分重要。
高斯--拉普拉斯(Laplacian of Gaussian)算子:
LOG算法的步骤如下:对原始图像进行模糊,然后,根据该图像计算出二阶导数(Laplacian)。这样会得出图像上的边缘和角点,这些边缘和角点对找到关键点很重要。
但是二阶导数对噪点很敏感,模糊可以消除某些噪点是更容易地计算出二阶导数。
难度是,计算出所有这些二阶导数的时间和空间复杂度均很高,所有我们必须优化他们。
优化方法:
为了使计算LOG更加迅速,我们使用第一步所创建的尺度空间。我们计算出连续两个尺度之间的差,也就是DOG,如图:
这些高斯差接近于LOG,因此我们可以用DOG来代替LOG,这样的时间复杂度大大降低,太帮了!
另外这些DOG还有另一个非常重要的好处,他能保证尺度不变,great!
对尺度不变的解释:
LOG并不是尺度不变的,因为他们取决于你所对图片进行模糊的程度,可以看看这个高斯公式:
你是否注意到表达式中σ2,这就是尺度,如果我们能够消除它,我们就能保证尺度的独立性,如果LOG用下图的符号表示:
那么尺度不变的LOG的表达式应是这样:
前面表达式的复杂度被DOG所消除,而且结果图片中的表达式中已经被乘以了σ2
边界效应:
如果不考虑边界效应,你是不能到达上面所述的那种效果的。
现在知道DOG的效果是被乘以σ2,但是同时被乘以了另一个常数K,就是我们在前面讨论过的K
正如我们是查找图片中的最大值和最小值的分布情况,我们不会检查图像中真实值,而是他们的分布情况,因此k就是一个小case(乘以一个正,常数不会改变最大值和最小值的分布情况)
总结:
在一个容器中连续的两张图片,得到的图片是两者之差,连续对每一个容器重复进行这些步骤。
任何疑问或者建议,请在下面留言,你的关注就是我的动力。
告别外星人,外星人走好! 中央电视台节目里的那句 ----------岁月你别催 该来的我不推;岁月你别催 走远的我不追; 让多少人感伤啊! “生活就像一把无情刻刀,改变了你的模样,改变了岁月,改变了江湖, 改变了不朽,改变了悲伤,改变了往事,改变了时光,不曾改变的只剩下全世界球迷心中永远的呐喊,世上只有一个罗纳尔多。” 岁月,你别催
该来的我不推
该还的还该给的,我给
岁月,你别催
走远的我不追
我不过是想道尽原委
他出自纵贯线《给自己的歌》 下面是歌词: 想得却不可得你奈人生何
该舍的舍不得只顾著跟往事瞎扯
等你发现时间是贼了
它早已偷光你的选择
爱恋不过是一场高烧
思念是紧跟著的好不了的咳
是不能原谅却无法阻挡
恨意在夜里翻墙
是空空荡荡却嗡嗡作响
谁在你心里放冷枪
旧爱的誓言像极了一个巴掌
每当你记起一句就挨一个耳光
然后好几年都问不得闻不得女人香
往事并不如烟是啊
在爱里念旧也不算美德
可惜恋爱不像写歌
再认真也成不了风格
我问你见过思念放过谁呢
不管你是累犯或是从无前科
我认识的只有那合久的分了
没见过分久的合
岁月你别催该来的我不推
该还的还该给的我给
岁月你别催走远的我不追
我不过是想道尽原委
谁能告诉我这是什黱呢?
他的爱在心里埋藏了抹平了几年了仍有余威
是不能原谅却无法阻挡
爱意在夜里翻墙
是空空荡荡却嗡嗡作响
谁在你心里放冷枪
旧爱的誓言像极了一个巴掌
每当你记起一句就挨一个耳光
然后好几年都问不得闻不得女人香
想得却不可得你奈人生何
想得却不可得情爱里无智者
1. 智能指针nsCOMPtr
a) 如果一个智能指针作为调用函数的输出参数,必须用getter_AddRefs来调用,例如
操作语法:
{
nsCOMPtr<nsIServiceManager> servMan;
nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
// do sth
}
它等价于:
{
nsIServiceManager* servMan;
nsresult rv = NS_GetServiceManager(&servMan);
// do sth
servMan->Release()s
}
b)
操作语法:
{
nsCOMPtr<nsIDirectoryServiceProvider> prov = do_QueryInterface(aElement);
// do sth
}
它等价于:
{
aElement->QueryInterface(iid, &prov);
// do sth
prov->Release();
}
It happens all the time doesn’t it? You need to unmount a CD or you want to pack away the external drive but when you try to umount it you get the dreaded “device is busy” message. Wouldn’t it be great if Linux actually told you what was keeping the drive busy? Here we are in 2008, I’m using Ubuntu Gutsy, and that message hasn’t changed in all the years I’ve used Linux.
对应的标准岗位工资
13- C:5500, B:6500, A:7500
14-C:7500, B:9000, A:10500
15- C:10500,B:12500,A:14500
16-C:14500,B:17000,A:19500
17- C:19500,B:22500,A:25500
18-C:25500,B:29000,A:32500
19- C:32500,B:36500,A:40500
20-C:40500,B:44500,A:49500
21- C:49500,B:54500,A:59500
22-C:59500,B:? A:?
还有若干奖金、股票分红
完全胜任的系数是1,基本胜任的系数是0.9,暂不胜任的系数是0.8
地区差异系数:一级城市1,二级城市0.9,三级城市0.8其它的0.7
在华为,应届本科生最低级别就是13C,13C以下是3千多名生产线上的操作工的级别。
助理工程师的技术等级为13C-15B。普通工程师B的等级为15A--16A,普通工程师A的等级为17C-17A。高级工程师B的等级18B-19B,高工A或技术专家19B--20A(华为技术专家的技术等级和待遇等同于三级部门主管,若高级专家最高可达到一级部门正职的技术等级21A-22B),三级部门主管 19B。A,二级部门主管20A,一级部门主管21B,A--22B最高等级22A。
04年进入华为的本科生目前大多15A,B。华为社招工作六年的能力和技术水平一般,基本能胜任工作普通社招员工,大多15A,B。如果在原公司是骨干可以高两个小级。即16B,16A。如果社招工作8年的普通员工,大多给予16A或17B。如果原公司(在业界有所闻名的公司)担任过公司正式任命的部门经理,并有超过两年担任部门经理(部门主管)职务的经历,有管理团队工作的业绩,或是工作十年以上的技术骨干,则不走普通招聘流程。作为特招进入。级别一般给予 18A--17A。给予签字费,股票。很多人会注明年终奖不低于某个数值。若是思科,爱立信,阿朗,诺西,等公司正式任命的部门经理(部门主管)则会给予等同于华为三级部门主管的级别19B或19A。(这里所说的部门经理即公司正式发文任命的部门经理,负责管理一个部门,负责管理部门整个部门的工作,制订部门计划,监督管理员工,负责员工考核,召开例会分配任务等。。负责领导本部门全体员工完成公司或上级下达的各项任务的部门领导者。)。
注:
1、签字费就是你愿意来华为给你的补偿金,一般是作为补偿你跳槽损失的奖金。一般3-N万。此签字费特招员工或普通工程师B以上的员工才有。(华为挖骨干员工的手段)。
2、这里所说的年收入也因人而异。如一个社招的18级的员工,他进入华为以后的前四年每年的收入最多35万。而一个土著18级,他的年收入最少百万。这个差距是股票和奖金造成的。
3、特招一般三面,没有普通社招的技术考试和群K。特招为每个产品线的人力资源也就是干部部的主管,(干部部是普通的负责招聘的部门,不是什么招收干部的部门,华为的干部部就是公司人力资源下设在在每个产品线的二级部门,负责应届招聘,社招,考核员工等。),用人部门主管和技术骨干面,大领导。特招以面谈为主。主要考察你领导团队能力,项目能力,。。
4、孙亚芳是最高级22A。和任一样。华为好像只有此两人为22A(具体不详),华为一级部门主管或副总裁在22B,C--21C之间,二级部门总监20A-20C,三级部门主管19A--19C。(刚开始定级时三级部门主管大多18A,B,现在过去若干年华为的级别也有水分了。
STM32微处理器基于ARM核,所以很多基于ARM嵌入式开发环境都可用于STM32开发平台。开发工具都可用于STM32开发。选择合适的开发环境可以加快开发进度,节省开发成本。本章将先对STM32常用的开发工具Keil MDK和IAR EWARM进行简单介绍,然后结合STM32_SK仿真评估板和STM32F103C的开发板讲解STM32片上资源使用,最后给出一个基于STM32的数据采集器的应用实例。
5.1 Keil MDK介绍
Keil是德国知名软件公司Keil(现已并入ARM 公司)开发的微控制器软件开发平台,是目前ARM内核单片机开发的主流工具。Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器在内的完整开发方案,通过一个集成开发环境(uVision)将这些功能组合在一起。uVision当前最高版本是uVision3,它的界面和常用的微软VC++的界面相似,界面友好,易学易用,在调试程序,软件仿真方面也有很强大的功能。因此很多开发ARM应用的工程师,都对它十分喜欢。
5.1.1 开发过程及集成开发环境简介
1. Keil的软件开发周期
使用Keil来开发嵌入式软件,开发周期和其他的平台软件开发周期是差不多的,大致有以下几个步骤:
1. 创建一个工程,选择一块目标芯片,并且做一些必要的工程配置。
2. 编写C或者汇编源文件。
3. 编译应用程序。
4. 修改源程序中的错误。
5. 联机调试。
下面这种结构图完整描述了Keil开发软件的整个过程。
2. uVision3 集成开发环境
uVision3 IDE是一款集编辑,编译和项目管理于一身的基于窗口的软件开发环境。uVision3集成了C语言编译器,宏编译,链接/定位,以及HEX文件产生器。uVision3具有如下特性:
功能齐全的源代码编辑器,
用于配置开发工具的设备库,
用于创建工程和维护工程的项目管理器,
所有的工具配置都采用对话框进行,
集成了源码级的仿真调试器,包括高速CPU和外设模拟器,
用于往Flash ROM下载应用程序的Flash编程工具,
完备的开发工具帮助文档,设备数据表和用户使用向导。
uVision3具有良好的界面风格,下图是一个典型的调试时的窗口。
工程区:用于访问文件组和文件,调试是可以查看CPU寄存器。
输出窗口:显示编译结果,以便快速查找错误的地方,同时还是调试命令输入输出窗口,也可以用于显示查找结果。
内存窗口:显示指定地址内村里的内容。
查看和调用栈窗口:用于查看和修改变量的值,并且现实当前函数调用树。
代码窗口:用于查看和编辑源文件。
外设对话框:检查微控制的片上外设的状态。
3. ULINK USB-JTAG接口适配器
ULINK USB-JTAG是一个用于连接PC USB口和开发板JTAG口的小硬件适配器。通过ULINK你可以在真实的目标板上创建,下载和测试嵌入式应用。ULINK支持如下操作:
下载目标程序。
检查内存和寄存器。
单步运行程序。
插入多个断点。
实时运行程序
烧写FLASH存储器
5.1.2 工程管理
在项目开发中,并不是仅有一个源程序就行了,还要为这个项目选择CPU(Keil支持数百种CPU,而这些CPU的特性并不完全相同),确定编译、汇编、连接的参数,指定调试的方式,有一些项目还会有多个文件组成等,为管理和使用方便,Keil使用工程(Project)这一概念,将这些参数设置和所需的所有文件都加到一个工程中,只对工程而不是对单一的源程序进行编译(汇编)和连接等操作。下面我们就以一个简单的例子HelloWorld来讲解如何建立工程和配置工程。在这个例子里,我们将实现开发板上的LED1闪烁,本例使用STM32F103C开发板为目标板。
5.1.2.1 新建工程
点击菜单“Project”,选择“New uVision Project”,这是将会出现一个对话框,要求给将要建立的工程起一个名字。
选择你要保存的路径,输入工程文件的名字,这里我们就叫HelloWorld,uVision3工程文件的后缀为“.uv2”,然后点击“Save”。 这时会弹出一个对话框要求你选择目标设备的型号。
你可以根据你使用的处理器来选择,如果您所使用的处理器型号在列表中找不到,也可以找一款与您使用的相兼容的型号来代替。这里我们选择STM32F103C8,如图所示,右边一栏是对这个芯片的基本的说明,然后点击“OK”。
有些芯片会提供启动代码,我们这个时候点击“Yes”,到此一个工程就建立好了。
5.1.2.2 配置工程
经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题。一般有<%= str%>和<%# str %>两种方式,这里简单总结一下。如有错误或异议之处,敬请各位指教。
一方面,这里所讲的前台即通常的.aspx文件,后台指的是与aspx相关联的CodeBehind,文件后缀名为.aspx.cs;另一方面,这里的绑定是指用户发出访问某一页面指令后,服务器端在执行过程中就已经将前台代码进行了赋值,而后生成html格式回传客户端显示,而并非已经显示到客户端后,然后通过其他方法(如ajax)去服务器端获取相应变量。
备注:上面说的两个文件是常见的代码隐藏(code-behind)模式,还有一种是代码嵌入(code-beside, inline)模式,那就是只存在aspx一个文件,而后台代码则写入此文件的<script type="text/javascript" runat="server"></script>之中(还有一些语法上区别),这对于本文讨论的问题略有影响,因为代码嵌入是声明性代码与C#/VB.NET代码都一起编译到一个类里面,而代码隐藏则将声明性代码与C#/VB.NET代码分开几次进行翻译/编译,因此前者是局部与局部(partial)的关系后者基类与派生类的关系,但这仅仅影响所能绑定变量的范围(与修饰符有关),下面会提到。以下均以代码隐藏模式为例。
一般来说,在前台代码的三种位置可能会用到(绑定)后台变量:
服务器端控件属性或HTML标签属性JavaScript代码中Html显示内容的位置(也就是开始标签与结束标签之间的内容,如<div>这里</div>(Html标签)或者<asp:Label ID="Label2" runat="server" Text="Label">这里</asp:Label>(服务器端控件),它作为占位符把变量显示于符号出现的位置) 对于第一种位置,有一些约束条件:
(1)一般的属性要求是字符串型或数值型(下面会提到有些服务器端属性支持属性为数据集合);
(2)并不是所有的属性都可以绑定变量,有些属性例如runat属性必须是"server"常量,即使绑定的字符串是server,也会导致分析器分析时出错;
(3)有一种属性,他要求属性值有约束(类型约束,比如服务器端控件要求TabIndex属性是short类型,或者字符串内容有约束),也应该在绑定时满足,否则依然可能编译时报错;
(4)还一种属性,虽然属性本身有约束,但即使绑定的变量不满足约束,也可以编译通过,比如input的checked属性,它只有checked字符串是合法的,但如果通过绑定获取到的字符串不是checked,那么这些属性将有自己内部处理机制,来保证可以正常使用;
(5)还要注意,即使对于同一类属性,服务器端和HTML的属性的处理机制也不同,同样是TabIndex(tabIndex),前者如果不满足,则分析器错误,后者则忽略这一问题。
对于第二种位置,一般只要绑定的后台变量和JavaScript中数据类型兼容即可。
对于第三种位置,如果绑定出现的位置不在服务器端控件内部,则没有约束条件,只要是常量字符串可以出现的位置,均可以绑定。但是对于置于服务器端控件内部,也就是上面那种<asp:Label ID="Label2" runat="server" Text="Label">这里</asp:Label>的方式,则有约束条件。通过总结,归纳为四类服务器端控件,如果绑定的代码出现在这些控件的开始和结束标签之间(这里所说的控件,是指如果绑定代码外有多层的嵌套控件包围,则是指包围绑定代码的最内层控件),有不同的显示结果:
(1)约束型控件:这类控件要求它的开始标签和结束标签中只能包含指定的子控件,因此如果在这里出现代码块,将编译错误。例如:
<asp:DataList runat="server"></asp:DataList>,在它之间,要求必须嵌套<ItemTemplate></ItemTemplate>。
(2)非嵌套类控件:这类控件,不允许在内部嵌套其他控件或标签,只能是常量字符串,它会将开始标签和结束标签中常量字符串内容作为他的属性。例如上面提到的TextBox,它会将标签间内容作为它的Text属性值。
(3)嵌套类控件:这类控件,可以嵌套其他任意控件,也可以包含字符串,因此可以正常显示绑定代码块所表示的字符串内容。例如Label控件、Panel等。
(4)数据绑定类控件:这类控件是ASP.NET提供的服务器端控件,除了可以绑定普通的变量类型,也可以绑定一个数据集合(只能采取下面的第二种方式实现)。
关于是否加引号:在以上三个位置使用时,是否应该将<%= str%>或<%# str %>置于单引号或双引号中呢?对于在不同位置,处理的方式是不同的:(具体请在下面两种方式的具体介绍时,加以体会)
(1)对于第一种位置,由于JavaScript是弱类型的,如果绑定时加引号,显然就认为就当做字符串来处理,这始终是正确的;如果绑定时不加引号,它将认为这是个数值型的,那么如果获取的真是数值,当然可以,如果是非数值型,则将产生脚本错误,这即使对于JavaScript赋值常量时,也是同样的:
var test1 = 123b;//运行时报错 var test2=123;//正确,是数值型 var test3="123b";//正确,字符串型 (2)对于第二种位置,经过测试,无论是对于服务器端控件属性还是HTML标签属性,加引号总是正确的;如果不加引号,则两种属性的处理方式不同:
对于服务器端控件属性,如果绑定的代码块不加引号,则编译时会提示“验证(ASP.NET):特性值前后必须加引号”的警告信息,但是生成为HTML后,对应生成的HTML属性已经被加上引号并获取了正确的绑定结果,因此加不加引号不会影响使用,但是建议对于规范的代码,还是加上为好;对于HTML标签属性,如果不加引号,则编译时会提示“验证(XHTML 1.0 Transitional): 特性值前后必须加引号”的警告信息,并且生成为HTML属性也确实没有加上引号,那么虽然属性后面确实是没有加上引号的正确的绑定值,但是不一定能展示出想要看到的结果。比如对于input标签的value属性,如果绑定的字符串是" hello world from variable”,则在客户端的input显示出的内容实际上只是"hello”字符串,生效的属性值是一个被截断的字符串,它从属性后的一串字符串(若未加引号)的第一个非空字符开始,截止到下一个空字符的前一个字符为止(比如对于" hello world”,结果将是"hello”),因此,加上引号是必须的。 (3)对于第三种位置,加与不加引号,获取的值及其显示均不受影响。
因此建议,所有绑定表达式都加上引号,作为字符串获取,然后根据实际需求,用相应函数进行转换,得到所需要的类型。
另外,这里所说的后台变量是泛指的,包括如下:
成员变量方法或属性的返回值 表达式,也就是所有后台能够执行的代码,运行后所得到的值(也就是直接将后台代码写在前台代码中,记得使用完全限定名或在后台中using相关namespace) 数据集合 后台变量有一些约束条件,需要满足:
(1)变量修饰符要求。变量是静态或者实例字段均可。对于代码隐藏模式的ASP.NET,以上的所述的变量必须为public或protected类型(因为是基类与派生类的关系),private或者internal都不行,而代码嵌入模式则任何修饰符的变量均可访问(一个类内部的关系)。
(2)变量类型要求。由于前台属性一般是字符串类型,而JavaScript基本类型也就是字符串型、数字型、布尔型,因此对应的变量应该也是这几种方式,其余类型如果不被支持(如复杂类型、数组、引用类型等),前台获取的就是调用了变量的ToString()方法所得到的字符串。因此,在绑定时,要根据情况看是否能进行隐式类型转换,必要时还要用相关函数来强制转换,以保证前台可以获得正确的值。当然,对于数据绑定类控件,它的有些属性可以为数据集合,但这时的绑定只能通过下面第二种方式才被支持。
以上是一些概念和基本约束,这些都是两种方式都应该满足的,下面具体介绍两种方式,来实现前台代码中(以下称为代码块)绑定后台变量的功能。
一. <%= str%>
此种方式其实是ASP 时代就支持的,ASP 通过包含在 < % 和 %>中的表达式将执行结果输出到客户浏览器 , 如:< % =test %>就是将变量test的值发送到客户浏览器中。在ASP.
这些函数只能在EL表达式内使用,EL表达式之外不能使用的,前缀+冒号+函数名。
jst函数l标签库使用:
后台:
request.setAttribute("hello","hello world");
List list = new ArrayList();
list.add("t1");
list.add("t2");
request.setAttribute("list",list);
前台:
<% taglib prefix="fn" uri=http://java.sun.com/jsp/jstl/functions %>
${fn:length(hello)}
${fn:length(list)}
输出:
11
2
自定义函数库:
1.定义类和方法(方法必须是public static)
2.编写自定义tld文件,编写完毕后将此文件放入WEB-INF或WEB-INF的任意子目录下
3.在jsp中采用taglib指令引入自定义函数库
4.采用 前缀+冒号+函数名 调用即可
后台:
package com.java_min.test
public class MyFunctions(){
public static String sayHello(String name){
return "Hello" + name;
}
}
文件名: myfunctions.tld
内容: 1.把样例文件的头部信息拷贝下来直到<uri>标签,包括<uri>标签, 2.把拷入的头部内容信息进行修改,不要和以前的一样就可以了,描述,前缀,uri等,例如 uri=http://www.java_min.com/functions short-name="java_min"
3.添加函数描述内容,即:声明自定义函数
<function>
<name>say</name> //此处的值就是jsp页面上调用时需要引用的函数名
<function-class>com.java_min.test.MyFunctions</function-class> //指定自定义类的路径
<function-signature>java.lang.String sayHello(java.lang.String)</function-signature> //生命函数返回值类型和参数类型,如果类型为基本类型,直接写类型即可,如int,long等,如果为对象类型,必须写完整路径,sayHello必须是要调用的函数名
</function>
前台:
<% taglib prefix="
一、Update Statistics的作用
为了提高数据库的效率,INFORMIX提供了一个基于成本的查询优化器, 执行update statistics语句的作用就是将您创建的数据库表的有关统计信息更新到系统sysmaster的相关表中(如systables、 syscolumns、sysindexes、sysdistrib、sysprocplan等),以便查询优化器选择最佳的执行路径。当 sysmaster库中没有相应的统计信息,或者统计信息不十分准确时,优化器便无法制定一个行之有效的查询策略,其结果必然是进行大量极其可怕的顺序扫 描,产生严重的性能问题。
因此,当您重新装载数据或者对数据库表进行了大量的更新操作后,应该及时执行update statistics。也许您会发现,数据库一些参数配置的不合理可能使数据库效率降低百分之几,但如果您没有定期执行update statistics的话。数据库的性能则可能降低几到十几倍。
二、Update Statistics的语法
执行update statistics共有三个级别,即:update statistics low、updates tatistics medium、update statistics high。
1 update statistics[low]for table[{table-namesynonym-name}[(column-list)]]][drop distributions]
update statistics low只更新表、字段、记录数、页数及索引等的最基本信息,对字段的分布情况不做统计。其语法说明如下:
(1)update statistics或update statistics low,对当前数据库中所有表(包括系统表)及过程进行更新统计。
(2)update statistics low for table,对当前数据库中所有表(包括临时表,但不包括系统表)进行更新统计。
(3)update statistics low for table tablename,对指定的表所有字段进行更新统计。
(4)update statistics low for table tablename(column-list),对指定表的指定字段进行更新统计。
(5)如果不带drop distributions,原有字段分布情况依然保留;否则,原有字段分布情况将被删除。
2 update statistics medium[for table[{table-namesynonym-name}[(column-list)]]][resolution percent[conf]][distributions only]
update statistics medium除了更新表、字段、记录数、页数及索引等的最基本信息外,对字段的分布情况会采取抽样的办法来统计,因此与update statistics low相比需要花费更多的时间。其语法说明如下:
(1)resolution percent是指分布统计的详细程序,percent定义的是一个百分数,如resolution2意思是指按照字段的值分布统计成50段,如果不指定resolution percent,缺省值为2.5。
(2)conf是指分布统计时取样的比例,conf参数的取值范围为0.80—0.99,缺省值为0.95。
(3)如果指定了distributions only,则对索引的信息不做更新统计。
PHP之所以能在web开发语言中排名靠前,不仅仅是因为语法简单,上手容易。我个人认为更多是因为其语言本身的:模块的易扩展性,可维护性以及内存安全管理等特点。写过PHP的程序员不一定都知道:PHP是如何执行的?其组织结构目录的作用?如果对其有所了解,对PHP的认识会更深入,写出的代码也会更高效,更健壮...... 1. build 和编译有关的目录。
2. ext 扩展库代码,例如 mysql、zlib、iconv 等我们熟悉的扩展库。其中/ext/standard/ 目录下是常用的标准函数集。
3. main 主目录包含主要的 PHP 宏和定义。
4. sapi 和各种服务器的接口调用,例如apache、IIS等,也包含一般的fastcgi、cgi等。
5. win32 和 Windows 下编译 PHP 有关的脚本。
6. Zend 文件夹核心的引擎,所有的 Zend API 定义与宏等。
7. scripts Linux 下的脚本目录。
8. tests 测试脚本目录。
9. sapi 各类 Web 服务器的接口。
10.TSRM Zend 和 PHP 的 “线程安全资源管理器” (TSRM) 目录。
11.pear 这个目录就是“PHP 扩展与应用仓库”的目录。包含了PEAR 的核心文件。
其中几个重要的文件绝对值得你花时间去了解:
php-src/main/php.h, 位于PHP 主目录。这个文件包含了绝大部分 PHP 宏及 API 定义。
php-src/Zend/zend.h, 位于 Zend 主目录。这个文件包含了绝大部分 Zend 宏及 API 定义。
public class TestStringsplit {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "marry,1865,12";
String[] sPlit = s.split(",");
for(String s1 : sPlit){
System.out.println(s1);
}
for(int i=0;i< sPlit.length; i++){
System.out.println(sPlit[i]);
}
}
}
一、websphere参数设置及性能调优
1、应用程序服务器 > server1 > Web 容器->线程池 Web 容器用来设置最大并发用户,它维护着一个线程池,用来处理接受到的jsp/servlet请求。
2、应用程序服务器 > server1 >ORB 服务->线程池 对象请求代理(ORB)可以设置线程池的大小;同时,在这里也可以设置线程池自增长功能,点选“可增长线程池”选项,使得即使设置了最大的线程池大小,当并发的EJB请求过多,线程池的大小还是可以超过预先设置的最大值。
3、应用程序服务器 > server1 >ORB 服务 在EJB1.1规范中,要求远程方法一律使用参数值传递方式来调用,如果调用EJB的Servlet或者其它EJB是部署在同一个应用服务器下,那么它们 是共享一个JVM的,也就是说可以使得函数调用的方式变为参数引用传递,这样的话,视参数对象的复杂程度而定,可以提高5%-50%的函数调用效率。我们 可以通过点击 “按引用传送” 选项来调整ORB的参数传递方式。
4、应用程序服务器 > server1 >Web 容器->定制属性 MaxKeepAliveConnections :表示系统同时保存的最大连接个数,超过这一个数时最近最少被使用的连接将被关闭, 整型,缺省值是:300;
MaxKeepAliveRequests :客户端请求被保持到一个请求队列,此属性用于决定请求队列可保持的最大客户端请求数,整型,缺省值是:100;
5、应用程序服务器 > server1 >进程定义 >Java 虚拟机->初始堆大小 Java 虚拟机(JVM)堆大小设置将影响 Java 对象的无用数据收集。堆设置过大,会占用过多的内存,使内存资源耗尽,从而会频繁的进行I/O操作来使用虚拟内存。堆设置过小,会使得对象可分配空间变小,从而会频繁的使用垃圾收集机制来释放内存空间,而每次垃圾收集,都会耗用一定的系统资源。请考虑: (1)选定应用程序服务器的 JVM 堆是否与同一机器上的其它应用程序服务器 JVM 堆共享物理内存。例如,您是以本地方式还是以远程方式运行监视器?
(2)指定 JVM 堆驻留在物理内存中并防止交换到磁盘。 (3)将起始 JVM 堆大小设置为最大 JVM 堆大小的 1/4。 (4)如果机器上只有一个应用程序服务器,则将最大 JVM 堆大小设置为以下值: 128 MB(内存小于 1 GB 的系统) 256 MB(内存 1 - 2 GB 的系统) 512 MB(内存大于 2 GB 的系统)
1. 检查各种变化 我在设计数据库的时候会考虑到哪些数据字段将来可能会发生变更。比方说,姓氏就是如此(注 意是西方人的姓氏,比如女性结婚后从夫姓等)。所以,在建立系统存储客户信息时,我倾向于 在单独的一个数据表里存储姓氏字段,而且还附加起始日和终止日等字段,这样就可以跟踪这一 数据条目的变化。 — Shropshire Lad 2. 采用有意义的字段名 有一回我参加开发过一个项目,其中有从其他程序员那里继承的程序,那个程序员喜欢用屏幕上 显示数据指示用语命名字段,这也不赖,但不幸的是,她还喜欢用一些奇怪的命名法,其命名采 用了匈牙利命名和控制序号的组合形式,比如cbo1、 txt2、txt2_b 等等。 除非你在使用只面向你的缩写字段名的系统,否则请尽可能地把字段描述的清楚些。当然,也别 做过头了,比如Customer_Shipping_Address_Street_Line_1 I 虽然很富有说明性,但没人愿意 键入这么长的名字,具体尺度就在你的把握中。 — Lamont Adams 3. 采用前缀命名 如果多个表里有好多同一类型的字段(比如FirstName),你不妨用特定表的前缀(比如 CusLastName)来帮助你标识字段。 — notoriousDOG 时效性数据应包括“最近更新日期/时间”字段。时间标记对查找数据问题的原因、按日期重新处 理/重载数据和清除旧数据特别有用。 — kol 5. 标准化和数据驱动 数据的标准化不仅方便了自己而且也方便了其他人。比方说,假如你的用户界面要访问外部数据 源(文件、XML 文档、其他数据库等),你不妨把相应的连接和路径信息存储在用户界面支持表 里。还有,如果用户界面执行工作流之类的任务(发送邮件、打印信笺、修改记录状态等),那 么产生工作流的数据也可以存放在数据库里。预先安排总需要付出努力,但如果这些过程采用数 据驱动而非硬编码的方式,那么策略变更和维护都会方便得多。事实上,如果过程是数据驱动 的,你就可以把相当大的责任推给用户,由用户来维护自己的工作流过程。 — tduvall 6. 标准化不能过头 对那些不熟悉标准化一词(normalization )的人而言,标准化可以保证表内的字段都是最基础的 要素,而这一措施有助于消除数据库中的数据冗余。标准化有好几种形式,但Third Normal Form(3NF)通常被认为在性能、扩展性和数据完整性方面达到了最好平衡。简单来说,3NF 规定: · 表内的每一个值都只能被表达一次。 · 表内的每一行都应该被唯一的标识(有唯一键)。 · 表内不应该存储依赖于其他键的非键信息。 遵守3NF 标准的数据库具有以下特点:有一组表专门存放通过键连接起来的关联数据。比方说, 某个存放客户及其有关定单的3NF 数据库就可能有两个表:Customer 和Order。Order 表不包 含定单关联客户的任何信息,但表内会存放一个键值,该键指向Customer 表里包含该客户信息 的那一行。 更高层次的标准化也有,但更标准是否就一定更好呢?答案是不一定。事实上,对某些项目来 说,甚至就连3NF 都可能给数据库引入太高的复杂性。 — Lamont Adams 为了效率的缘故,对表不进行标准化有时也是必要的,这样的例子很多。曾经有个开发财务分析 软件的活就是用非标准化表把查询时间从平均40 秒降低到了两秒左右。虽然我不得不这么做, 但我绝不把数据表的非标准化当作当然的设计理念。而具体的操作不过是一种派生。所以如果表 出了问题重新产生非标准化的表是完全可能的。 — epepke 7.
apache commons collections 本文简要的介绍了apache commons中的collections框架内容。 commons collections : java集合框架是jdk 1.3对jdk1.2的一个主要的补充。java集合框架包含了很多强大的数据结构,这些数据结构加快了很多重要的java程序的开发。从那之后,集合框架就已经成为java处理集合的公开标准。 commons-collections以jdk的集合框架为基础,提供了新的接口、实现以及工具。它具有以下特点: ® bag接口:适用于包含一个对象的多个拷贝的集合 ® buffer接口:适用于具有顺序的集合类,例如fifos(先进先出) ® bidimap(双向映射):可以通过值查找键,也可以通过键查找值 ® map迭代器:提供了对映射的快速迭代 ® 对类型检查进行了封装,确保特定类的实例可以被添加到集合中 ® 对转换进行了封装,将集合中的对象转换成被加入时的类型 ® 对集合进行组合,使多个集合看起来就像一个集合一样 ® 有序映射和set,保持元素添加时的顺序,包括一个基于lru的map ® 标识映射可以给予对象的==来比较对象,而不是基于equals方法 ® 引用映射可以允许键and/or值可以有控制的进行回收 ® 很多比较器的实现 ® 很多迭代器的实现 ® 从数组或者枚举到集合的适配器 ® 用来测试或者创建典型set理论的集合属性,例如与、或、闭包 用户指南: commons-collections为了帮助日复一日的编程,提供了大量的类。本部分主要介绍了一些collections的关键特性。 注意同步 commons-collections使用了和标准java集合类似的同步设计方法。如果不添加额外的同步方法,大多数关于集合、映射和bag的实现都不是线程安全的。集合的synchronizexxx方法就是这些实现中的一种方式,可以使集合在多线程的应用程序中被同步。 类层次的javadoc应该指出如果没有额外的同步机制,在进行多线程访问时,某个特定的实现是否是安全的。如果没有特别指出是线程安全的,那么就被认为是需要进行同步的。 工具类: 每个主要的集合接口都有一个utility类。因此,set和sortedset接口的utility类就是setutils。这些utility类提供了操作集合类型的共通方法。 基本的方法都包含在两个根集合接口的utility类中,即collectionutils和maputils。因为所有的其他集合接口都集成collection或者map,所以collectionutils和maputils可以被扩展使用。共同的方法包括交集操作、计数操作、迭代操作、逻辑操作和类型强制转换操作等。同时,utility类还提供了对集合封装类的访问,这与jdk collections类的方式类似。 maps : map 迭代 jdk中的map接口很难进行迭代。api用户总是需要通过entryset或者keyset进行迭代。commons-collectons现在提供了一个新的接口—mapiterator来允许对maps进行简单的迭代。 iterablemap map = new hashmap(); mapiterator it = map.mapiterator(); while(it.hasnext()){ object key = it.next(); object value = it.
字符转ascii码:用charCodeAt(); ascii码转字符:用fromCharCode(); 看一个小例子 <script> str="A"; code = str.charCodeAt(); str2 = String.fromCharCode(code); str3 = String.fromCharCode(0x60+26); document.write(code+'<br />'); document.write(str2+'<br />'); document.write(str3); </script> 输出: 65 A z
排序是数据处理中的经常性工作,Excel排序有序数计算(类似成绩统计中的名次)和数据重排两类。本文以几个车间的产值和名称为例,介绍Excel 2000/XP的数据排序方法。 一、数值排序 1、RANK函数 RANK函数是Excel计算序数的主要工具,它的语法为:RANK(number,ref,order),其中number为参与计算的数字或含有数字的单元格,ref是对参与计算的数字单元格区域的绝对引用,order是用来说明排序方式的数字(如果order为零或省略,则以降序方式给出结果,反之按升序方式)。 例如要计算E2、E3、E4单元格存放一季度的总产值,计算各车间产值排名的方法是:在F2单元格内输入公式 “=RANK(E2,$E$2:$E$4)”,敲回车即可计算出铸造车间的产值排名是2。再将F2中的公式复制到剪贴板,选中F3、F4单元格按 Ctrl+V,就能计算出其余两个车间的产值排名为3和1。美文坊提醒大家如果B1单元格中输入的公式为“=RANK(E2,$E$2:$E$4,1)”,则计算出的序数按升序方式排列,即2、1和3。需要注意的是:相同数值用RANK函数计算得到的序数(名次)相同,但会导致后续数字的序数空缺。假如上例中F2单元格存放的数值与F3相同,则按本法计算出的排名分别是 3、3和1(降序时)。 2、COUNTIF函数 COUNTIF函数可以统计某一区域中符合条件的单元格数目,它的语法为COUNTIF(range,criteria)。其中range为参与统计的单元格区域,criteria是以数字、表达式或文本形式定义的条件。其中数字可以直接写入,表达式和文本必须加引号。 仍以上面的为例,F2单元格内输入的公式为“=COUNTIF($E$2:$E$4,”>“&E2)+1”。计算各车间产值排名的方法同上,结果也完全相同,2、1和3。 此公式的计算过程是这样的:首先根据E2单元格内的数值,在连接符&的作用下产生一个逻辑表达式,即“>176。7”、 “>167。3”等。COUNTIF函数计算出引用区域内符合条件的单元格数量,该结果加一即可得到该数值的名次。很显然,利用上述方法得到的是降序排列的名次,对重复数据计算得到的结果与RANK函数相同。 3、IF函数 Excel自身带有排序功能,可使数据以降序或升序方式重新排列。如果将它与IF函数结合,可以计算出没有空缺的排名。以上例中E2、E3、E4单元格的产值排序为例,具体做法是:选中E2单元格,根据排序需要,单击Excel工具栏中的“降序排序”或“升序排序”按钮,即可使工作表中的所有数据按要求重新排列。 假如数据是按产值由大到小(降序)排列的,而您又想赋予每个车间从1到n(n为自然数)的排名。可以在G2单元格中输入1,然后在G3单元格中输入公式“=IF(E3=E2,G3,G3+1)”,只要将公式复制到G4等单元格,就可以计算出其他车间的产值排名。 二、文本排序 选举等场合需要按姓氏笔划为文本排序,Excel提供了比较好的解决办法。如果您要将上例数据表按车间名称的笔划排序,可以使用以下方法:选中排序关键字所在列(或行)的首个单元格,单击Excel“数据”菜单下的“排序”命令,再单击其中的“选项”按钮。选中“排序选项”对话框“方法”下的“笔画排序 ”,再根据数据排列方向选择“按行排序”或“按列排序”,“确定”后回到“排序”对话框。如果您的数据带有标题行,则应选中“有标题行”(反之不选),然后打开“主要关键字”下拉列表,选择其中的“单位”,选中排序方式(“升序”或“降序”)后“确定”,表中的所有数据就会据此重新排列。 三、自定义排序 如果您要求Excel按照“金工车间”、“铸造车间”和“维修车间”的特定顺序重排工作表数据,前面介绍的几种方法就无能为力了。这类问题可以用定义排序规则的方法解决:首先单击Excel“工具”菜单下的“选项”命令,打开“选项”对话框中的“自定义序列”选项卡。选中左边“自定义序列”下的“新序列 ”,光标就会在右边的“输入序列”框内闪动,您就可以输入“金工车间”、“铸造车间”等自定义序列了,输入的每个序列之间要用英文逗号分隔,或者每输入一个序列就敲回车。如果序列已经存在于工作表中,可以选中序列所在的单元格区域单击“导入”,这些序列就会被自动加入“输入序列”框。无论采用以上哪种方法,单击“添加”按钮即可将序列放入“自定义序列”中备用。 使用排序规则排序的具体方法与笔划排序很相似,只是您要打开“排序选项”对话框中的“自定义排序次序”下拉列表,选中前面定义的排序规则,其他选项保持不动。回到“排序”对话框后根据需要选择“升序”或“降序”,“确定”后即可完成数据的自定义排序。 需要说明的是:显 示在“自定义序列”选项卡中的序列(如一、二、三等),均可按以上方法参与排序,请读者注意Excel 提供的自定义序列类型。 转载于:https://blog.51cto.com/badrsf/352484
最近使用HttpClient读取页面出现中文乱码问题,解决问题后写出本文章,希望能对大家有所帮助。
问题描述:HttpClient所读取的页面为UTF-8格式,使用如下方法读取后出现乱码问题,将读取内容转码无效。
public static String getHttpResponse(String url)
{
String result = null;
try{
HttpClient httpClient;
GetMethod getMethod;
httpClient = new HttpClient();
getMethod = new GetMethod(url);
getMethod.getParams().setParameter("http.method.retry-handler", new DefaultHttpMethodRetryHandler());
int statusCode = httpClient.executeMethod(getMethod);
if(statusCode == 200)
{
StringBuffer temp = new StringBuffer();
InputStream in = getMethod.getResponseBodyAsStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(in));
for(String tempstr = ""; (tempstr = buffer.readLine()) != null;)
temp = temp.append(tempstr);
buffer.close();
in.close();
result = temp.toString().trim();
} else
PS快捷键大全 一、工具箱(多种工具共用一个快捷键的可同时按【Shift】加此快捷键选取) 矩形、椭圆选框工具 【M】 移动工具 【V】 套索、多边形套索、磁性套索 【L】 魔棒工具 【W】 裁剪工具 【C】 切片工具、切片选择工具 【K】 喷枪工具 【J】 画笔工具、铅笔工具 【B】 像皮图章、图案图章 【S】 历史画笔工具、艺术历史画笔 【Y】 像皮擦、背景擦除、魔术像皮擦 【E】 渐变工具、油漆桶工具 【G】 模糊、锐化、涂抹工具 【R】 减淡、加深、海棉工具 【O】 路径选择工具、直接选取工具 【A】 文字工具 【T】 钢笔、自由钢笔 【P】 矩形、圆边矩形、椭圆、多边形、直线 【U】 写字板、声音注释 【N】 吸管、颜色取样器、度量工具 【I】 抓手工具 【H】 缩放工具 【Z】 默认前景色和背景色 【D】 切换前景色和背景色 【X】 切换标准模式和快速蒙板模式 【Q】 标准屏幕模式、带有菜单栏的全屏模式、全屏模式 【F】 跳到ImageReady3.0中 【Ctrl】+【Shift】+【M】 临时使用移动工具 【Ctrl】 临时使用吸色工具 【Alt】 临时使用抓手工具 【空格】 快速输入工具选项(当前工具选项面板中至少有一个可调节数字) 【0】至【9】 循环选择画笔 【[】或【]】 建立新渐变(在”渐变编辑器”中) 【Ctrl】+【N】 二、文件操作 新建图形文件 【Ctrl】+【N】 打开已有的图像 【Ctrl】+【O】 打开为.
如何将MySQL数据导入到SqlServer中,请看以下步骤:
1.安装mysql数据库的ODBC驱动,mysql-connector-odbc-3.51.19-win32.msi
2.打开控制面板管理工具数据源ODBC,在用户DSN中添加一个MySQLODBC3.51数据源。
3.在登录login选项卡中输入数据源名称DataSourceName,此处输入MysqlDNS;然后输入服务器Server,用户User,密码Password,输入正确后选择要导入的数据库。在连接选项connectoptions中根据需要设置MySql使用的端口port和字符集CharacterSet。
注:字符集一定要和Mysql服务器相对应,如果Mysql使用了gbk字符集,则一定要设置字符集为gbk,否则导入到SqlServer可能会出现问号乱码。
4.打开sqlserver企业管理器,新建一数据库MySql。选择该数据库,单击右键选择所有任务导入数据。
5.选择数据源为其它(ODBC数据源),用户/系统DSN为MysqlDNS。其余根据向导进行,即可将数据从MySql数据库导入到MSSQL数据库中。
昨天,我将自己做好的并已经调试过的asp网页和access数据库拷贝到服务器默认网站所配置的路径(C:/Inetpub/wwwroot)下,服务器iis环境我事先早已经安装好(服务环境是:Windows 2003+iis6)。拷贝完成后,我从“Internet 信息服务”中浏览网页,没有问题可以正常运行,也能够读取数据库中的信息。我认为没有问题了。
忽然,我觉得很奇怪,我通过网页的表单写入数据的时候怎么写不进去呢?我赶紧检查了一番,发现我的源程序没有问题的,在我本地开发环境中可以运行也可以写入数据,但是拷贝到服务器上怎么不行了呢? 我又查看了一下这方面的资料发现:原来是服务器中我的Access需要设置写入权限。具体操作步骤是:
1)需要在服务器上安装上office 中的Access 程序。不安装的话有可能出现错误提示的。
2)找到Access 数据库存储的文件夹 3) 在该文件上点击鼠标右键属性找到安全选项 。
4)在安全选项卡中添加Iusr_机器名 用户,设置其读写权限就可以了。
2010-6-11
问题1:未启用父路径
症状举例:
Server.MapPath() 错误 ASP 0175 : 80004005
不允许的 Path 字符
/0709/dqyllhsub/news/OpenDatabase.asp,行 4
在 MapPath 的 Path 参数中不允许字符 ..。
原因分析:
许多Web页面里要用到诸如../格式的语句(即回到上一层的页面,也就是父路径),而IIS6.0出于安全考虑,这一选项默认是关闭的。
解决方法:
在IIS中 属性->主目录->配置->选项中。把”启用父路径“前面打上勾。确认刷新。
问题2:ASP的Web扩展配置不当(同样适用于ASP.NET、CGI)
症状举例:
HTTP 错误 404 - 文件或目录未找到。
原因分析:
在IIS6.0中新增了web程序扩展这一选项,你可以在其中对ASP、ASP.NET、CGI、IDC等程序进行允许或禁止,默认情况下ASP等程序是禁止的。
解决方法:
在IIS中的Web服务扩展中选中Active Server Pages,点击“允许”。
问题3:身份认证配置不当
症状举例:
HTTP 错误 401.2 - 未经授权:访问由于服务器配置被拒绝。
原因分析:IIS 支持以下几种 Web 身份验证方法:
匿名身份验证
IIS 创建 IUSR_计算机名称 帐户(其中 计算机名称 是正在运行 IIS 的服务器的名称),用来在匿名用户请求 Web 内容时对他们进行身份验证。此帐户授予用户本地登录权限。你可以将匿名用户访问重置为使用任何有效的 Windows 帐户。
基本身份验证
使用基本身份验证可限制对 NTFS 格式 Web 服务器上的文件的访问。使用基本身份验证,用户必须输入凭据,而且访问是基于用户 ID 的。用户 ID 和密码都以明文形式在网络间进行发送。
今天早上安装了win7,然后下载了QQ2010,装完之后打开居然提示这个 “应用程序无法启动”,因为应用程序的并行配置不正确,通过网上查找资料找到了不能运行的原因:由于WIN7系统未加载Visual C++库,而QQ2009是基于VC++2005开发,所以需要到微软的官方网站下载补丁程序以便程序正常运行 解决方法:
通过以下链接下载补丁安装即可
http://download.microsoft.com/download/7/9/8/798325b7-8993-4ef9-9148-8db9ff4187fc/vcredist_x86.exe
安装后就可以使用QQ2010了。
熟练掌握C/C++语言,熟悉Windows开发平台,能熟练运用MFC自主编开发出一些应用程序;
熟练掌握SQL语句,对数据库有很好的认识,能熟练使用SQL Server2000软件;
熟练掌握JAVA语言,熟悉J2ME对手机软件开发一定的基础;
深入理解面向对象的思想,并能熟练应用于具体的程序设计开发中;
熟悉Unix/Linux下C语言的编程以及常用的命令,熟悉汇编语言;
熟悉网络的TCP/IP、UDP等协议,能处理解决电脑系统软件常见的故障; C++ using namespace std 详解
所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
一 :
<iostream>和<iostream.h>是不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。
后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。
因此,当使用<iostream.h>时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespacestd;这样才能正确使用cout。
二:
所谓namespace,是指标识符的各种可见范围。
C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:
1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:
std::cout << std::hex<< 3.4<< std::endl;
2、使用using关键字。
using std::cout;
using std::endl;
以上程序可以写成
cout << std::hex<< 3.4<< endl;
3、最方便的就是使用using namespace std;
例如:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写:
cout << hex<< 3.4<< endl;
因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。
所以就有了<iostream.h>和<iostream>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。
命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"
using namespace std 的用法
摘自
using namespacestd;用的并不少! ---------------------------------------------------------------
关键词:中文分词,中文分词算法,基于字符串匹配的分词,基于理解的分词,基于统计的分词 到目前为止,中文分词包括三种方法:1)基于字符串匹配的分词;2)基于理解的分词;3)基于统计的分词。到目前为止,还无法证明哪一种方法更准确,每种方法都有自己的利弊,有强项也有致命弱点,简单的对比见下表所示: 各种分词方法的优劣对比 各种分词方法的优劣对比 分词方法
基于字符串匹配分词
基于理解的分词
基于统计的分词
歧义识别
差
强
强
新词识别
差
强
强
需要词典
需要
不需要
不需要
需要语料库
否
否
是
需要规则库
否
是
否
算法复杂性
容易
很难
一般
技术成熟度
成熟
不成熟
成熟
实施难度
容易
很难
一般
分词准确性
一般
准确
较准
分词速度
快
慢
一般
(1)歧义识别 歧义识别指一个字符串有多种分词方法,计算机难以给出到底哪一种分词算法才是正确的分词系列。如"表面的"可以分为"表面/的"或"表/面的"。计算机无法判断哪一种才是准确的分词系列。 基于字符串的分词算法:仅仅是跟一个电子词典进行比较,故不能进行歧义识别; 基于理解的分词算法:指通过理解字符串的含义,故有很强的歧义识别能力; 基于统计的分词算法:根据字符连续出现次数的多少,得到分词系列,故常常能够给出正确的分词系列选择,但是也有可能判断错误的情况。 (2)新词识别 新词识别也称作未登录词识别,指正确识别词典中没有出现的词语。姓名、机构名、地址、称谓等千变万化,词典中常常不能完全收录这些词语;另外,网络中出现的流行用语也是一种未登录词的常见来源,如"打酱油"为最近出现在网络中,并迅速流行,从而成为一个新词。大量的研究证明新词识别是中文分词准确性的一个重要影响因素。 基于字符串的分词算法:无法正确识别未登录词,因为这种算法仅仅与词典中存在的词语进行比较; 基于理解的分词算法:理解字符串的含义,从而有很强的新词识别能力; 基于统计的分词算法:这种算法对第二种未登录词有很强的识别能力,因为出现次数多,才会当作一个新词;对于第二类未登录词,这类词语有一定的规律,如姓名:"姓"+ 名字,如李胜利;机构:前缀+称谓,如希望集团;故需要结合一定的规则进行识别,仅仅统计方法难以正确识别。 (3)需要词典 基于字符串的分词算法:基本思路就是与电子词典进行比较,故电子词典是必须的。并且词典越大,分词的正确率越高,因为词典越大,未登录词越少,从而可以大大减少未登录词识别的错误; 基于理解的分词算法:理解字符串的含义,故不需要一个电子词典; 基于统计的分词算法:仅仅根据统计得到最终的结果,故电子词典不是必须的。 (4)需要语料库 基于字符串的分词算法:分词过程仅仅与一个已经存在的电子词典进行比较,故不需要语料库; 基于理解的分词算法:理解字符串的含义,故不需要电子词典; 基于统计的分词算法:需要语料库进行统计训练,故语料库是必须的;且好的语料库是分词准确性的保证。 (5)需要规则库 基于字符串的分词算法:分词过程仅仅与一个已经存在的电子词典进行比较,不需要规则库来进行分词; 基于理解的分词算法:规则是计算机进行理解的基础,故准确、完备的规则库是这种分词算法的前提; 基于统计的分词算法:根据语料库统计训练,故规则库不是必须的。 (6)算法复杂性 基于字符串的分词算法:仅仅进行字符串的比较操作,故算法简单; 基于理解的分词算法:需要充分处理各种规则,故算法非常复杂;事实上到目前为止,还没有成熟的这类算法; 基于统计的分词算法:需要语料库进行训练,虽然算法也比较复杂,但是已经比较常见,故这种分词的复杂性比第一种大,比第二种容易。现在的实用分词系统都采用这种算法。 (7)技术成熟度 基于字符串的分词算法:是最早出现也是最成熟的算法; 基于理解的分词算法:是最不成熟的一类算法,到目前为止还没有成熟的算法; 基于统计的分词算法:已经有多种成熟的这类算法,基本上能够满足实际的应用。 故技术成熟度:基于匹配的分词算法〉基于理解的分词算法〉基于统计的分词算法。 (8)实施复杂性 同上面的道理,实施复杂性:基于理解的分词算法〉基于统计的分词算法〉基于匹配的分词算法。 (9)分词准确性 到目前为止还没有一个准确的结论,不过从理论上说,基于理解的分词算法有最高的分词准确性,理论上有100%的准确性;而基于匹配的分词算法和基于统计的分词算法是一种"
最近准备学习OpenGL,结果发现敲入书中给的代码,居然提示头文件找不到,相当郁闷,查了一下才发现有些不是VC自带的,需要自己下载安装,以下为转帖,感觉说的还算详细,OpenGl大牛们,就略过此文好了,呵呵
OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。
1、与C语言紧密结合。
OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单。
2、强大的可移植性。
微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于 Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL 的基本命令都做到了硬件无关,甚至是平台无关。
3、高性能的图形渲染。
OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。
总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。
OpenGL官方网站(英文)
http://www.opengl.org/
下面将对Windows下的OpenGL编程进行简单介绍。
学习OpenGL前的准备工作
第一步,选择一个编译环境
现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是支持OpenGL的。
我选择Visual Studio 2008和VC6++作为学习OpenGL的环境。
第二步,安装GLUT工具包
GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。
Windows环境下的GLUT下载地址:(大小约为150k)
http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip
无法从以上地址下载的话请使用下面的连接:
http://upload.programfan.com/upfile/200607311626279.zip
Windows环境下安装GLUT的步骤:
1、将下载的压缩包解开,将得到5个文件
2、在“我的电脑”中搜索“gl.h”,并找到其所在文件夹 如果是VC++6,则应该将glut.h复制在“D:/Program Files/MicrosoftVisualStudio/VC98 /Include/GL文件夹”)。 如果是VisualStudio2008,把glut.h复制到x:/Program Files/Microsoft/Visual Studio 9.0/VC/include/GL文件夹中,如果没有GL这个文件夹则可以自己新建一个。(x是你安装VS的盘符号,如果装的是VC++的话,里面有个gl文件,Visual Studio 2008则需要自己去新建一个)
3、把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(即与include并排的lib文件夹下)。
4、把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:/Windows/System32)
第三步,建立一个OpenGL工程
无论VisualStudio2008还是VC++6:
选择File->New->Project,然后选择Win32 Console Application,(不是win32 application).选择一个名字,然后按OK。在谈出的对话框左边点Application Settings,找到Empty project并勾上,选择Finish。然后向该工程添加一个代码文件,取名为“OpenGL.c”,注意用.c来作为文件结尾。
搞定了,就跟平时的工程没什么两样的。
注意: 包含头文件:
#include <GL/glut.h>
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glut32.lib")
第一个OpenGL程序
一个简单的OpenGL程序如下:(注意,如果需要编译并运行,需要正确安装GLUT,安装方法如上所述)
#include <GL/glut.h>
NOR flash和NAND flash的区别 收藏 一般而言,flash分为nor和nand2种,简单的说就是用or门和and门搭建的2种flash。目前用为海量存储器的flash都是nand结构,而一些当成rom使用的flash为nor结构。至于他们的物理上的区别,我也不明白,为了让自己扫盲,特地找了篇比较他们特性的入门文章,看来还是要多学习才行。intel也在将nand flash向pc主存储器方向推广,目前的产业能力也预示着这并不是妄想,目前最高的容量的nand flash已经达到了16Gbit/单片,说不定过几年,我们就再也不能在pc里听见读写磁盘时候发出的吱吱声了。
NOR和NAND是现在市场上两种主要的非易失闪存技术。Intel于1988年首先开发出NOR flash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面。紧接着,1989年,东芝公司发表了NAND flash结构,强调降低每比特的成本,更高的性能,并且象磁盘一样可以通过接口轻松升级。但是经过了十多年之后,仍然有相当多的硬件工程师分不清NOR和NAND闪存。“flash存储器”经常可以与“NOR存储器”互换使用。许多业内人士也搞不清楚NAND闪存技术相对于NOR技术的优越之处,因为大多数情况下闪存只是用来存储少量的代码,这时NOR闪存更适合一些。而NAND则是高数据存储密度的理想解决方案。 NOR的特点是芯片内执行(XIP, eXecute In Place),这样应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。NOR的传输效率很高,在1~4MB的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响了它的性能。NAND结构能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快。应用NAND的困难在于flash的管理和需要特殊的系统接口。
性能比较
flash闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何flash器件的写入操作只能在空或已擦除的单元内进行,所以大多数情况下,在进行写入操作之前必须先执行擦除。NAND器件执行擦除操作是十分简单的,而NOR则要求在进行擦除前先要将目标块内所有的位都写为0。由于擦除NOR器件时是以64~128KB的块进行的,执行一个写入/擦除操作的时间为5s,与此相反,擦除NAND器件是以8~32KB的块进行的,执行相同的操作最多只需要4ms。执行擦除时块尺寸的不同进一步拉大了NOR和NADN之间的性能差距,统计表明,对于给定的一套写入操作(尤其是更新小文件时更多的擦除操作必须在基于NOR的单元中进行。这样,当选择存储解决方案时,设计师必须权衡以下的各项因素。
NOR的读速度比NAND稍快一些。
NAND的写入速度比NOR快很多。
NAND的4ms擦除速度远比NOR的5s快。
大多数写入操作需要先进行擦除操作。
NAND的擦除单元更小,相应的擦除电路更少。
接口差别
NOR flash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节。NAND器件使用复杂的I/O口来串行地存取数据,各个产品或厂商的方法可能各不相同。8个引脚用来传送控制、地址和数据信息。NAND读和写操作采用512字节的块,这一点有点像硬盘管理此类操作,很自然地,基于NAND的存储器就可以取代硬盘或其他块设备。
容量和成本
NAND flash的单元尺寸几乎是NOR器件的一半,由于生产过程更为简单,NAND结构可以在给定的模具尺寸内提供更高的容量,也就相应地降低了价格。NOR flash占据了容量为1~16MB闪存市场的大部分,而NAND flash只是用在8~128MB的产品当中,这也说明NOR主要应用在代码存储介质中,NAND适合于数据存储,NAND在CompactFlash、Secure Digital、PC Cards和MMC存储卡市场上所占份额最大。
可靠性和耐用性
采用flahs介质时一个需要重点考虑的问题是可靠性。对于需要扩展MTBF的系统来说,Flash是非常合适的存储方案。可以从寿命(耐用性)、位交换和坏块处理三个方面来比较NOR和NAND的可靠性。
寿命(耐用性)
在NAND闪存中每个块的最大擦写次数是一百万次,而NOR的擦写次数是十万次。NAND存储器除了具有10比1的块擦除周期优势,典型的NAND块尺寸要比NOR器件小8倍,每个NAND存储器块在给定的时间内的删除次数要少一些。
位交换
所有flash器件都受位交换现象的困扰。在某些情况下(很少见,NAND发生的次数要比NOR多),一个比特位会发生反转或被报告反转了。一位的变化可能不很明显,但是如果发生在一个关键文件上,这个小小的故障可能导致系统停机。如果只是报告有问题,多读几次就可能解决了。当然,如果这个位真的改变了,就必须采用错误探测/错误更正(EDC/ECC)算法。位反转的问题更多见于NAND闪存,NAND的供应商建议使用NAND闪存的时候,同时使用EDC/ECC算法。这个问题对于用NAND存储多媒体信息时倒不是致命的。当然,如果用本地存储设备来存储操作系统、配置文件或其他敏感信息时,必须使用EDC/ECC系统以确保可靠性。
坏块处理
NAND器件中的坏块是随机分布的。以前也曾有过消除坏块的努力,但发现成品率太低,代价太高,根本不划算。NAND器件需要对介质进行初始化扫描以发现坏块,并将坏块标记为不可用。在已制成的器件中,如果通过可靠的方法不能进行这项处理,将导致高故障率。 易于使用
可以非常直接地使用基于NOR的闪存,可以像其他存储器那样连接,并可以在上面直接运行代码。由于需要I/O接口,NAND要复杂得多。各种NAND器件的存取方法因厂家而异。在使用NAND器件时,必须先写入驱动程序,才能继续执行其他操作。向NAND器件写入信息需要相当的技巧,因为设计师绝不能向坏块写入,这就意味着在NAND器件上自始至终都必须进行虚拟映射。
软件支持
当讨论软件支持的时候,应该区别基本的读/写/擦操作和高一级的用于磁盘仿真和闪存管理算法的软件,包括性能优化。在NOR器件上运行代码不需要任何的软件支持,在NAND器件上进行同样操作时,通常需要驱动程序,也就是内存技术驱动程序(MTD),NAND和NOR器件在进行写入和擦除操作时都需要MTD。使用NOR器件时所需要的MTD要相对少一些,许多厂商都提供用于NOR器件的更高级软件,这其中包括M-System的TrueFFS驱动,该驱动被Wind River System、Microsoft、QNX Software System、Symbian和Intel等厂商所采用。驱动还用于对DiskOnChip产品进行仿真和NAND闪存的管理,包括纠错、坏块处理和损耗平衡。
可以提交的内容:百度博客、腾讯博客、新浪博客、163网易博客、搜狗(搜狐)博客等各种博客以及网站 你的博客想要有更多更广泛的朋来光临,除了相互访问外,一个更广阔的天地就是各大搜索引擎,有个别朋友可能不知道收搜引擎是什么,简单的说,比如百度搜索、谷歌搜索等,只要被它们收录了,那么,你的博客流量就不是每日几百了。当然,七各大搜索引擎不是一下子就搜录你的博客,具体方法: 1、在收录前,每隔两三天前去提交一次,它就收录你的博客主页 2、收录后,有了新的内容,就再去提交一次,它就收录你的新内容 一、七各大搜索引擎博客网站免费收录入口地址列表: 1. Google谷哥搜索引擎博客收录:免费提交个人博客 http://blogsearch.google.com/ping?hl=zh-CN 2. 百度搜索引擎博客收录:免费提交个人博客 http://utility.baidu.com/blogsearch/submit.php 3. 雅虎搜索引擎博客收录:免费提交个人博客 http://www.yahoo.cn/ex/blog_rss/rss_input.php 4. 搜狗(搜狐)搜索引擎博客收录:免费提交个人博客 http://www.sogou.com/feedback/blogfeedback.php 5. 新浪爱问搜索引擎博客收录:免费提交个人博客 http://blog.iask.com/add_new_rss.php 6. 有道搜索引擎(163.com)博客收录:免费提交个人博客 http://tellbot.yodao.com/report?type=BLOG&keyFrom=help 7. 奇酷搜索引擎(以前的奇虎)搜索引擎博客收录:免费提交个人博客 http://so.blog.qikoo.com/subrss.html 其中1-5完全正常,第6有时会有点问题,要多刷几次验证码,第7好象有问题 最后祝你的博客点击量早日突破百万大关!注:百度空间需要在你的空间中添加“订阅我的空间”模块,因为有了这个模块后,就有rss地址了 二、七各大搜索引擎博客网站免费收录入口地址列表: 1. Google谷哥搜索引擎网站收录:免费提交网站 http://www.google.com/addurl/ 2. 百度搜索引擎网站收录:免费提交网站 http://www.baidu.com/search/url_submit.html 3. 雅虎搜索引擎网站收录:免费提交网站 http://www.google.com/addurl/ 4. 搜狗(搜狐)搜索引擎网收录:免费提交网站 http://www.sogou.com/docs/help/webmasters.htm#01 不必提交 5. 新浪爱问搜索引擎网站收录:免费提交网站 http://iask.com/guest/add_url.php 6. 有道搜索引擎(163.com)网站收录:免费提交网站 http://tellbot.youdao.com/report 有些搜索引擎不必提交的 如 搜搜(soso搜索)搜索引擎、搜狗(搜狐)搜索引擎等,只要google 谷哥收录了它们就自然收录