Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 15845 articles
Browse latest View live

[MySQL FAQ]系列 — 线上环境到底要不要开启query cache

$
0
0

Query Cache(查询缓存,以下简称QC)存储SELECT语句及其产生的数据结果,特别适用于:频繁提交同一个语句,并且该表数据变化不是很频繁的场景,例如一些静态页面,或者页面中的某块不经常发生变化的信息。QC有可能会从 InnoDB Buffer Pool或者 MyISAM key buffer里读取结果。

由于QC需要缓存最新数据结果,因此表数据发生任何变化(INSERT、UPDATE、DELETE或其他可能产生数据变化的操作),都会导致QC被刷新。

根据MySQL官方的测试,QC的优劣分别是:

1、如果对一个表执行简单的查询,但每次查询都不一样的话,打开QC后,性能反而  下降了13%左右。但通常实际业务中,通常不会只有这种请求,因此实际影响应该比这个小一些。

2、如果对一个只有一行数据的表进行查询,则可以  提升238%,这个效果还是非常不错的。

因此,如果是在一个更新频率非常低而只读查询频率非常高的场景下,打开QC还是比较有优势的,其他场景下,则不建议使用。而且,QC一般也维持在100MB以内就够了,没必要设置超过数百MB。

QC严格要求2次SQL请求要完全一样,包括SQL语句,连接的数据库、协议版本、字符集等因素都会影响,下面几个例子中的SQL会被认为是完全不一样而不会使用同一个QC内存块:

mysql> set names latin1; SELECT * FROM table_name;
mysql> set names latin1; select * from table_name;
mysql> set names utf8; select * from table_name;

此外,QC也不适用于下面几个场景:

1、子查询或者外层查询;
2、存储过程、存储函数、触发器、event中调用的SQL,或者引用到这些结果的;
3、包含一些特殊函数时,例如:BENCHMARK()、CURDATE()、CURRENT_TIMESTAMP()、NOW()、RAND()、UUID()等等;
4、读取mysql、INFORMATION_SCHEMA、performance_schema 库数据的;
5、类似SELECT…LOCK IN SHARE MODE、SELECT…FOR UPDATE、SELECT..INTO OUTFILE/DUMPFILE、SELECT..WHRE…IS NULL等语句;
6、SELECT执行计划用到临时表(TEMPORARY TABLE);
7、未引用任何表的查询,例如 SELECT 1+1 这种;
8、产生了 warnings 的查询;
9、SELECT语句里加了 SQL_NO_CACHE 关键字;

更加奇葩的是,MySQL在从QC中取回结果前,会先判断执行SQL的用户是否有全部库、表的SELECT权限,如果没有,则也不会使用QC。

相比下面这个,其实上面所说的都不重要。

最为重要的是,在MySQL里QC是由一个全局锁在控制,每次更新QC的内存块都需要进行锁定。
例如,一次查询结果是20KB,当前 query_cache_min_res_unit值设置为 4KB(默认值就是4KB,可调整),那么么本次查询结果共需要分为 5次写入QC,每次都要锁定,可见其成本有多高。

我们可以通过 PROFILING功能来查看 QC 相关的一些锁竞争,例如像下面这样的:

• Waiting for query cache lock
• Waiting on query cache mutex

或者,也可以通过执行 SHOW PROCESSLIST来看线程的状态,例如:

• checking privileges on cached query
检查用户是否有权限读取QC中的结果集

• checking query cache for query
检查本次查询结果是否已经存储在QC中

• invalidating query cache entries
由于相关表数据已经修改了,因此将QC中的内存记录被标记为失效

• sending cached result to client
从QC中,将缓存后的结果返回给客户程序

• storing result in query cache
将查询结果缓存到QC中

如果可以频繁看到上述几种状态,那么说明当前QC基本存在比较重的竞争。

说了这么多废话,其实核心要点就一个:
如果线上环境中99%以上都是只读,很少有更新,再考虑开启QC吧,否则,就别开了。
关闭方法很简单,有两种:

1、同时设置选项 query_cache_type = 0 和 query_cache_size = 0;
2、如果用源码编译MySQL的话,编译时增加参数 --without-query-cache 即可;

延伸阅读:
http://www.dbasquare.com/kb/how-query-cache-can-cause-performance-problems/
http://www.percona.com/blog/2012/09/05/write-contentions-on-the-query-cache/
http://dev.mysql.com/doc/refman/5.6/en/query-cache.html


由一个异常引发的scope总结

$
0
0

一、背景 

     web项目pom.xml都配置好之后,其中关于servlet的配置如下:

     

<dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency>

    结果在启动的时候报如下异常:

    

spring-analysis\target\spring-analysis-1.0\WEB-INF\lib\servlet-api-2.5.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
2014-9-6 12:03:27 org.apache.catalina.core.StandardContext start
严重: Error listenerStart

 

     在网上查到的原因是,tomcat本身自带的servlet-api-2.5.jar与引入的servlet-api-2.5.jar包冲突了

   解决办法如下,将配置改为:

   

<dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version><scope>compile</scope></dependency>

 

    以往比较少注意到scope标签的用处,借此机会总结下。

 

二、scope的解释以及用法

   以下内容来源于博客  http://drizzlewalk.blog.51cto.com/2203401/665590

  依赖范围控制哪些依赖在哪些classpath 中可用,哪些依赖包含在一个应用中。让我们详细看一下每一种范围:

compile (编译范围)

compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用,同时它们也会被打包。

 

provided (已提供范围)

provided 依赖只有在当JDK 或者一个容器已提供该依赖之后才使用。例如, 如果你开发了一个web 应用,你可能在编译 classpath 中需要可用的Servlet API 来编译一个servlet,但是你不会想要在打包好的WAR 中包含这个Servlet API;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。已提供范围的依赖在编译classpath (不是运行时)可用。它们不是传递性的,也不会被打包。

 

runtime (运行时范围)

runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC

驱动实现。

test (测试范围)

test范围依赖 在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。

 

system (系统范围)

system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的 Maven 仓库中引用依赖)。

 

 

 

 

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



【前瞻】李彦宏:未来五年移动互联网将会怎样突变?

$
0
0
【前瞻】李彦宏:未来五年移动互联网将会怎样突变?
2014-09-05 湖南菜鸟网络
_______________________________________
    9月3日消息,2014百度世界大会今日在北京举行,百度CEO李彦宏在会上表示,未来五年使用语音和图像使用需求的比列会超过50%,会超过文字搜索。另外,他还解读了传统行业在应对移动互联网时的三大问题。
  
    未来语音和图片搜索超文字搜索
  
    李彦宏表示,移动时代消费者的行为在发生变化,移动互联网的到来,给了用户新的可能性,现在人们的搜索需求分为:语音、文字、图片。

  他认为,语音相比文字是一个更加自然、更加低门槛的表达方式。目前,有的人每天有500多次语音搜索,而400次以上的绝大多数人是儿童。

  另外,拍照搜索也是一种自然的搜索方式。百度数据显示,图片搜索中,35.5%是商品搜索,15.8%是人脸搜索。

  李彦宏表示,在过去,技术的门槛一直在降低,创新的速度在过去一年里加速。五年以后会是怎样?未来五年使用语音和图像使用需求的比列会超过50%,会超过文字搜索。

  传统行业应对移动互联网的三大问题

  李彦宏在会上表示,过去的一年很特殊,移动互联网的浪潮不仅给互联网公司带来冲击,也给传统行业带来冲击,今天到百度世界大会的人中,大多数都来自非互联网行业。

  他认为,目前传统行业应对移动互联网常见的方式三种,第一个是建移动站;第二是Native?APP;第三是建第三方平台。

  1、移动站:功能弱转化低

  例子:佳美口腔

  移动端流量增速是PC端的4倍,移动端的流量新客户转化率不到PC的50%。李彦宏以为百度为例,表示BAT也面临这样的问题。“移动增速超过PC,但收入仅占30%,说明变现能力低,其他互联网公司在20%,或者更低”。

  2、原生APP:推广难活跃度低

  例子:某大型航空公司

  每年运送乘客8千万,常旅客会员2千万,但移动端用户不足70万人,日活跃用户2万人,对这样的行业来说不是那么方便,这家航空公司花了很多经历去推广也是效果很弱。总起来说,原生APP因为使用率较低,是个高门槛的触网方式。

  3、第三方平台:依赖第三方个性化服务受限,效率低

  例子:公众号

  新辣道火锅:团购比例大,依赖第三方,需要市场活动,第三方开发至少一个月,团单营收占总收入的10%,到点团购的48%。

  宝泽行:订阅量5000,但通过公众号预约服务小于5%,转化客量为0。
  
    以下为李彦宏演讲实录:

  各位尊敬的来宾,企业家朋友们,大家上午好!欢迎来到2014百度世界,刚才主持人也讲,百度世界是我们一年一度的技术创新大会,每年我们都利用这个时机向大家展示过去的一年当中百度的技术方面的各种创新的成果,过去的一年我觉得尤其特殊,因为我们每个人可能都能够深切的感受到移动互联网这个大潮给我们带来的冲击和影响。其实移动不仅给互联网公司带来了巨大的影响和冲击,也给很多很多传统产业的从业者带来了巨大的影响和冲击,今天我们请到的这些1600—2000人,我看很多人还在站着,嘉宾当中绝大多数都来自所谓的非互联网产业或者讲传统产业,有娱乐业的、有旅游业的、有金融业的、有教育业的、有餐饮业的等等,各行各业,说明大家都非常关心互联网,尤其是移动互联网给大家带来的影响到底是什么,今天我们也想从这个话题开始来跟大家进行我们的分享。

  移动时代消费者的行为在发生变化,我想这是每一个人可能都感受到的,但是具体在发生什么样的变化我们要来看一下。

  这是我们熟悉的百度搜索,每一个人通过他们自己掌握的终端,以输入关键词的形式表达他的需求,进入这个搜索框,最后通过百度来获得答案,这是已经有十几年历史的搜索引擎能够给大家带来的好处,可是移动互联网到来,给了我们的用户新的可能性和新的机会,比如说现代的搜索是可以用语音的,这个大家可能有不少人已经知道了,语音是一个更加自然的表达需求的方式。我们知道文字的历史大约只有5千多年,语音的历史有多少年?语音的历史至少有20万年,所以它是一个更加自然的、更加容易的、更加低门槛的表达的方式,这样的一个方式在过去很多很多年,在PC互联网时代,并不能够用来像计算机、像互联网表达需求,可是今天这样一种可能性就是存在了,不仅存在,其实我可以告诉大家,现在有10%的进入百度的搜索请求是以语音的形式来表达的,所以他已经变成了很多很多人的习惯,这种习惯其实我们也看,对于很多人来说他的依赖度是非常非常高的,我们看到有些人他每天要进行很多次的语音搜索。

  很多次是什么概念呢?就是一天使用语音搜索次数最多的会多少次呢?大家有没有一个猜测?50次?100次?我告诉大家,我们做了一个统计,是500次,500多次,一个人一天使用了500多次的语音进行搜索,而且我们看了一下,每天使用比如说几百次的,400次以上的语音搜索的绝大多数人是儿童,这也印证我刚才讲的,就是说语音是一个更加自然的、更加低门槛的表达的方式,当一个儿童他可能还不会打字的时候,他可能已经可以用语音来表达他的需求了,这就是一个语音搜索的例子。7年前姐姐的年龄是妹妹的4倍,7年以后姐妹俩的年龄之合是48岁,姐姐今年多少岁?我们可以想象这是一个可能小学二年级的学生用语音输入的。如果我们用文字来打的话呢,可能就是说,你输入这些字之后所需要的这个时间比你自己心算出来的这个答案还要长一些,所以你也干脆不去输入了。但是当语音是一种可能性的时候,你可以很方便的用语言告诉百度说这是你想要的,我们有答案,所以这是语音。

  除了语音之外还有更丰富的形式,就是图片。现在的百度也支持拍照搜索,或者说你用一个图片去找相似的图片,图片或者说拍照搜索其实也是非常自然、非常低门槛的表达需求的方式。我们甚至可以讲就是说,当一个小孩子在学会语言之前他可以用眼睛认知世界了,他们的这种认知、他们的这种表达,也可以通过现代的科技,也可以通过移动互联网带来的技术创新来解决,所以我们在支持了拍照或者图片搜索之后,我们也可以看到很多很多人在用这种方式来向百度表达这种需求。我们看了一下,其实表达需求最多的一个类型是跟生活方式相关的,比如说一个包拍下来看看网上哪有卖这个包的,比如说一个家具、用品,有很多人搜索,其实可以看这种搜索价值是非常高的,这种拍照搜索占到了35.5%。

  第二大类,是占15.8%的搜索,是什么呢?是通过人脸进行识别,拍一个照输入看我长的像哪个明星,或者拍一个人输入看网上还有哪些这样的图片。除了人脸之外,还有人的很多其他部位可以进行识别,这个我们就不详细去讲了。

  可能有不少人知道,1943年IBM一个非常传奇的CEO讲述了一个非常传奇的经久不衰被别人不断引用的一段话,他说“我认为整个全球计算机的市场需求量大概是50%”,所以过去技术的门槛一直一直在降低,使用的门槛一直一直在降低,从文字到语音到图片技术门槛在上升,也就使得使用的门槛,比如说从一个有大学教育的非常有知识的人变成了越来越小二年级的小学生,一直到像这样的婴儿,他也可以用他的眼睛,他也可以用他的视觉来表达需求,而这种创新的速度在过去一年或者两年当中,我们看到是在加速的,这是一个非常令人兴奋的时代,这是一个魔幻的时代。

  所以我们看现在人们需求表达的方式可以有语音、可以有文字、可以有图片,那么我们展望一下5年以后会是什么样子。未来5年我认为使用语音和图片搜索的请求量会超过纯文字的需求量,过去你说一段话里面有20%的话不认识,所以整个话就废掉了,不知道什么意思,所以不可能用这个东西表达。过去拍一张照片出来的东西完全是乱七八糟的,根本不是你想要的,你也不会再使用了。未来随着技术的进步,对语音的理解精度越来越高,对图片的识别精度也越来越高,我们就可以让人们用更加自然、更加低门槛、更加方便的方式来表达他们的需求。

  其实不仅仅语言、文字和图片可以表达需求,人们还有更多的表达需求的方式,这就是一个方式。今年4月1日我们发布了一个概念产品叫做“百度筷搜”,很多人都来问我说,你能不能给我一个,我想买,那个时候我们没有产品,今天我们有产品了,今天在外面的这个展台上大家可以看到,“百度筷搜”已经成为现实了,这个东西可以干什么?可以测地沟油,你把它伸到一个橄榄油里面,它会告诉你这是一个很高质量的橄榄油,不仅可以测油,还可以测水,它可以告诉你这是一个弱碱性的水,或者告诉你这个水不好,油、水,各种各样的食物,这也是一种新的感知世界的方式,也是用户我们的消费者表达他们需求的方式。消费者反映的需求都反映在百度的将来。

  消费者的需求发生了什么样的变化,我们看到越来越多的人在百度中寻求服务,百度十几年的历史,大多数年份我们处在一个PC互联网的时代,人们对百度的认知,就是说我输入一个关键词然后获得相应的知识、获得相应的信息、获得相应的答案,换句话说百度的作用就是连接人和信息,移动互联网的未来让人、让消费者改变了预期,他们希望百度能够提供服务,从2013年7月到2014年7月从百度发出的请求提升了130%,越来越多的人希望百度给我越来越多的信息,我还要得到我相应的服务,这些消费者的行为的变化,需求的变化,期望值的变化,不仅对百度有巨大的影响,对于我们所有的商家、所有的企业家、所有的从业者都会有影响,我觉得传统服务业也要对我们消费者的变化、行为的变化保持敏感,这点其实也不需要我用更多的语言说服大家,我们看到越来越多的传统产业在拥抱移动互联网,用各种各样他们的方式在拥抱移动互联网。

  常见的方式其实就这么三种。第一种,建立一个移动的网站,在PC时代,有一个面向PC的网站,到移动时代,说手机屏幕变小了、带宽变窄了、费用变贵了,就需要有这种方式。还有一个用原声应用的方式来迎接互联网、移动互联网带来的挑战或者说来用这样一个形式去跟他潜在的消费者来进行沟通。

  除了这两种方式还有一个第三方平台。第三方平台是指什么呢?给大家举一个例子,比如说团购,我们这个商家可以加入一个团购,他通过团购的方式也可以吸引很多移动互联网或者手机的用户。比如说微信的公众号,你不需要在外头建一个什么东西,你直接在他的体系内就可以跟自己的老客户进行沟通,所以这些我们看到都是我们的传统企业拥抱移动互联网的方式。

  这些方式有什么好处或者有什么用处,我们举一个例子。佳美口腔,这是一个有移动网站的服务商家,我们看到在过去的一年当中,佳美口腔他的移动网站增速是PC网站流量增速的4倍,我想每个人都有同感,移动的增速是非常非常快的,其实百度也是一样的,我们刚发布的季报也可以看到,移动端的某些天,在周末或者假日已经超过了PC的流量。但是我们也可以看到,移动端的流量质量是相对比较低的,至少现在的人看来质量是相对比较低的,他对于新客户的转化只是不到PC的50%。百度我刚刚讲,有些天我们的移动流量已经超过了PC,但是我们移动的收入占整个收入的比重大概30%,说明他的变现能力还是低于PC的,其实30%已经算是很高得了。像我们看到其他主流的互联网公司都在20%甚至更低,所以移动互联网给每一个企业带来的挑战都是类似的,我们怎么去解决他,可能对每一个企业都是不同的答案。

  对于佳美口腔来说,我们看到他们可能意识到了,就是说手机或者移动网站有些不好的地方,屏幕小、网速慢、带宽要钱,但是他们没有意识到就是说,移动可能带来了很多过去PC没有的能力,或者说用户的这种习惯和预期跟PC时代是不一样的,比如说对于这样一个服务来说,用户可能希望在线的通过手机来跟他的医生进行沟通、进行咨询,用户可能希望看到网上对于佳美口腔的各种各样的评价,消费者的评价,甚至他希望跟佳美口腔预约一个,比如说下星期二早上9点我想去洗牙,这些功能在移动端里头目前都没有,或者也不容易实现。

  所以我们看到移动端他有他的问题,他的问题就是功能弱和转化率低,我们再看一个原生应用的例子,这是一大型的航空公司,这个航空公司每年运送人数是8千万人次,他有常旅客会员2千万人,可是我看到他的原生应用移动端不超过7千万人,如果按照日活,日活是我们这个行业特别看中的一个指标,表明用户对你的依赖程度,他的日活是2万人,对于一个年运送量在8千万人次的大型航空公司来说,2万人真的是太少了。但是Native APP这种形式对于这样一个航空公司来说并不是那么方便,因为这是一个相对比较低频的应用,不是每个人天天都会坐飞机,是他想不起来去用。即使比如说这家航空公司花了很多精力推广这个Native APP,希望靠它来吸引新的乘客,我们看到这个收效也是会非常非常微弱的。所以Native App有一个问题就是说,推广难、活跃度低,那些有推广能力的APP Store也好,手机应用商也好,说我捆绑了你的应用给我多少钱,可是只有两个人捆绑你的应用,你想推广成本有多高,因为是一个低频应用,有的不下载,或者下载了也可能应用程度不高,所以Native App对绝大多数人来说是非常非常低门槛的移动方案。

  我们再看第三方平台,刚刚说的团购,这是一个餐饮业的,新辣道鱼火锅,通过团购吸引客户,现在团购已经占他总的收入比重超过了10%,对他来说是非常有意义的销售渠道了,但是再仔细看,48%的消费者是到了他的店之后才开始去买团购券的,这意味着什么呢?意味着将近一半人其实并不是新用户,而是说他已经明确说我在这儿吃饭了,才在这儿买的,我想这不是新辣道餐饮企业想要的情况,他想要的,原来没想在这儿吃饭,结果刺激了一下在这儿吃饭了,原来不是我的客户,没有在这儿消费,我现在通过优惠让他来了,可是我们看这里面有非常大的折损,不是这一类客户。

  要想刺激那些本来没有的需求,像这种餐饮企业经常干的一件事就是做活动,我们看一下新辣道做活动,这是他最近做的一个活动,小食代的套餐,新辣道是相当大的餐饮企业,吸引了有30万的用户关注他的公众号,所以下了很大的本钱,有一定规模的,他要想通过公众号的方式触达他的用户、触达他的消费者搞这样的活动,搞这个市场活动,比如这个小食代需要依赖第三方的开发机构,自己没有这样的IT能力,至少要开发一个月。我们知道餐饮这个行业其实竞争非常激烈,市场利润很薄,消费者的口味变化也很快,为了做市场活动这么长时间还要依赖第三方,对他们来说也是有点太难了。

  再看一个公众号的例子,宝泽行,大家知道,这是宝马的4S店,通过公众号吸引到了5千用户订阅他的公众号,他希望通过这种方式干什么呢,也是两个作用,一个就是说维护他的老客户,宝马的车主什么时候开始需要来换油了,什么时候来开始要维护了、维修了,或者是通过这个东西吸引一些人,过去没有在这儿买宝马的人来买宝马,我们看到只有不到5%的用户通过公众号来预约他的维修服务,我们知道4S店利润最丰厚的就是老客户的维修、维护,他可以挣很多钱,但是这个方面我们看到,他其实效果是不明显的,只有不到5%的人会这样来用。而真正转化,就是新客户的这种转化是一单都没有,没有一个人是通过这种方式,原来不打算买宝马去买宝马的。

  有没有一种方式既能够方便的维护老的客户,又能够大量的吸引新客户呢?怎么样才能够运用我刚才讲到的各种各样移动时代带来新的技术、新的创新来为自己服务呢?如何让你的顾客随时随地直达你来提供的服务呢?今天百度世界上我们就要给大家揭开这个答案,所以接下来的时间把它交给我的三位同事,他们分别会从各自不同的角度来跟大家解释百度的答案,下面有请百度副总裁李明远上台。  所以公众号还有一个问题,就是个性化服务受限,效率非常低,每个人买车的时间是不一样的,他需要做保养的时间也是不一样的,如果我们能够在一个客户需要做保养的时候提醒他说到我们家来做保养吧,就会非常好,这个效果就会大大提升,可是公众号没有这样的功能,不允许他这样做。所以个性化服务受限,效率很低。
  青春就应该这样绽放   游戏测试:三国时期谁是你最好的兄弟!!   你不得不信的星座秘密

Mozilla终止支持1024位CA证书

$
0
0
随着Firefox 32的发布,Mozilla正式终止支持1024位CA证书。早在2011年美国国家标准技术研究所就建议企业升级到2048位或更长的密钥,尽管当时因式分解和破解1024位长的RSA密钥仍然需要大量的计算资源。除了Firefox外,Mozilla的邮件客户端Thunderbird也停止了对1024位密钥的支持。有多少网站会受到影响?Rapid7的Project Sonar扫描了6500万证书,索引了约2000万网站,大约有107,535个网站的证书将会不被信任,但其中76,185个网站使用的证书已经过期了,任何浏览器都会发出警告。






前台页面优化全攻略(四)

$
0
0

  通过前几篇文章,你应该已经掌握了很多优化网站的方法。现在你的网站加载速度已经很快了,但是你必须持续的监控你的网站,了解它的大小变化,要不然一段时间过去之后,它可能又成为了一个胖子。

  如今每个页面平均已经达到1.7M,每年增长大概32%。你可以通过以下几个工具来查看你的网站是不是又在暴饮暴食,而且它们都是免费的。

   1. Pingdom

  Pingdom是我喜欢的一个在线测试工具。它会揭露出所以你想知道的细节,你可以一清二楚的看到网站的现状:重量、加载速度、代码分析、性能评分、开发者建议,它还提供了一个历史的时间轴帮你查看网站瘦身的成果。如果你只想用一个工具完成所有的检测,Pingdom再合适不过了。

   2. Firefox Web Developer Add-on

  Web Developer 插件 是火狐的Web开发调试插件 以工具栏的形式对网页的(X)HTML、脚本、多媒体、CSS、缓存、图象等多方面的实用工具。使我们能轻易的获得网页的更多信息,使我们进一步的了解当前所浏览的网页。

  在Web Developer插件工具栏中,主要由以下几个部分组成:Disable、Cookies、CSS、Forms、Images、Information、Miscellaneous、Outline、Resize、Tools、View Source和Options。

   3. GTmetrix

  GTmetrix 使用Google的 PageSpeed Insights  和 雅虎的  YSlow 来对你的网站进行评级,并且会提供可行性建议来帮助你改善你的网站性能。

  经过分析之后,你就会得到一份详细的测试报告,网站同时还提供了PDF格式的报告下载,非常贴心。如果你运行的是WordPress,那么还有针对WordPress的优化建议。只要你在该网站注册一个账号,就可以享受免费的定时监测服务。

   4. Google PageSpeed Insights

  谷歌也出了一款性能优化工具:PageSpeed Insights。其目的是帮助站长优化页面,从而能够带来最佳的渲染性能,尤其实针对移动页面。

  根据谷歌Analytics的数据显示,现如今移动页面平均加载时间都需要超过7秒以上,虽然在移动平台上已经得到很大改善,但还需改进。

  PageSpeed Insights的使用方法很简单,进入官网,然后输入你的网站URL,就会开始分析。它会帮你启用压缩( 前台页面优化全攻略1.1),使用浏览器缓存,清除首屏内容中阻止呈现的 JavaScript 和 CSS,缩短服务器响应时间, 优化图片, 压缩 JavaScript,压缩 HTML等。你会惊奇的发现,它会帮我们解决很多本系列之前提到到过的优化方案。

   5. YSlow

  YSlow是Yahoo发布的一款基于FireFox的插件。安装YSlow必须首先先安装  Firebug,然后下载YSlow,再对其安装。

  YSlow可以对网站的页面进行分析,并告诉你为了提高网站性能,如何基于某些规则而进行优化。YSlow可以分析任何网站,并为每一个规则产生一个整体报告,如果页面可以进行优化,则YSlow会列出具体的修改意见。

  YSlow有23条规则:

  (1. 减少HTTP请求次数

  (2. 使用CDN

  (3. 避免空的src和href

  (4. 为文件头指定Expires

  (5. 使用gzip压缩内容

  (6. 把CSS放到顶部

  (7. 把JS放到底部

  (8. 避免使用CSS表达式

  (9. 将CSS和JS放到外部文件中

  (10. 权衡DNS查找次数

  (11. 精简CSS和JS

  (12. 避免跳转,同域避免反斜杠 “/” 的跳转,跨域使用Alias或者mod_rewirte建立CNAME

  (13. 删除重复的JS和CSS

  (14. 配置ETags

  (15. 可缓存的AJAX

  (16. 使用GET来完成AJAX请求

  (17. 减少DOM元素数量

  (18. 避免404

  (19. 减少Cookie的大小

  (20. 使用无cookie的域

  (21. 不要使用滤镜

  (22. 不要在HTML中缩放图片

  (23. 缩小favicon.ico并缓存

   6. Browser Developer Consoles

  如果你不想使用其它平台提供的功能,想要自己一步步地分析,Firebug、Chrome Inspector和其它浏览器的开发者工具都可以帮助你优化, 这些工具都在一步步地强大起来。

   7. PageScoring Website Speed Test

  如果你想要一个快速而又简单的工具,Website Speed Test就是很好的选择,它有一个很好的名字,X如其名。它会展示出所有页面的加载速度和页面大小,下载时间为每个单独的文件,可以帮你方便的隔离问题。

   8. Uptrends Speed Test

  和其它的优化工具一样,它提供全页面测试工具,帮你测试加载时间,以及完整的HTML页面(图片 , frames, CSS style sheets, Flash objects, RSS feeds  和 Javascript 文件)的速度。

   9. Page Speed Tool

  Page Speed Tool是一个外观精美,强调文件大小,资源和下载速度的工具。虽然加载时间的测试只计算为HTML源代码不是所有文件,但是通过友好的界面,你依然可以得到一些完整的数据。

   10. Web Page  Analyzer

  Web Page Analyzer 帮助用户计算网页大小、组成和下载的时间,并可给予测试的结果给出优化的建议。设置可以模拟不同的网速下的网站打开时间,目标是让你的页面回到14.4K。

  总结

  到这里这个页面优化的系列就全部结束了,最后又列举出这么多工具,有选择恐惧症的人真是对不住了,如果不知道哪个好用,推荐你用第四个吧,也就是Google的PageSpeed Insights,因为它提供的功能基本涵盖了这几章我列举出的优化方案。最后希望这四篇文章会对你有所帮助,程序员都是好人,Best wishes~

前台页面优化全攻略(三)

$
0
0

  经过前 两篇文章的实践,你的网站加载速度一定有了非常明显的变化。能把实践跟到这篇文章的人想必一定是极客中的极客。如果你仍对网站的加载速度不满意,可以看看再尝试一下本文中几近疯狂的终极优化方案。

  你可以对网站进行快速的优化,但网站日常的节食却很难。也许你已经花了很大的力气去优化你的 CSSJavaScript代码,但是你所做的努力马上又会因为老板或客户期望的新功能而付之东流。所以看来不论是人还是网页,减肥都贵在坚持。

  这篇终极减肥方案可能不适合所有的网站,但是我相信它可以引起你对网页大小的重视。

  1. 永远都不要相信第三方平台的代码

  你会随随便便的让一个不认识的开发者改动你的网站代码吗?我想应该没有人会这么二,但是为什么你就如此的相信第三方平台的代码呢?在网站中添加一个实用的组件实在太容易了,但是它们很少会关心你的网站的安全性。你必须经常检查这些插件的源码并用 firebug跟踪一下,这显然是个悲伤的故事。

  2. 一个JavaScript库就够了

  也许你的网站正在使用jQuery,这样很好,你应该坚持用它,不要为了让你的网站更酷而添加各种各样的库。

  你还需要考虑以下几个问题:

  1.如果没有使用一些库,你的网站能正常的构建吗?

  2.有没有更加轻量级的库可以取代?比如 Zepto.js 和 Minified.js 都可以取代jQuery核心库的部分API。

  3.是因为浏览器版本的差异你才不得不加上一个库来支持的么?你有没有因为熟悉和用着舒服来决定选择哪个库?

  3. 谨慎使用CMS模板

  很少有建站模板会直接提供一个轻量级的页面,但他们的确是不错的开始。

  不论是一个免费的还是付费的模板他们都有很高的商业价值,为什么一些大公司不直接花一些钱买个不错的模板,而要花高价养活几个程序员呢?虽然模板可以提供网站的大部分功能,但是它有一些隐形的花费,一个模板为了满足不同网站的不同需求,就必须实现成百上千的方法。你可能只会用到其中的几个,但是其它功能还是会存在于代码之中。

  大概是我比较不幸,我使用的WordPress主题居然达到了2M。虽然大家都知道肯定会有轻量级的主题,但是找到它也是个麻烦事儿~

  4. 为框架消脂

  像Bootstrap和Foundation这些模板类型的框架是非常实用的原型设计和项目切入点。但是通用的模板很多CSS和JavaScript代码你都不会用到,就连HTML代码中也会有很多没用的东西。

  就我个人来说,我喜欢模块化的开发方式,我需要什么,我就添加什么。项目是从零开始,由我来决定要什么和不要什么。框架就像是雕刻大理石,你会凿掉没有用的那一部分,这样通常比较难。而模块化就像堆积木,你可以充分发挥你的各种能力。

  我不会说我永远都不使用框架,但是我们必须要考虑框架给我们带来的负面影响。有一个工具 grunt-uncss 它可以帮我们除去框架中不需要的代码。

  5. 享受渐进增强(Progressive Enhancement)

  随着互联网的发展,浏览器的发展也突飞猛进,在原来的多浏览器厂商并分天下的局面下,现在还出现了多平台的划分。开发人员面对原来五大浏览器IE、 火狐、Opera、Safari、Chrome的局面已经有些不知所措,何况现在我们还需要处理iphone、ipad、android的mobile浏 览器、其他智能手机中带有的非现代浏览器(对浏览器标准支持不完整的)。在这种情况下,如果你想要让你的网站变得广为人知,那么必须从新思考兼容性的问 题。

  渐进增强PE可以帮助大家较好的解决这个问题。PE是以内容为核心的开发方式,在内容的基础上,开发人员使用css加工样式,利用javascript添加行为来提升用户的使用体验,由于是以内容为核心,所以使用PE的同时,亦解决的兼容性问题。

  那么,PE中提到的内容核心是什么?对于用户、BA、UX来说,内容可以是网站给访问的用户带来的内容和功能,具体可以单纯到只是网站中的文字,也 包括网站带给用户的交互功能,比如说发送邮件,填写表单,甚至还可能为给用户带来的视觉效果、颜色搭配、排版、阅读体验等等。但是,对于我们开发者来 说,PE核心内容就是我们的HTML代码,简洁易懂的标记们。HTML是我们制作页面功能的基础,也是几乎所有浏览器呈现页面功能的基础,开发人员通过添 加css样式和js代码使内容在更强的浏览器上工作得更好,提升用户体验。

  在这边举一个例子,80后可能都会有印象,家里的电视机是又90年代初的黑白电视机换到00年初的CRT彩色电视机,接着随着科技发展,到现在 LED高清电视机,甚至都出现了3D电视机。对于用户来说,电视机给他们带来的是电视节目,看中央一台也看了这么多年了,但是先进的电视机给用户带来了新 的观赏体验,不仅带来了色彩,还带来了高清的画质,丰富的观影体验。反过来看,同样内容的电视节目同样可以在旧的电视机上播出,内容一样能被用户获取到, 这一切都是向后兼容的,PE给我们带来的好处就在于此。浏览器的发展,从Netscape到现在的Chrome也是类似的一个发展过程。那么,我们的网站 给用户带来的是尽可能一样的体验,而并非是完全一样的。你也不能奢望一个kindle的silk浏览器能像chrome表现得那么出色。

  由此看来,我们需要从新审视解决浏览器兼容性这个问题,我们的开发需要从一直一来的以兼容性为目标的开发转化为以可用性为目标的开发,可用性指的是网站带给用户的功能从一开始就是跨浏览器的。

  6. 选择一个自动化的构建工具

  你应该确保你已经完成了所有的关于简化图片,CSS和JavaScript的工作。这些工作都可以被人工地完成,但是如果你觉得麻烦,也可以尝试一下像  Grunt.js 和  Gulp.js 这样自动化的工具。

  7. 了解你的代码

  CSS和JavaScript 预处理器技术已经非常的成熟,而且也涌现出了越来越多的预处理器框架。常用的像 Sass、Less CSS、Stylus等等。

  什么是 CSS 预处理器?CSS 预处理器是一种语言用来为 CSS 增加一些编程的的特性,无需考虑浏览器的兼容性问题,例如你可以在 CSS 中使用变量、简单的程序逻辑、函数等等在编程语言中的一些基本技巧,可以让你的 CSS 更见简洁,适应性更强,代码更直观等诸多好处。

  但是如果你使用预处理器技术你就很可能不了解你的代码是如何执行,不论你使用什么样的技术,最好是了解你的代码执行流程。

  8. 使用offline AppCache

  对于web app来说,离线应用功能已经越来越重要。诚然,浏览器本身就有缓存机制,但是,这些缓存机制不够可靠,可能并不会按你所想要的方式运行。HTML5则通过 ApplicationCache接口处理了离线应用中的一些问题。

  使用这个接口让你的应用拥有三方面的优势:

  1. 离线浏览——用户在不能联网的时候依然能浏览整个站点
  2. 高速——缓存资源是存储在本地的,因此能更快加载。
  3. 更小的服务器负载——浏览器只需要从服务器端下载有改变的资源即可,相同资源不需要重复下载。

  Application Cache(或 AppCache)让一个开发者可以指定浏览器需要保存哪个文件。当用户在离线情况下时,即使他们按了刷新按钮,你的应用也能正确加载和工作。

  9. 简化你的网站

  在过去的几年中,Web网站和应用程序的复杂度有了明显的一个改进——以客户为中心。但不是网站都做到了这一点,因为种种原因网站变得臃肿:

  1. 错误地认为更多的功能可以吸引更多的客户。

  2. 错误地觉得开发更多的东西可以赚到更多的钱。

  3. 不知道怎么样才能更好。

  幸运的是,通过用户测试可以帮助你了解到哪些不常用的功能可以用用其它时尚的、轻量级的功能替换。

  幸运的是,一个小的用户测试可以帮助你识别不常用的选项可撕下的产品或更换,以时尚的,轻量级的替代品。

  10. 改变你的编程态度

  有没有人因为网站达到了1.7M而感到羞愧?不管是什么时候什么原因网站变的臃肿,程序员都应该为这件事情负全责。

  当然开发速度和成本也是非常重要的,但是互联网发展到现在已经造就了用户不愿意等待的习惯,一个加载缓慢的网站不管创意有多好用户也不会等。你的老板和客户不会关心你使用的是什么技术。如果你不突出地解决可能出现的问题,你就不会成为一个优秀的程序员。

  轻量级的页面就是证明自己最直接的方式,你应该 有了个正确的编程态度,时刻注意以下的问题:

  1. 人们很容易忘记的带宽问题,当你使用在一个50Mbps宽带的电脑,你很可能会忽略在差的3G接收地区和一些繁忙的酒店网站的加载情况。

  2. 在每一个项目中都要考虑页面权重问题的。这个字体是必要的吗?你能降低背景图像的尺寸吗?有可用的CSS3动画来替换JavaScript库吗?

  3. 网页肥胖是一种流行病,如果你做的很好,你会变的很突出。

  总结

  前台页面优化全攻略实战篇到这里就结束了,如果你能把这三篇优化方案都尝试一遍,你一定可以变成一个优秀的开发人员,并且能开发出极简的网站。在下一篇文章中,我会列举出一些网站性能的测试工具和在线平台,相信你可以很明显地看到网站优化的效果。

科学家证明玩游戏可以帮助学英语

$
0
0
?瑞典哥德堡大学和卡尔斯塔德大学的研究者们联合发表了最新的研究报告,报告显示孩子们玩电子游戏对于英语学习来说最有益。


科学探索

 
 

  ?瑞典哥德堡大学和卡尔斯塔德大学的研究者们联合发表了最新的研究报告,报告显示孩子们玩电子游戏对于英语学习来说最有益。其实“玩游戏学英语”这个说法很早以前就有在传,不过有了专家撑腰,玩家们的底气倒是更足一些。科学家通过对一组六年级学生进行观察,发现一段时间内玩游戏频繁的孩子和不怎么玩游戏的比起来,其词汇量和语言运用能力明显更强。

 

 

  有趣的是,研究人员发现玩 MMO 网络游戏更加有利于学习,毕竟玩家需要试图去和其他人交流。当然了,前提是你必须要去一个英语服务器上玩才行。

  虽然有了科学家的研究,但这距离我们能理直气壮地说“我这是在学英语”应该还很远。另外,现在游戏汉化那么发达,网游国服那么盛行,“玩游戏学英语”,这反倒是比以前更难了。

来源: cnBeta

详解 Too many open files

$
0
0

 运行在Linux系统上的Java程序可能会出现"Too many open files"的异常情况,且常见于高并发访问文件系统,多线程网络连接等场景。 

        程序经常访问的文件、socket在Linux中都是文件file,系统需要记录每个当前访问file的name、location、access authority等相关信息,这样的一个实体被称为file entry。“open files table”(图中橙色标识)存储这些file entry,以数组的形式线性管理。文件描述符(file descriptor)作为进程到open files table的指针,也就是open files table的下标索引,将每个进程与它所访问的文件关联起来了。 

 

        每个进程中都有一个file descriptor table管理当前进程所访问( open or  create)的所有文件,文件描述符关联着open files table中文件的file entry。细节不表,对于open files table能容纳多少file entry。Linux系统配置open files table的文件限制,如果超过配置值,就会拒绝其它文件操作的请求,并抛出Too many open files异常。这种限制有系统级和用户级之分。 

        系统级: 
                系统级设置对所有用户有效。可通过两种方式查看系统最大文件限制 
                1   cat /proc/sys/fs/file-max  
                2   sysctl -a 查看结果中fs.file-max这项的配置数量 
                如果需要增加配置数量就修改/etc/sysctl.conf文件,配置fs.file-max属性,如果属性不存在就添加。 
                配置完成后使用 sysctl -p来通知系统启用这项配置 

        用户级: 
                Linux限制每个登录用户的可连接文件数。可通过   ulimit -n来查看当前有效设置。如果想修改这个值就使用  ulimit -n <setting number> 命令。 

              对于文件描述符增加的比例,资料推荐是以2的幂次为参考。如当前文件描述符数量是1024,可增加到2048,如果不够,可设置到4096,依此类推。 

       在出现Too many open files问题后,首先得找出主要原因。最大的可能是打开的文件或是socket没有正常关闭。为了定位问题是否由Java进程引起,通过Java进程号查看当前进程占用文件描述符情况: 

Java代码   收藏代码
  1. lsof -p $java_pid 每个文件描述符的具体属性  
  2. lsof -p $java_pid | wc -l  当前Java进程file descriptor table中FD的总量  


        分析命令的结果,可判断问题是否由非正常释放资源所引起。 




文件描述符资料 :  简介       PDF下载 

 

来源: http://langyu.iteye.com/blog/763247



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




浅谈SOA面向服务化编程架构(dubbo)

$
0
0



 

     dubbo 是阿里系的技术。并非淘宝系的技术啦,淘宝系的分布式服务治理框架式HSF啦
,只闻其声,不能见其物。而dubbo是阿里开源的一个SOA服务治理解决方案,dubbo本身
集成了监控中心,注册中心,负载集群...等等。代码和整体的框架还是很优雅滴呀!
     github地址 https://github.com/alibaba/dubbo
     文档地址:http://alibaba.github.io/dubbo-doc-static/Developer+Guide-zh.htm  
     目前发布的版本是2.5.3,gihub上的最新代码到2.5.4快照版本。很遗憾的是到dubbo的
维护团队没有继续维护下去呀!不过dubbo目前的功能已经算是灰常的完善了。可以说是一
整套的SOA治理方案了,完全能够用于生产环境之中啦。更多的详细使用,文档中写的灰常
的详细呀,过一遍文档就基本上搞明白啦!扯淡完了,进入正题。

     首先是最图最底部的为dubbo服务的集群(服务者),即对外界暴露服务,dubbo本身就
是支持集群模式,而且支持多种通信协议(dubbo,rmi,http...)。主要部署核心的业务代码。

 右边的注册中心,dubbo提供了也是提供了多种注册中心, zookeeper注册中心是其中一
种同样无单点故障问题,dubbo服务依赖于注册中心,在dubbo服务启动时,回向注册中心
去进行一个服务的注册(发布服务)。对服务进行管理。

    接下来看tomcat集群,主流的tomcat集群搭配(nginx+tomcat+redis/memcache)都是灰常
的简单的,百度google一下就能搞定。书写的所有控制器都放到其中,控制器中依赖的服
务实现是来之后端dubbo集群的,而dubbo服务是注册到zookeeper上的,只需要连上注册
中心就获取到了我们所需要的服务,并且进行调用。主要是对控制器层做一个集群,提高
可用性和性能。

    tomcat左下角是一个NOSQL集群,主要是处理一个session的共享/分布式缓存。
    最上层是nginx的集群主要是把静态页面全都放到nginx中即可,注意,如果使用restful风
格,并且使用JS MVC框架的话!完全不需要把页面部署到tomcat中,让tomcat只跑控制代
码即可。restful架构的话页面时全静态,数据全都走json的方式即可。

   上诉扩展瓶颈在nginx上,解决的方式就算使用在nginx之前套LVS吧,或者硬件做一个负
载。

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



查看mysql正在执行的SQL语句

$
0
0

1)我们先通过status命令查看Mysql运行状态

mysql> status;

--------------

mysql  Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1

 

Connection id: 113752

Current database: information_schema

Current user: push_user@localhost

SSL: Not in use

Current pager: stdout

Using outfile: ''

Using delimiter: ;

Server version: 5.1.73 Source distribution

Protocol version: 10

Connection: Localhost via UNIX socket

Server characterset: latin1

Db     characterset: utf8

Client characterset: latin1

Conn.  characterset: latin1

UNIX socket: /tmp/mysql.sock

Uptime: 22 days 8 hours 31 min 23 sec

 

Threads: 38  Questions: 1037751897  Slow queries: 2356  Opens: 79836  Flush tables: 1  Open tables: 64  Queries per second avg: 537.282

--------------

在上面显示列表的最后一条,我们来查看Slow queries这一项的值,如果多次查看的值大于0的话,说明有些查询sql命令执行时间过长。

 

2)这时再通过show processlist命令来查看当前正在运行的SQL,从中找出运行慢的SQL语句,找到执行慢的语句后,再用explain命令查看这些语句的执行计划。

 

mysql> show processlist;

+--------+-----------+---------------------+--------------------+---------+-------+-------+------------------+

| Id     | User      | Host                | db                 | Command | Time  | State | Info             |

+--------+-----------+---------------------+--------------------+---------+-------+-------+------------------+

|  50270 | ambari    | DataBase-01:41512   | ambari             | Sleep   |    23 |       | NULL             |

|  50271 | ambari    | DataBase-01:41511   | ambari             | Sleep   |     6 |       | NULL             |

|  50272 | ambari    | DataBase-01:41514   | ambari             | Sleep   |    23 |       | NULL             |

|  62452 | oozie     | DataBase-02:42987   | oozie              | Sleep   |    25 |       | NULL             |

|  63660 | ambari    | DataBase-01:56052   | ambari             | Sleep   |     0 |       | NULL             |

| 110404 | push_user | localhost:33817     | quartz             | Sleep   |    12 |       | NULL             |

| 112835 | push_user | localhost:46571     | hibernate          | Sleep   |     1 |       | NULL             |

| 113163 | push_user | localhost:56585     | hibernate          | Sleep   |     1 |       | NULL             |

| 113289 | push_user | 14.118.132.20:47333 | DW                 | Sleep   |   628 |       | NULL             |

| 113320 | push_user | localhost:47428     | hibernate          | Sleep   |     3 |       | NULL             |

| 113321 | push_user | localhost:47429     | hibernate          | Sleep   |     3 |       | NULL             |

| 113322 | push_user | localhost:47430     | hibernate          | Sleep   |     3 |       | NULL             |

| 113357 | push_user | localhost:52337     | hibernate          | Sleep   |     3 |       | NULL             |

| 113364 | push_user | localhost:57206     | hibernate          | Sleep   |     3 |       | NULL             |

| 113366 | push_user | localhost:34813     | hibernate          | Sleep   |     1 |       | NULL             |

| 113398 | push_user | localhost:37382     | hibernate          | Sleep   |     1 |       | NULL             |

| 113498 | push_user | localhost:47626     | quartz             | Sleep   | 12717 |       | NULL             |

| 113709 | push_user | localhost:59382     | hibernate          | Sleep   |     1 |       | NULL             |

| 113710 | push_user | localhost:33627     | hibernate          | Sleep   |     1 |       | NULL             |

| 113715 | hive      | DataBase-02:54968   | hive               | Sleep   |  2390 |       | NULL             |

| 113716 | hive      | DataBase-02:54969   | hive               | Sleep   |  2390 |       | NULL             |

| 113717 | hive      | DataBase-02:54974   | hive               | Sleep   |  2336 |       | NULL             |

| 113718 | hive      | DataBase-02:54975   | hive               | Sleep   |  2336 |       | NULL             |

| 113719 | push_user | localhost:48243     | hibernate          | Sleep   |     1 |       | NULL             |

| 113720 | push_user | localhost:48245     | hibernate          | Sleep   |     1 |       | NULL             |

| 113721 | push_user | localhost:48244     | hibernate          | Sleep   |     1 |       | NULL             |

| 113722 | push_user | localhost:48247     | hibernate          | Sleep   |     1 |       | NULL             |

| 113723 | push_user | localhost:48249     | hibernate          | Sleep   |     1 |       | NULL             |

| 113724 | push_user | localhost:48248     | hibernate          | Sleep   |     1 |       | NULL             |

| 113745 | push_user | localhost:50684     | hibernate          | Sleep   |     1 |       | NULL             |

| 113746 | push_user | localhost:50685     | hibernate          | Sleep   |     1 |       | NULL             |

| 113747 | push_user | localhost:50695     | hibernate          | Sleep   |     1 |       | NULL             |

| 113748 | push_user | localhost:50696     | hibernate          | Sleep   |     1 |       | NULL             |

| 113749 | push_user | localhost:50697     | hibernate          | Sleep   |     1 |       | NULL             |

| 113750 | push_user | localhost:50699     | hibernate          | Sleep   |     1 |       | NULL             |

| 113751 | push_user | localhost:50700     | hibernate          | Sleep   |     1 |       | NULL             |

| 113752 | push_user | localhost           | information_schema | Query   |     0 | NULL  | show processlist |

| 113753 | push_user | 14.118.132.20:28688 | DW                 | Sleep   |   396 |       | NULL             |

+--------+-----------+---------------------+--------------------+---------+-------+-------+------------------+

38 rows in set (0.00 sec)

或者通过如下命令查询:

mysql> use information_schema;

mysql> select * from PROCESSLIST where info is not null;

+--------+-----------+-----------+--------------------+---------+------+-----------+--------------------------------------------------+

| ID     | USER      | HOST      | DB                 | COMMAND | TIME | STATE     | INFO                                             |

+--------+-----------+-----------+--------------------+---------+------+-----------+--------------------------------------------------+

| 113752 | push_user | localhost | information_schema | Query   |    0 | executing | select * from PROCESSLIST where info is not null |

+--------+-----------+-----------+--------------------+---------+------+-----------+--------------------------------------------------+

 

1 row in set (0.00 sec)

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



进销存数据库表设计

$
0
0
CREATE TABLE user   /*用户表*/  
(  
  User_Id     varchar(6),  
  User_Pwd    varchar(8) NULL,  
  Again_Pwd   varchar(8) NULL,  
  Bel_Group   varchar(3) NULL,  
  Div_Type    varchar(1) NULL,  
  User_Auth   varchar(1) NULL,  
  Auth_Type   varchar(1) NULL,  
  User_Status varchar(1) NULL,  
  Create_User varchar(6) NULL,  
  Create_Date varchar(7) NULL,  
  Create_Time varchar(6) NULL,  
  Appr_User   varchar(6) NULL,  
  Appr_Date   varchar(7) NULL,  
  Appr_Time   varchar(6) NULL,  
  Pwd_Date    varchar(7) NULL,  
  Err_Count   float NULL,  
  Use_eJCIC   varchar(1) NULL  
) 
 
CREATE TABLE Supplier  /*供应商表*/  
(  
  Supplier_ID     int     IDENTITY(1,1)     NOT NULL, /* 供应商编号 ,主键 */  
  Name            varchar(250)              NOT NULL, /* 供应商名称 */  
  Address         varchar(250)              NOT NULL, /* 地址 */  
  Phone           varchar(25)               NULL,     /* 电话 */  
  Fax             varchar(25)               NULL,     /* 传真 */  
  PostalCode      varchar(10)               NULL,     /* 邮编 */  
  ConstactPerson  varchar(20)               NULL      /* 联系人 */  
 )  
  
CREATE TABLE Customer   /* 客户表*/  
(  
  Customer_ID     int    IDENTITY(1,1)      NOT NULL, /* 客户编号,主键*/  
  Name            varchar(250)              NOT NULL, /* 客户名称 */  
  Address         varchar(250)              NOT NULL, /* 地址 */   
  Phone           varchar(25)               NULL,     /* 电话 */  
  Fax             varchar(25)               NULL,     /* 传真 */  
  PostalCode      varchar(10)               NULL,     /* 邮编 */  
  ConstactPerson  varchar(20)               NULL      /* 联系人 */  
 )   
  
CREATE TABLE Dept      /*部门表*/  
(  
  Dept_ID        int   IDENTITY(1,1)        NOT NULL, /* 部门编号,主键 */  
  Name           varchar(30)                NOT NULL, /* 名称 */  
  Remark           varchar(250)               NOT NULL/* 描述,备注 */   
)  
  
CREATE TABLE Dept_Supplier /*部门--供应商表*/  
(  
  Dept_ID       int                         NOT NULL,  /* 部门编号,主键 ,  外键( 参照 DEPT 表  )*/  
  Supplier_ID   int                         NOT NULL   /* 供应商编号 ,主键,外键( 参照 SUPPLIER 表) */  
)  
  
CREATE TABLE Dept_Customer /*部门--客户表*/  
(  
  Dept_ID       int                         NOT NULL, /* 部门编号,主键 ,  外键( 参照 DEPT 表  )*/  
  Customer_ID   int                         NOT NULL  /* 客户编号,主键,  外键( 参照 SUPPLIER 表) */  
)  
  
CREATE TABLE StoreHouse   /* 仓库表 */  
(  
  StoreHouse_ID   int IDENTITY(1,1)         NOT NULL,  /* 仓库编号,主键 */  
  Address         varchar(250)              NOT NULL,  /* 地址 */  
  Phone           varchar(25)               NULL,      /* 电话 */  
  Employee_ID     INT                       NOT NULL,  /* 仓库保管 ,外键 ( 参照 EMPLOYEE 表 ) */  
  CreateDate      datetime                  NULL       /* 仓库成立时间 */  
)  
  
CREATE TABLE ProductClass  /* 商品总分类表 */  
(  
  ProductClass_ID  int IDENTITY(1,1)        NOT NULL,  /* 商品总分类编号, 主键 */   
  Name             varchar(30)              NOT NULL,  /* 商品分类名称 */  
  Employee_ID      INT                      NOT NULL,  /* 建分类人 ,外键 ( 参照 EMPLOYEE 表 )*/  
  CreateDate       datetime                 NULL,      /* 建分类时间 */  
  Remark           varchar(250)             NULL,    /* 描述,备注 */  
)  
  
CREATE TABLE ProductList  /* 商品细分类表 */  
(  
  ProductClass_ID  INT                      NOT NULL, /* 商品总分类编号, 外键 ( 参照PRODUCTCLASS 表 ) */  
  ProductList_ID   int IDENTITY(1,1)        NOT NULL, /* 商品细分类编号,主键 */  
  Name             varchar(30)              NOT NULL, /* 商品名称 */  
  Employee_ID      INT                      NOT NULL, /* 建分类人,外键 ( 参照 EMPLOYEE 表 )*/  
  CreateDate       datetime                 NULL,     /* 建分类时间 */  
  Remark           varchar(250)             NULL,   /* 描述 ,备注 */  
 )  
  
CREATE TABLE ProductSpec  /* 商品规格表 */  
(  
  ProductSpec_ID   INT IDENTITY(1,1)        NOT NULL, /* 商品规格编号,主键 */  
  Name             varchar(30)              NOT NULL, /* 商品规格名称 */  
  Employee_ID      INT                      NOT NULL, /* 操作员 ,外键 ( 参照 EMPLOYEE 表 )*/  
  CreateDate       datetime                 NULL,     /* 创建时间 */  
  Remark           varchar(250)           NULL    /* 描述,备注 */  
)
  
CREATE TABLE ProductUnit /* 商品计量单位表 */  
(  
  ProductUnit_ID   INT IDENTITY(1,1)        NOT NULL, /* 计量单位编号 ,主键 */  
  Name             varchar(30)              NOT NULL, /* 计量单位名称 */  
  Employee_ID      INT                      NOT NULL, /* 操作员 ,外键 ( 参照 EMPLOYEE 表 )*/  
  CreateDate       datetime                 NULL,     /* 创建时间 */  
  Remark           varchar(250)             NULL      /* 描述,备注 */  
)  
   
CREATE TABLE Product    /* 商品目录表 */  
(  
  ProductList_ID   int                      NOT NULL,  /* 商品细分类编号, 外键 ( 参照 PRODUCTLIST 表 ) */  
  Product_ID       INT IDENTITY(1,1)        NOT NULL,  /* 商品名称编号, 主键 */  
  Name             varchar(30)              NOT NULL,  /* 商品名称 */  
  ProductSpec_ID   INT                      NOT NULL,  /* 商品规格, 外键 ( 参照 PRODUCTSPEC 表 ) */  
  ProductUnit_ID   INT                      NOT NULL,  /* 计量单位, 外键 ( 参照 PRODUCTUNIT 表 ) */  
  Price            MONEY                    NULL,      /* 参考价格 */  
  Employee_ID      INT                      NOT NULL,  /* 操作员,   外键 ( 参照 EMPLOYEE 表 )*/  
  CreateDate       datetime                 NULL,      /* 创建时间 */  
  Remark             varchar(250)             NULL     /* 描述,备注 */  
)  
  
CREATE TABLE Product_Supplier  /* 商品--供应商表 */  
(   
  Product_ID       INT                      NOT NULL,   /* 商品名称编号,主键 , 外键( 参照 PRODUCT 表  )*/  
  Supplier_ID      INT                      NOT NULL    /* 供应商编号 , 主键,  外键( 参照 SUPPLIER 表) */  
)  
  
CREATE TABLE Employee         /* 员工表 */  
(   
  Employee_ID      INT IDENTITY(1,1)        NOT NULL,  /* 员工编号 */  
  Dept_ID          INT                      NOT NULL,  /* 所属部门编号 */  
  Name             varchar(30)              NOT NULL,  /* 姓名 */  
  Duty             varchar(20)              NOT NULL,  /* 职务 */  
  Gender           varchar(6)               NOT NULL,  /* 性别 */  
  BirthDate        datetime                 NOT NULL,  /* 出生日期 */  
  HireDate         datetime                 NULL,      /* 合同签订 日期 */  
  MatureDate       datetime                 NULL,      /* 合同到期日 */  
  IdentityCard     varchar(20)              NULL,      /* 身份证号 */  
  Address          varchar(250)             NULL,      /* 住址 */  
  Phone            varchar(25)              NULL,      /* 电话 */  
  Email            varchar(30)              NULL       /* E_MAIL */  
)  
   
CREATE TABLE BuyOrder         /* 进货合同 */  
(  
  BuyOrder_ID     INT IDENTITY(1,1)        NOT NULL, /* 进货合同编号 , 主键 */  
  WriteDate       datetime                 NOT NULL, /* 合同签订日期  */  
  InsureDate      datetime                 NOT NULL, /* 合同生效日期  */  
  EndDate         datetime                 NOT NULL, /* 合同到期日期  */  
  Dept_ID         INT                      NOT NULL, /* 签订部门, 外键 ( 参照 DEPT 表 ) */  
  Supplier_ID     INT                      NOT NULL, /* 供应商,   外键 ( 参照 SUPPLIER 表 ) */  
  Employee_ID     INT                      NOT NULL  /* 合同主要负责人, 外键 ( 参照 EMPLOYEE 表) */  
)  

CREATE TABLE BuyOrder_Detail  /* 进货合同明细表 */  
(  
  BuyOrder_ID     INT                      NOT NULL,  /* 进货合同编号,主键, 外键 ( 参照 BUYORDER 表 ) */  
  Product_ID      INT                      NOT NULL,  /* 所进商品编号,主键, 外键 (参照 PRODUCT 表 ) */   
  Quantity        INT                      NOT NULL,  /* 商品数量 */  
  Price           money                    NOT NULL   /* 商品进价 */  
)  
  
  
CREATE TABLE EnterStock    /* 入库单表 */  
(  
  EnterStock_ID    INT IDENTITY(1,1)       NOT NULL, /* 入库单编号 , 主键 */  
  EnterDate        datetime                NOT NULL, /* 入库时间 */  
  Dept_ID          INT                     NOT NULL, /* 入库部门 ,外键 ( 参照 DEPT 表 )*/  
  StoreHouse_ID    INT                     NOT NULL, /* 所入仓库 ,外键 ( 参照 STOREHOUSE 表)*/  
  Employee_ID      INT                     NOT NULL  /* 入库人 ,  外键 ( 参照 EMPLOYEE 表)*/  
  /*需添加 仓库保管员如何来验证入库单 ?? */  
)  
  
CREATE TABLE EnterStock_Detail /* 入库单明细 */  
(   
  EnterStock_ID    INT                     NOT NULL, /* 入库单编号 , 主键, 外键 (参照 ENTERSTOCK 表 )*/  
  Product_ID       INT                     NOT NULL, /* 此种商品编号,主键, 外键 (参照 PRODUCT 表 ) */   
  Quantity         int                     NOT NULL, /* 此种商品数量 */  
  Price            money                   NULL,     /* 此种商品参考价格  */  
  HaveInvoice      bit                     not null, /* 此种商品有没有开发票 ( 缺省为 0 , 有没有开票 )*/  
  InvoiceNum       varchar(30)             NULL      /* 发票号 */  
)  
  
  
CREATE TABLE BackStock  /* 退库单表 */  
(  
  BackStock_ID     INT IDENTITY(1,1)       NOT NULL, /* 退库单编号 , 主键 */  
  BackDate         datetime                NOT NULL, /* 退库时间 */  
  Dept_ID          INT                     NOT NULL, /* 退库部门 ,  外键 ( 参照 DEPT 表 )*/  
  StoreHouse_ID    INT                     NOT NULL, /* 所退入仓库 ,外键 ( 参照 STOREHOUSE 表)*/  
  Employee_ID      INT                     NOT NULL, /* 退库人 ,    外键 ( 参照 EMPLOYEE 表)*/  
  Remark           varchar(250)            NULL      /* 退库原因 */  
)  

CREATE TABLE BackStock_Detail /*退库单明细表*/  
(   
  BackStock_ID     INT                     NOT NULL, /* 退库单编号 , 主键, 外键 (参照 BACKSTOCK 表 )*/   
  Product_ID       INT                     NOT NULL, /* 所退商品编号,主键, 外键 (参照 PRODUCT 表 ) */   
  Quantity         int                     NOT NULL, /* 退入数量 */  
  Price            money                   NULL      /* 参考价格 */  
)  
  
CREATE TABLE LeaveStock  /* 出库单表 */  
(  
  LeaveStock_ID    INT IDENTITY(1,1)       NOT NULL,  /* 出库单编号 , 主键, 外键 (参照 LEAVESTOCK 表 )*/  
  LeaveDate        datetime                NOT NULL,  /* 出库时间 */   
  Dept_ID          INT                     NOT NULL,  /* 出库部门 ,  外键 ( 参照 DEPT 表 )*/  
  StoreHouse_ID    INT                     NOT NULL,  /* 所出仓库 ,外键 ( 参照 STOREHOUSE 表)*/  
  ToStoreHouse_ID  INT                     NOT NULL,  /* 所入仓库 ,外键 ( 参照 STOREHOUSE 表)*/  
  Employee_ID      INT                     NOT NULL   /* 出库人 ,    外键 ( 参照 EMPLOYEE 表)*/  
  /* 仓库保管员如何来验证出库单 ?? */  
)  
  
CREATE TABLE LeaveStock_Detail  /* 出库单明细表 */  
(   
  LeaveStock_ID    INT                     NOT NULL,  /* 出库单编号 , 主键, 外键 (参照 BACKSTOCK 表 )*/   
  Product_ID       INT                     NOT NULL,  /* 所出商品编号,主键, 外键 (参照 PRODUCT 表 ) */   
  Quantity         int                     NOT NULL,  /* 出库数量 */  
  Price            money                   NULL       /* 出库价格 */   
)  
  
CREATE TABLE BackSale  /* 退货单表 */  
(  
  BackSale_ID      INT IDENTITY(1,1)       NOT NULL,  /* 退货单编号 , 主键 */  
  BackDate         datetime                NOT NULL,  /* 退货日期  */   
  Dept_ID          INT                     NOT NULL,  /* 退货部门 ,  外键 ( 参照 DEPT 表 )*/  
  StoreHouse_ID    INT                     NOT NULL,  /* 退入仓库 ,  外键 ( 参照 STOREHOUSE 表)*/  
  Employee_ID      INT                     NOT NULL,  /* 退货人 ,    外键 ( 参照 EMPLOYEE 表)*/  
  Remark           varchar(250)            NULL       /* 退货原因 */  
  
)  
CREATE TABLE BackSale_Detail  /*退货单明细表*/  
(   
  BackSale_ID      INT                     NOT NULL,  /* 退货单编号 , 主键, 外键 (参照 BACKSTOCK 表 )*/   
  Product_ID       INT                     NOT NULL,  /* 所退商品编号,主键, 外键 (参照 PRODUCT 表 ) */   
  Quantity         int                     NOT NULL,  /* 退货数量 */  
  Price            money                   NULL       /* 价格 */   
)  
  
  
CREATE TABLE SaleOrder    /*销售合同*/  
(  
  SaleOrder_ID     INT IDENTITY(1,1)       NOT NULL,  /* 合同编号 , 主键 */  
  WriteDate        datetime                NOT NULL,  /* 合同签订日期  */  
  InsureDate       datetime                NOT NULL,  /* 合同生效日期  */  
  EndDate          datetime                NOT NULL,  /* 合同到期日期  */  
  Dept_ID          INT                     NOT NULL,  /* 签订部门, 外键 ( 参照 DEPT 表 ) */  
  Customer_ID      INT                     NOT NULL,  /* 客户编号, 外键 ( 参照 CUSTOMER 表 ) */  
  Employee_ID      INT                     NOT NULL   /* 合同主要负责人, 外键 ( 参照 EMPLOYEE 表) */  
)  

CREATE TABLE SaleOrder_Detail  /* 销售合同明细表 */  
(  
  SaleOrder_ID     INT                     NOT NULL,  /* 销售合同编号,主键, 外键 ( 参照 BUYORDER 表 ) */  
  Product_ID       INT                     NOT NULL,  /* 销售商品编号,主键, 外键 (参照 PRODUCT 表 ) */   
  Quantity         int                     not null,  /* 商品数量 */  
  Price            money                   null       /* 商品进价 */  
)  
  
  
CREATE TABLE Buy     /* 进货表(验货表)*/  
(  
   Buy_ID          INT IDENTITY(1,1)         NOT NULL, /* 进货编号 , 主键 */  
   ComeDate        datetime                  NOT NULL, /* 进货日期 */  
   Dept_ID         INT                       NOT NULL, /* 进货部门, 外键 ( 参照 DEPT 表 ) */   
   Employee_ID     INT                       NOT NULL  /* 验货人,   外键 ( 参照 EMPLOYEE 表)*/  
)  
  
CREATE TABLE Buy_Detail  /*进货表明细(验货表)*/    
(  
  Buy_ID           INT                      NOT NULL, /* 进货编号,主键, 外键 ( 参照 BUY 表 ) */  
  Product_ID       INT                      NOT NULL, /* 商品编号,主键, 外键 ( 参照 PRODUCT 表 ) */   
  BuyOrder_ID      INT                      NULL,     /* 采购合同,  外键 ( 参照 BUYORDER 表 ) */  
  Quantity         int                      not null, /* 数量 */  
  Price            money                    null      /* 价格 */  
  /* BUYORDER_ID 为 NULL 时, 为现金进货 */    
)  
  
CREATE TABLE Sale   /* 销售表*/  
(  
  Sale_ID          INT IDENTITY(1,1)        NOT NULL,  /* 销售 编号  */  
  SaleDate         datetime                 not null,  /* 销售 日期 */  
  Dept_ID          INT                      NOT NULL,  /* 销售部门, 外键 ( 参照 DEPT 表 ) */   
  Employee_ID      INT                      NOT NULL   /* 售货人,   外键 ( 参照 EMPLOYEE 表)*/  
)  
  
CREATE TABLE Sale_Detail  /* 销售明细 ( 验货表 ) */    
(  
  Sale_ID          INT                      NOT NULL,  /* 销售编号,主键, 外键 ( 参照 SALE 表 ) */  
  Product_ID       INT                      NOT NULL,  /* 商品编号,主键, 外键 ( 参照 PRODUCT 表 ) */    
  SaleOrder_ID     INT                      NULL,      /* 销售合同, 外键 ( 参照 SALEORDER 表 ) */  
  Quantity         int                      not null,  /* 数量 */  
  Price            money                    not null,  /* 价格 */  
  Discount         int                      null       /* 折扣 */  
  /* SALEORDER_ID 为 NULL 时, 为现金销售 */  
)  
  
  
CREATE TABLE StockPile  /* 库存表 */  
(   
  StockPile_ID     INT IDENTITY(1,1)        NOT NULL, /* 库存编号 , 主键 */  
  Dept_ID          INT                      NOT NULL, /* 商品所属部门, 外键 ( 参照 DEPT 表 ) */    
  StoreHouse_ID    INT                      NOT NULL, /* 所在仓库,     外键 ( 参照 SOTREHOUSE 表 ) */     
  Product_ID       INT                      NOT NULL, /* 商品编号,     外键 ( 参照 PRODUCT 表 ) */     
  FirstEnterDate   datetime                 not null, /* 此种商品第一次入库时间 */  
  LastLeaveDate    datetime                 null,     /* 此种商品最后一次出库时间 */  
  Quantity         int                      not null, /* 所存数量 */  
  Price            money                    not null  /* 加权价 */  
  /* LASTLEAVEDATE 为NULL 时,此种商品从来没有 卖过 */   
)  

 

 

转至:

http://blog.csdn.net/liaojiafan/article/details/4879178





已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



几个CSS重置默认样式reset.css代码

$
0
0
  因为各大浏览器存在兼容性问题,同一个CSS属性在不同浏览器下的表现不一定相同,有经验的前端设计者都会自定义一个重置浏览器默认样式的CSS文件,在这个文件中定义一些针对不同浏览器最终表现一致的代码,大家最为熟悉的也许就是*{margin:0 0}了,其实这是最简单照顾兼容性的代码,一般情况下,仅有这个是不够的,笔者收集了几个前端设计网站使用的reset.css代码,为您做参考,你可复制这些代码保存为reset.css文件,在每个页面中引入即可。

CSS重置浏览器样式代码一:
body,ul,li,p,h1,h2,h3,h4,h5,h6,img,br,hr,table,tr,td,dl,dt,dd,form {
	margin: 0;
	padding: 0;
}
body {
	font-family: Arial,"微软雅黑";
	font-size: 12px;
	color: #434343;
}
.clear {
	clear: both;
	font-size: 0px;
}
ul,li {
	list-style: none;
}
img {
	border: none;
}
/*一般链接*/
a {
	text-decoration: none;
	color: #555;
}
a: hover {
	color: #3366ff;
} 


CSS重置浏览器代码二:
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td { background: transparent; border: 0; margin: 0; padding: 0; vertical-align: baseline; font-size: 100%; font: inherit; -webkit-text-size-adjust: none; }
body { line-height: 1; }
table { border-collapse: collapse; border-spacing: 0; }
object, :focus { outline: none; }
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section /* HTML 5 */ { display: block; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
a img { border: none; }
input,button,textarea,select,optgroup,option{ font-size: 100%; font: inherit; }
.al { text-align: left; }
.ar { text-align: right; }
.ac { text-align: center; }
.lc { margin: 0 auto; }
.fl, .il .fl { float: left; }
.fr, .il .fr { float: right; }
.fc, .il .fc { float: none; clear: both; }
.rel { position: relative; }
.abs { position: absolute; }
.il { list-style: none; }
.il li { float: left; }


CSS重置浏览器代码三:来自Eric Meyer网站:
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font-weight: inherit;
	font-style: inherit;
	font-size: 100%;
	font-family: inherit;
	vertical-align: baseline;
}
: focus {
	outline: 0;
}
body {
	line-height: 1;
	color: black;
	background: white;
}
ol, ul {
	list-style: none;
}
table {
	border-collapse: separate;
	border-spacing: 0;
}
caption, th, td {
	text-align: left;
	font-weight: normal;
}
blockquote: before, blockquote: after,
q: before, q: after {
	content: "";
}
blockquote, q {
	quotes: "" "";
}


CSS重置浏览器代码四: Normalize.css,这是由 Nicolas Gallagher 和 Jonathan Neal 维护的一个CSS 重置样式库,Bootstrap采用。
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */

/**
 * 1. Set default font family to sans-serif.
 * 2. Prevent iOS text size adjust after orientation change, without disabling
 *    user zoom.
 */

html {
  font-family: sans-serif; /* 1 */
  -ms-text-size-adjust: 100%; /* 2 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/**
 * Remove default margin.
 */

body {
  margin: 0;
}

/* HTML5 display definitions
   ========================================================================== */

/**
 * Correct `block` display not defined for any HTML5 element in IE 8/9.
 * Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox.
 * Correct `block` display not defined for `main` in IE 11.
 */

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
  display: block;
}

/**
 * 1. Correct `inline-block` display not defined in IE 8/9.
 * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
 */

audio,
canvas,
progress,
video {
  display: inline-block; /* 1 */
  vertical-align: baseline; /* 2 */
}

/**
 * Prevent modern browsers from displaying `audio` without controls.
 * Remove excess height in iOS 5 devices.
 */

audio:not([controls]) {
  display: none;
  height: 0;
}

/**
 * Address `[hidden]` styling not present in IE 8/9/10.
 * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
 */

[hidden],
template {
  display: none;
}

/* Links
   ========================================================================== */

/**
 * Remove the gray background color from active links in IE 10.
 */

a {
  background: transparent;
}

/**
 * Improve readability when focused and also mouse hovered in all browsers.
 */

a:active,
a:hover {
  outline: 0;
}

/* Text-level semantics
   ========================================================================== */

/**
 * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
 */

abbr[title] {
  border-bottom: 1px dotted;
}

/**
 * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
 */

b,
strong {
  font-weight: bold;
}

/**
 * Address styling not present in Safari and Chrome.
 */

dfn {
  font-style: italic;
}

/**
 * Address variable `h1` font-size and margin within `section` and `article`
 * contexts in Firefox 4+, Safari, and Chrome.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/**
 * Address styling not present in IE 8/9.
 */

mark {
  background: #ff0;
  color: #000;
}

/**
 * Address inconsistent and variable font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` affecting `line-height` in all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sup {
  top: -0.5em;
}

sub {
  bottom: -0.25em;
}

/* Embedded content
   ========================================================================== */

/**
 * Remove border when inside `a` element in IE 8/9/10.
 */

img {
  border: 0;
}

/**
 * Correct overflow not hidden in IE 9/10/11.
 */

svg:not(:root) {
  overflow: hidden;
}

/* Grouping content
   ========================================================================== */

/**
 * Address margin not present in IE 8/9 and Safari.
 */

figure {
  margin: 1em 40px;
}

/**
 * Address differences between Firefox and other browsers.
 */

hr {
  -moz-box-sizing: content-box;
  box-sizing: content-box;
  height: 0;
}

/**
 * Contain overflow in all browsers.
 */

pre {
  overflow: auto;
}

/**
 * Address odd `em`-unit font size rendering in all browsers.
 */

code,
kbd,
pre,
samp {
  font-family: monospace, monospace;
  font-size: 1em;
}

/* Forms
   ========================================================================== */

/**
 * Known limitation: by default, Chrome and Safari on OS X allow very limited
 * styling of `select`, unless a `border` property is set.
 */

/**
 * 1. Correct color not being inherited.
 *    Known issue: affects color of disabled elements.
 * 2. Correct font properties not being inherited.
 * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
 */

button,
input,
optgroup,
select,
textarea {
  color: inherit; /* 1 */
  font: inherit; /* 2 */
  margin: 0; /* 3 */
}

/**
 * Address `overflow` set to `hidden` in IE 8/9/10/11.
 */

button {
  overflow: visible;
}

/**
 * Address inconsistent `text-transform` inheritance for `button` and `select`.
 * All other form control elements do not inherit `text-transform` values.
 * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
 * Correct `select` style inheritance in Firefox.
 */

button,
select {
  text-transform: none;
}

/**
 * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
 *    and `video` controls.
 * 2. Correct inability to style clickable `input` types in iOS.
 * 3. Improve usability and consistency of cursor style between image-type
 *    `input` and others.
 */

button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
  -webkit-appearance: button; /* 2 */
  cursor: pointer; /* 3 */
}

/**
 * Re-set default cursor for disabled elements.
 */

button[disabled],
html input[disabled] {
  cursor: default;
}

/**
 * Remove inner padding and border in Firefox 4+.
 */

button::-moz-focus-inner,
input::-moz-focus-inner {
  border: 0;
  padding: 0;
}

/**
 * Address Firefox 4+ setting `line-height` on `input` using `!important` in
 * the UA stylesheet.
 */

input {
  line-height: normal;
}

/**
 * It's recommended that you don't attempt to style these elements.
 * Firefox's implementation doesn't respect box-sizing, padding, or width.
 *
 * 1. Address box sizing set to `content-box` in IE 8/9/10.
 * 2. Remove excess padding in IE 8/9/10.
 */

input[type="checkbox"],
input[type="radio"] {
  box-sizing: border-box; /* 1 */
  padding: 0; /* 2 */
}

/**
 * Fix the cursor style for Chrome's increment/decrement buttons. For certain
 * `font-size` values of the `input`, it causes the cursor style of the
 * decrement button to change from `default` to `text`.
 */

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
 * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
 *    (include `-moz` to future-proof).
 */

input[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  -moz-box-sizing: content-box;
  -webkit-box-sizing: content-box; /* 2 */
  box-sizing: content-box;
}

/**
 * Remove inner padding and search cancel button in Safari and Chrome on OS X.
 * Safari (but not Chrome) clips the cancel button when the search input has
 * padding (and `textfield` appearance).
 */

input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * Define consistent border, margin, and padding.
 */

fieldset {
  border: 1px solid #c0c0c0;
  margin: 0 2px;
  padding: 0.35em 0.625em 0.75em;
}

/**
 * 1. Correct `color` not being inherited in IE 8/9/10/11.
 * 2. Remove padding so people aren't caught out if they zero out fieldsets.
 */

legend {
  border: 0; /* 1 */
  padding: 0; /* 2 */
}

/**
 * Remove default vertical scrollbar in IE 8/9/10/11.
 */

textarea {
  overflow: auto;
}

/**
 * Don't inherit the `font-weight` (applied by a rule above).
 * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
 */

optgroup {
  font-weight: bold;
}

/* Tables
   ========================================================================== */

/**
 * Remove most spacing between table cells.
 */

table {
  border-collapse: collapse;
  border-spacing: 0;
}

td,
th {
  padding: 0;
}



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



数据压缩与信息熵

$
0
0

1992年,美国佐治亚州的WEB Technology公司,宣布做出了重大的技术突破。

该公司的DataFiles/16软件,号称可以将任意大于64KB的文件,压缩为原始大小的16分之一。业界议论纷纷,如果消息属实,无异于压缩技术的革命。

数据压缩

许多专家还没有看到软件,就断言这是不可能的。因为根据压缩原理,你不可能将 任意文件压缩到16分之一。事实上,有一些文件是无法压缩的,哪怕一个二进制位,都压缩不掉。

后来,事实果然如此,这款软件从来没有正式发布。没过几年,就连WEB Technology公司都消失了。

那么,为何不是所有的文件都可以被压缩?是否存在一个压缩极限呢,也就是说,到了一定大小,就没法再压缩了?

一、压缩的有限性

首先,回答第一个问题:为什么WEB Technology公司的发明不可能是真的。

反证法可以轻易地证明这一点。假定任何文件都可以压缩到n个二进制位(bit)以内,那么最多有2 n种不同的压缩结果。也就是说,如果有2 n+1个文件,必然至少有两个文件会产生同样的压缩结果。这意味着,这两个文件不可能无损地还原(解压缩)。因此,得到证明,并非所有文件都可以压缩到n个二进制位以下。

很自然地,下一个问题就是,这个n到底是多少?

二、压缩原理

要回答一个文件最小可以压缩到多少,必须要知道压缩的原理。

压缩原理其实很简单,就是找出那些重复出现的字符串,然后用更短的符号代替,从而达到缩短字符串的目的。比如,有一篇文章大量使用"中华人民共和国"这个词语,我们用"中国"代替,就缩短了5个字符,如果用"华"代替,就缩短了6个字符。事实上,只要保证对应关系,可以用任意字符代替那些重复出现的字符串。

本质上,所谓"压缩"就是找出文件内容的概率分布,将那些出现概率高的部分代替成更短的形式。所以,内容越是重复的文件,就可以压缩地越小。比如,"ABABABABABABAB"可以压缩成"7AB"。

相应地,如果内容毫无重复,就很难压缩。极端情况就是,遇到那些均匀分布的随机字符串,往往连一个字符都压缩不了。比如,任意排列的10个阿拉伯数字(5271839406),就是无法压缩的;再比如,无理数(比如π)也很难压缩。

压缩就是一个消除冗余的过程,相当于用一种更精简的形式,表达相同的内容。可以想象,压缩过一次以后,文件中的重复字符串将大幅减少。好的压缩算法,可以将冗余降到最低,以至于再也没有办法进一步压缩。所以,压缩已经压缩过的文件(递归压缩),通常是没有意义的。

三、压缩的极限

知道了压缩原理之后,就可以计算压缩的极限了。

上一节说过,压缩可以分解成两个步骤。第一步是得到文件内容的概率分布,哪些部分出现的次数多,哪些部分出现的次数少;第二步是对文件进行编码,用较短的符号替代那些重复出现的部分。

第一步的概率分布一般是确定的,现在就来考虑第二步,怎样找到最短的符号作为替代符。

如果文件内容只有两种情况(比如扔硬币的结果),那么只要一个二进制位就够了,1表示正面,0表示表示负面。如果文件内容包含三种情况(比如球赛的结果),那么最少需要两个二进制位。如果文件内容包含六种情况(比如扔筛子的结果),那么最少需要三个二进制位。

一般来说,在均匀分布的情况下,假定一个字符(或字符串)在文件中出现的概率是p,那么在这个位置上最多可能出现1/p种情况。需要log 2(1/p)个二进制位表示替代符号。

这个结论可以推广到一般情况。假定文件有n个部分组成,每个部分的内容在文件中的出现概率分别为p 1、p 2、...p n。那么,替代符号占据的二进制最少为下面这个式子。

log 2(1/p 1) + log 2(1/p 2) + ... + log 2(1/p n)

= ∑ log 2(1/p n)

这可以被看作一个文件的压缩极限。

四、信息熵的公式

上一节的公式给出了文件压缩的极限。对于n相等的两个文件,概率p决定了这个式子的大小。p越大,表明文件内容越有规律,压缩后的体积就越小;p越小,表明文件内容越随机,压缩后的体积就越大。

为了便于文件之间的比较,将上式除以n,可以得到平均每个符号所占用的二进制位。

∑ log 2(1/p n) / n

= log 2(1/p 1)/n + log 2(1/p 2)/n + ... + log 2(1/p n)/n

由于p是根据频率统计得到的,因此上面的公式等价于下面的形式。

p 1*log 2(1/p 1) + p 2*log 2(1/p 2) + ... + p n*log 2(1/p n)

= ∑ p n*log 2(1/p n)

= E( log 2(1/p) )

上面式子中最后的E,表示数学期望。可以理解成,每个符号所占用的二进制位,等于概率倒数的对数的数学期望。

下面是一个例子。假定有两个文件都包含1024个符号,在ASCII码的情况下,它们的长度是相等的,都是1KB。甲文件的内容50%是a,30%b,20%是c,则平均每个符号要占用1.49个二进制位。

0.5*log 2(1/0.5) + 0.3*log 2(1/0.3) + 0.2*log 2(1/0.2)

= 1.49

既然每个符号要占用1.49个二进制位,那么压缩1024个符号,理论上最少需要1526个二进制位,约0.186KB,相当于压缩掉了81%的体积。

乙文件的内容10%是a,10%是b,......,10%是j,则平均每个符号要占用3.32个二进制位。

0.1*log 2(1/0.1)*10

= 3.32

既然每个符号要占用3.32个二进制位,那么压缩1024个符号,理论上最少需要3400个二进制位,约0.415KB,相当于压缩掉了58%的体积。

对比上面两个算式,可以看到文件内容越是分散(随机),所需要的二进制位就越长。所以,这个值可以用来衡量文件内容的随机性(又称不确定性)。这就叫做信息熵(information entropy)。

它是1948年由美国数学家 克劳德·香农(Claude Shannon)在经典论文 《通信的数学理论》中,首先提出的。

Claude Shannon

五、信息熵的含义

想要理解信息熵这个概念,有几点需要注意。

(1)信息熵只反映内容的随机性,与内容本身无关。不管是什么样内容的文件,只要服从同样的概率分布,就会计算得到同样的信息熵。

(2)信息熵越大,表示占用的二进制位越长,因此就可以表达更多的符号。所以,人们有时也说,信息熵越大,表示信息量越大。不过,由于第一点的原因,这种说法很容易产生误导。较大的信息熵,只表示可能出现的符号较多,并不意味着你可以从中得到更多的信息。

(3)信息熵与热力学的熵,基本无关。这两个熵不是同一件事,信息熵表示无序的信息,热力学的熵表示无序的能量(参见我写的 《熵的社会学意义》)。

(文章完)

=====================================================

以下为广告部分。欢迎大家在我的网络日志 投放广告,推广自己的产品。今天介绍的是 生命链记忆网

[赞助商广告]

别人的终究是别人的,今天我们书写自己的传奇!个人史是汇入正史河流的涓涓细流。

生命链记忆网是永远在线的个人史馆,是永恒的信息载体,永久保留每个人的人生记忆和生命轨迹直至千秋万代。

花一分钟成为 注册用户,就可以使用两大基本功能: 生命链生命之书

(1) 生命链就是你的根,你可以邀请祖先(父系和母系)及子女合链,让自己的生命链有形化、可视化;所有血亲和姻亲成员之间可互动。

图1

(2) 生命之书就是书写你的人生故事,包括日记、自传、随笔等等;自传可选择公开,在自传馆里能被所有人看到。

图2

生命链功能永久免费!

生命之书功能每年付费10元,可使用100M空间(免费试用6个月);累计付费1000元,生命之书永久开启。

永恒之旅,从此开始, 点击试用

(完)

文档信息

软件质量之道

$
0
0

        我曾与一些资历非常高但毫无实际经验的人共事过,也曾与一些只有很少或根本没有资历但才华横溢的工程师一起工作过,我也曾经不得已跟一些并不想用心做事、也对学习新东西丝毫不感兴趣的人共事过。如果说我们这个职业是一张纸,那么这些人就好比纸上的污点。软件开发业的低劣性不能完全怪罪于那些无知的经理、狡猾的市场营销人员以及总是急不可耐的用户,实际上很大程度上要归咎于这个行业的某些从业人员,他们应该去从事一些即使玩忽职守也不会造成像软件业里这样大的危害的行当,而不应该混迹于这个聚集着人类想象力的最复杂的创造性的行业。

-- MatthewWilson

 

1 引子

        最近,有同事请教了我一些关于软件质量的相关问题,很抱歉我没能给出一个较好的答案。主要原因是,这两年来,一直忙碌在基本知识的学习总结上,虽然也接触了很多这方面的内容,却没有一个很好的总结以及记录,对此深表惭愧。

        这一次的项目的启动会议上,听说了小韩的这么一句话,大概是这样子的,“我们作为一个互联网公司,不但要做一个优秀的产品,还要从产品上去教育群众,引导社会”。加上这段时间看到前面Matthew Wilson的这段话,觉得自己作为这个行业的一员,肩负着重大的责任。

        所以,借此机会,对这两年来关于亲身经历过的软件质量管理进行总结。另外,声明一下,首先,这只是我对这方面的一些思考,可能跟其他人的想法不同,如果有其他想法的同学们,我们可以进行讨论学习,以求共同进步;其次,个人观点难免会和其他人发生冲突,如果对读者们造成了冒犯,还请多多原谅和多多指教;最后,我是非常喜欢讨论的一个人,因为每次讨论都会有丰富的收获,如果有同学们进行讨论学习,我非常高兴!

        这部分跟整个主题(PerfectC++)可能不太符合,但是每一门语言都应该有对应的质量管理方式,毕竟每个软件都不能保证没有Bug,所以软件质量也是重中之重,根本之根本。所以我依旧将其列入Perfect C++的一部分,但是内容应该也适用于大部分语言。

 

2 软件质量

        说道软件质量,首先是如何进行衡量呢?我想大部分人想到的最简单的一个衡量标准就是:这个软件有多少个Bug?

        这样简单的标准,其实是错误的。第一,软件的Bug是不能进行统计的,因为在不同场合下,不同情境下,都可能存在Bug,但是这个数量却是无法衡量的。第二,质量不能单靠“错误”来衡量,例如说软件的执行效率等等,也应该作为标准之一。

        说到这部分,我也只能引用《代码大全》中的相关部分了(第20章软件质量概述)。其中,软件质量从外在特征,即用户角度来说,包括:正确性、可用性、效率、可靠性、完整性、适应性、精确性和健壮性;从内在特征,即代码角度来说,包括:可维护性、灵活性、可移植性、可重用性、可读性、可测试性和可理解性等方面。

 

2.1 外在特征

        关于外在特征,是我们经常关注的部分,因为站在用户的角度来说,这就是用户最关注的部分,用户关心的,自然是我们最看重的。但是软件质量并不能将这些细节都进行多度的处理,过于关注某个细节,就会对其他方面产生一定的影响,大概情况如下表:

 

正确性

可用性

效率

可靠性

完整性

适应性

精确性

健壮性

正确性

 

 

 

可用性

 

 

 

 

 

效率

 

 

可靠性

 

 

 

完整性

 

 

 

 

 

适应性

 

 

 

 

 

精确性

 

 

健壮性

        当然这只是一些典型关系,在不同的项目中,可能影响恰好是相反的。

 

2.2 内在特征

        作为一名开发人员,应该对内在特征进行思考。据我所知,其实大部分人是没有关注这部分的,而这部分的影响又是非常大的。而这部分又是外在特征的根本之所在,从我的角度来理解,内在特征管理到位,会大幅度提高软件质量。

 

2.3 普遍原理

         说了这么多,可能有很多人不是很在意软件质量这个话题,但是想一下,一个人每天平均写多少行代码呢?其他时间都在干什么呢?我想大部分时间都是在调试,定位Bug,解决,再测试吧。

        提高生产效率和改善质量的最佳途径就是减少花在这种代码上的返工时间,无论返工的代码是由需求、设计改变还是调试引起的。

        另外,要为软件添加一个功能,时间消耗又是多少呢?我想一个与整体毫无关联的功能添加要比在一个复杂逻辑的功能里面追加要简单的多吧。

        所以,效果明显的缩短开发周期的办法就是改善产品的质量,由此减少花费在调试和软件返工上的时间。

        当然,上面这两点都是在大量数据上得到的结论,具体请参考《代码大全》第20.5章节:软件质量的普遍原理。

 

3 改善软件质量的技术

        总说些不实用的话,很没意思,所以赶紧跳过前面的凉菜,开始上硬菜!

 

3.1 主要方法

        既然软件质量分为这么多方面,那到底该如何改善呢?改善的方法主要有:

        1> 确定明确的软件质量目标。首先要有明确的目标,如果目标不制定,那就如沙漠中行军,最后也是全部灭亡的效果。

        2> 确定保证这些目标要做的工作。其次,为了达到这些目标应该展开那些工作?只有目标,没有工作计划,相当于在原地休息,效果也是一样的。

        3> 确定明确的测试策略。测试不能改善软件质量(这个跟现在工作的状况恰好相反,真是让我无力吐槽),根据测试结果来评估和改善软件质量,就是大海捞针而已,捞到捞不到只能看运气,并且还会导致测试人员苦不堪言。测试人员一定要提出明确的测试策略,不能将“测试”作为改善软件质量的首要方法。

        4> 确定明确的需求定义。需求定义一定要明确,很多情况下,需求人员定义的跟用户想得到的恰好相反,这样的开发都是无用功。

        5> 确定明确的开发工程指南。开发工程指南包括上面各个方面的定义,应当控制软件的技术特征,贯彻所有开发活动之中,例如说代码规范就是一个典型的代表。

        6> 代码复查。这个工作非常重要,不但可以发现大量的问题,还可以一定程度上提高人员的技术质量,但也有一些复查很不到位,过分关注细节,投入成本过高,收获却很少。

 

3.2 常用技术及Bug检出率

        下面是一些常用的技术和对应检出Bug的检测率,可以有一个直观的了解。

检错措施

最低检出率

典型检出率

最好检出率

非正式设计复查

25%

35%

40%

正式设计复查

45%

55%

65%

非正式代码复查

20%

25%

35%

正式代码复查

45%

60%

75%

个人代码复查

20%

40%

60%

单元测试

15%

30%

50%

组件测试

20%

30%

35%

集成测试

25%

35%

40%

回归测试

15%

25%

30%

系统测试

25%

40%

55%

小规模Beta测试(10人以下)

25%

35%

40%

大规模Beta测试(1000人以上)

60%

75%

85%

        上面的这些数据,应该是每一个测试人员都应该了解的。测试经理也并不是只是简简单单安排估算一下测试用例条数,分配用例编写,安排人员进行测试,提交Bug而已。按照我个人的理解,确定软件质量才是一个测试经理首要任务,测试只不过是其中最最基本的之一。如果单靠测试,那么每个刚毕业的学生,经过几个月,哪怕是几个星期的培训即可胜任,不提升自己的技能,后果大家都知道的。

        下面分别针对上面的各个目标,为大家带来一些工具和经验的分析。当然这些也只在我的经验范围之内,欢迎大牛前来补充。

 

4 软件质量的基本目标

        提到软件质量目标,首要要明确合格的代码有哪些要求,主要指标如下:

        1> 总行数:包括空行在内代码的行数。

        2> 函数圈复杂度:圈复杂度是指一个函数可执行路径的数目。以下语句为圈复杂度的值贡献为1,if/else/for/while语句,三元运算符语句,if/for/while判断条件中的||或&&,switch语句,后接break/goto/return/throw/continue语句的case语句,catch/except语句等。

        3> 函数深度:函数深度指示函数中分支嵌套的层数。

        4> 语句数目:在C++语言中,语句是以分号结尾的。分支语句if,循环语句for/while,跳转语句goto都被计算在内,预处理语句#include/#define/#undef也被计算在内,对其他的预处理语句则不做计算,在#else/#elif/#endif之间的语句将被忽略。

        5> 分支语句比例:该值表示分支语句占语句数目的比例,这里的“分支语句”指的是使程序不顺序执行的语句,包括if/else/for/while/switch。

        6> 注释比例:该值指示注释行占总行数的比例。

        7> 函数数目:函数的数量。

        8> 平均每个函数包含的语句数目:总的函数语句数目除以函数的数目。

        第一个要介绍的软件为Source Monitor,这是一个代码质量检测的基本工具,即计算上述指标的工具。

        对于开发人员来说,可以将其添加到Visual Studio、UltraEdit等等一系列的编辑工具中,具体添加方式可以参考Source Monitor的文档。而测试人员需要了解如何使用命令行模式,建立一个工程,并筛选出不符合要求的目标。

        下面是一个参考目标(来自于华为):

        1> 圈复杂度7以下;

        2> 最大行数1000以下;

        3> 每个类最大方法数30以下;

        4> 每个方法最大行数50以下;

        5> 最大深度5以下。

 

5 代码质量的基本目标

        对于C++来说,检查其代码质量非常困难,尤其含有大量的指针,模板等方面,所以可以看到的代码分析工具并不多,一般大多采用PCLint进行静态代码检查。

        PCLint是一个非常严格的编译器,可以发现很多编译器并不提醒的错误,以次来提高代码的质量,例如说识别内存越界问题,未初始化的变量,空指针操作,冗余的代码,执行效率问题等等。

        对于开发人员,每次提交代码,都必须执行PCLint,保证修改代码的安全性。对于测试人员,应该配置PCLint执行环境,定期对代码进行扫描检查,为开发人员提出警告。

        PCLint的基本目标即无编译Error和Warning。

 

6 测试目标

6.1 单元测试

        这里提到的测试为单元测试,即开发人员主要关心的方面。但是需要测试人员进行管理控制。

        理论上,凡是圈复杂度大于2的函数,都应该进行相关的单元测试的编写。具体编写的任务一般由该函数的作者进行完成,当然也有很多测试驱动开发的例子,但是这对一般的测试人员要求过高,需要对整体的框架以及代码非常了解,能够明确定义开发框架和函数才能胜任,所以就不过多赘述。

        单元测试的工具,目前大多采用GTest、GMock以及MockCpp这几个,mock工具只需选择其一即可。

        在这个环节,开发人员每次添加函数,如果圈复杂度较高,需要添加对应的测试函数。而测试人员应该每次构建时进行冒烟测试,保证所有测试函数通过,另外,应该结合圈复杂度的基准,如果圈复杂度较高却没有测试函数的,应该给与警告。

 

6.2 系统测试

        这个方面需要测试人员关心,主要工具可以采用Visual Studio中集成的测试工程,然后录制脚本,通过执行脚本,达到系统测试的目的。

        一般测试之前需要测试用例的编写任务,这个任务以前是开发人员进行编写,这样针对代码的修改量,修改范围,用例可以写的非常详细,针对性也非常强。参考基准目标为:测试用例数目/代码修改行数 = 1/3。

        测试结束,进行正式版本发布时的标准应为:失败测试用例数目/有效测试用例总条数< 3%。当然,进行测试版本发布时,可以针对不同方面调节这个值的大小。

        如果不满足版本发布要求,应该针对Bug修改代码,进行测试用例的追加,直到符合该范围的要求,才能进行版本发布。

        由于我不是测试人员,所以对系统测试这方面了解不是很多,包括可以用的工具进行自动化测试等,如果有大牛有经验,欢迎指教。

 

7 需求明确目标

        这一点主要依赖于产品评审会议,组织产品人员、开发人员、测试人员、用户等进行产品需求的评审。这样可以明确需求,同时可以精化需求,降低开发时间,快速进行迭代,推动产品的前进。

        由于我对这方面的理解不是很深,欢迎有深刻理解的同学进行补充。

 

8 集成构建

        前面针对软件质量的各个方面的目标和达到目标的方法进行了描述,当然没有代码复查的相关部分,这个一般不同的公司组织方式不一,在这里不进行赘述了。但是要把上面这几部分综合起来,进行自动化的控制,每天,或者每次代码提交都进行检查,那么就可以大幅度减少人力,大家也可以抽出时间来进行交流学习,继续提升自己,岂不是很好吗?

        既然说到这,达到目标自然也是可能的。首先,需要自动构建管理工具:Cruise Control,这个工具分为.Net版和Java版,当然最好还是选择后者,因为可以进行搭配使用的工具很多。这个工具的主要功能是,提供一个服务器端,用户进行任务的配置,例如说编译,各个目标的检查,最后按照时间或者代码的更新,执行各个任务的检查,将失败的任务告诉用户。

        其次,各个任务的执行,可以使用Ant,Ant是基于Java的一个build工具,使用Ant可以指定编译期间不同的任务,然后Cruise Control中指定这些任务,就可以达到了自动化执行的目的。

        最后,结果的统计与表示。Cruise Control只是一个管理工具,具体的数据需要测试人员进行收集,并统计对应的部分。例如本月一共提交了多少个用例,有多少执行失败了,等等这样可以表示描述软件质量的信息。为了达到这个目标,一般测试人员都需要掌握一种或多种脚本语言。



9 进一步思考

        软件行业发展了这么多年,大家都追随在“敏捷”之后,我没有从上一个时代走过,不能说这真的是“快了”还是“慢了”,质量到底是“高了”还是“低了”,大家都在拼命的赶时间,赶进度,赶版本。

        最近总想写点什么,总结点什么,话题很多,自己却认识很浅薄,常识被那些大牛们践踏的不敢说对还是错,只感觉路越来越长,感谢这些伟人们,开拓了这条不归路,我还有走完的那一天么?

        时代在改变,技术在进步,即使没有坐上最后一趟技术潮流的末班车,我们也应该步行走向未来!
作者:winking324 发表于2014-9-7 16:35:23 原文链接
阅读:189 评论:3 查看评论

heipark------hadoop性能调优笔记

$
0
0

Hadoop调优

mapred.tasktracker.map.tasks.maximum

 

官方解释:The maximum number of map tasks that will be run  simultaneously by a task tracker.

 

我的理解:一个tasktracker最多可以同时运行的map任务数量

 

默认值:2

 

优化值:mapred.tasktracker.map.tasks.maximum = cpu数量

 

cpu数量 = 服务器CPU总核数 / 每个CPU的核数
服务器CPU总核数 = more /proc/cpuinfo | grep 'processor' | wc -l
每个CPU的核数 = more /proc/cpuinfo | grep 'cpu cores'

mapred.map.tasks

官方的解释:The default number of map tasks per job

 

我的解释:一个Job会使用task tracker的map任务槽数量,这个值 ≤ mapred.tasktracker.map.tasks.maximum

 

默认值:2

 

优化值:

  1. CPU数量 (我们目前的实践值)
  2. (CPU数量 > 2) ? (CPU数量 * 0.75) : 1  (mapr的官方建议)

 

注意:map任务的数量是由input spilit决定的,和上面两个参数无关

mapred.tasktracker.reduce.tasks.maximum

 

官方解释:The maximum number of reduce tasks that will be run  simultaneously by a task tracker.

 

我的理解:一个task tracker最多可以同时运行的reduce任务数量

 

默认值:2

 

优化值: (CPU数量 > 2) ? (CPU数量 * 0.50): 1 (mapr的官方建议)

mapred.reduce.tasks

 

官方解释:The default number of reduce tasks per job. Typically set to 99%  of the cluster's reduce capacity, so that if a node fails the reduces can  still be executed in a single wave.

 

我的理解:一个Job会使用task tracker的reduce任务槽数量

 

默认值:1

 

优化值:

  • 0.95 * mapred.tasktracker.tasks.maximum

理由:启用95%的reduce任务槽运行task, recude task运行一轮就可以完成。剩余5%的任务槽永远失败任务,重新执行

  • 1.75 * mapred.tasktracker.tasks.maximum

理由:因为reduce task数量超过reduce槽数,所以需要两轮才能完成所有reduce task。具体快的原理我没有完全理解,上原文:

 

     hadoop官方wiki: 写道

At 1.75 the faster nodes will finish their first round of reduces and launch a second round of reduces doing a much better job of load balancing.

 

环境变量

disable ipv6配置,修改bin/hadoop,添加下行:

 

 

HADOOP_OPTS="$HADOOP_OPTS -Djava.net.preferIPv4Stack=true"

 

Hive调优:

 

mapred.reduce.tasks

 

官方 写道
The default number of reduce tasks per job. Typically set
to a prime close to the number of available hosts. Ignored when
mapred.job.tracker is "local". Hadoop set this to 1 by default, whereas hive uses -1 as its default value.
By setting this property to -1, Hive will automatically figure out what should be the number of reducers.

 

 

我的理解
tasktracker执行hive job的reduce任务数,设置为"-1"hive将自动设置该值,策略如下:

1. hive.exec.reducers.bytes.per.reducer(默认为1GB)
2. hive.exec.reducers.max(默认为999)

mapred.reduce.tasks = min ( 参数2,总输入数据量/参数1 )

 

默认值:-1

 

优化值:显式设置为Hadoop配置中mapred.reduce.tasks值,参考上文。

 

参考资料:

 




 

http://wiki.apache.org/hadoop/HowManyMapsAndReduces

http://www.mapr.com/doc/display/MapR/mapred-site.xml

http://hi.baidu.com/dtzw/blog/item/5b64880aaf057d33b0351db4.html

http://www.tbdata.org/archives/622

http://developer.yahoo.com/hadoop/tutorial/module7.html

 

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




盖茨有改革历史教育的良策

$
0
0
2008年,卸任执行官一职的盖茨早晨都要在跑步机上跑一小时,在此期间他会观看Teaching Company出品的“大课程”系列DVD,他偶然看起了一套冠名为“大历史”的DVD。在视频课程中,大历史没有专注于特定主题,而是结合了历史、生物、化学、天文学等不同领域的知识,演讲人David Christian教授从八个不同的时期讲述地球历史,从宇宙大爆炸到智人到农业到现代世界。他的大历史教育是受到了法国历史学派年鉴学派的启发,年鉴学派坚持认为应该从多个时空尺度去探索历史。这套“大历史”DVD给盖茨留下了深刻影响,认为应该向美国学校推广。作为一名亿万富翁,他有足够的资本。大历史教育项目在盖茨基金会的资助下正式启动,上个月加州大学系统宣布承认大历史教育课程,为其推广到加州1300所高中铺平了道路。但不是所有人都认同盖茨。纽约大学的Diane Ravitch说,这门课是否应该标记为“比尔盖茨的历史”,因为亿万富翁看到的历史和非亿万富翁大不相同?在批评者看来,比尔盖茨不是真正的专家,他只是恰好看了DVD,认为是个好主意,他也有足够的钱资助它。






从程序员到项目经理:项目管理三大目标

$
0
0

从程序员到项目经理:项目管理三大目标

项目管理的三大目标即时间、成本和质量,实际是告诉项目经理应重点关注什么因素,项目控制应该做什么工作。三大目标虽然简单,但如果能将其真正贯彻到自己的行动中,那么对项目计划制定、过程控制等工作,均能起到引导作用。有了努力的方向,项目经理也就可以真正告别“盲目”了。

1.我的第一次顿悟

(1)懂三大目标才算入门

我曾经也是一个混沌型的项目经理,每天浑浑噩噩,不要知要管什么,要做什么,在项目的大浪中随波逐流。直到有一天,我的上司在跟我聊天时说到项目有三大目标:时间、成本和质量,我当时就像被雷击一般,如梦初醒。时间、成本、质量,这不正是项目经理最应该要关注的事情吗?

这是我在项目管理方面的第一次顿悟。从这一天起,我才感觉自己像一个真正的项目经理了。也正是从这一天起,我才明白原来项目管理是有章可循的,我买来了项目管理的书籍,参加了项目管理培训,开始了新一轮如饥似渴的学习。

后来在工作中我每天都尝试着问自己这些问题:

l 时间:项目计划在什么时候完成?有哪些工作,分别在什么时候完成?是否发生了偏差?如果有偏差,怎么处理?

l 成本:项目计划花多少钱?每项子任务分别打算用多少钱(多少人月)来完成?是否发生了偏差?如果有偏差,怎么处理?

l 质量:软件功能完整吗?软件操作方便吗?运行结果正确吗?运行效率够快吗?软件代码符合规范吗?客户用起来满意吗?

我想如果能做到这些,项目管理也就算入门了。项目经理只有心中时刻谨记三大目标,行动才会有方向,才能真正主动、有意识的管理项目,也才能算是一个真正的项目经理。

(2) 三大目标就是“快好省”

项目管理的三大目标,其实是项目管理九大领域中的三块,分别代表花多少钱、多少时间、做成什么样,显然这些都是项目管理中至关重要的问题,如果项目经理连这三个问题都不关心,那也就没有什么可以关心的了。

周总理曾经提出要“多快好省的建设社会主义”,三大目标实际上与“快好省”是一致的。为什么没有多呢,因为“多”绝不是项目管理的目标,项目只需要完成规定的内容即可,如果以“多”为目标,那么项目永远都没有完工的一天。

(3)谁在关心三大目标

既然是三大目标,那应该是项目各方都非常关心的,其实不然。三大目标是平衡了项目业主方和承建方双方利益,为实现双方而综合考虑的结果。比如成本,就是花出去的钱,显然是承建方的命根子,但是业主方并不关心,签订合同后,你花多少钱跟他们有什么关系呢?他们才懒得理呢。而质量,虽然对业主方至关重要,但承建方却往往并不上心。为什么有那么多豆腐渣工程,就是因为承建方只关注成本,不关心质量的后果。

 

三大目标

买方(业主方)

卖方(承建方)

成本

合同签订后,项目实施成本基本上与客户无关。

关心程度:0星

成本要尽量低,对公司至关重要。

关心程度:5星

进度

要快,尽早投入使用。

关心程度:4星

要快,可尽早回收款项。

关心程度:4星

质量

质量越高,使用越爽。

关心程度:5星

质量越高,成本越高,质量太低不能验收。公司被迫关心质量。

关心程度:3星

 

从上表可以看出,业主方和承建方其实是存在一定的利益冲突的。项目经理必须能够平衡好双方的利益关系,要使双方都满意。时间、成本和质量,就像是构成木桶的三块板子,哪块板上有洞,木桶都是装不了水的。

2.从三大目标到五大因素

所谓项目五大因素,就是项目三大目标加上范围和资源,它们是构成项目的基本要素。虽然管理专家们很少将它们并称,但鉴于它们的重要性,以及相互之间的紧密关系,有必要进行一些说明分析,以引起项目经理们重视。

(1) 项目五因素

如果说三大目标是项目管理中最重要的因素,难道项目范围、资源就不重要的了吗?其实它们也很重要,甚至可以说更加重要,因为它们是解决做什么与谁来做的问题,这五大因素都是项目经理必须要关注的问题。

那为什么单单把三大目标拿出来说呢?其实很简单,这是因为项目范围、资源其实是约束性因素,而不是项目目标。其中项目范围是客户对项目的约束,而资源是你的老板对项目的约束。用口语来说就是,有这么一摊事(范围),老板给你这么多人(资源),你把它干好,什么叫干好呢?就是费用不能超支(成本)、干出来的东西还要好用(质量)。

(2)项目约束公式

项目五大因素之间,并不是孤立的,它们之间的变化关系可以用一个简单的公式来表示,我们不妨称之为“项目约束公式”:

成本 = 范围 × 质量 = 时间 × 资源投入

根据这一公式,我们可以得到几个“推论”:

●项目范围、质量、时间和资源投入都与项目成本成正比。

●如果客户要求添加额外工作(范围变大),或者质量要求提高,那么项目实施成本将升高。当资源投入一定时,项目所用时间会变长。如果期限不变,则需要加大资源投入。

●预算不变的情况下,范围变大,只能降低质量,质量要求提高,只能减少范围(少做一点工作)

可见这五大因素这间,是对立统一的关系,它们互相制约,互相影响,又相辅相成,因此必须要进行总体控制,保证各个因素之间的平衡,这也就是项目管理九大知识领域中为什么有一个整合管理的重要原因。

(3)挣值管理的不足

在项目管理中,有一个著名的方法叫“挣值管理”,它是用计划进度、实际进度、预算成本、实际成本这几个值进行运算比较,用来衡量项目绩效的一种方法。该方法对推行项目的数字化管理有着巨大的推动作用,然而由于缺失了一个重要因素,使得这个方法存在着严重的不足。

这个因素就是质量。挣值分析只有成本和进度两个方面的因素,没有质量,将其用于绩效考核时免不了产生很大的漏洞。为什么会没有质量呢?这是因为质量难以用数字进行度量,特别是对于软件项目而言。虽然国标《软件工程 产品质量》(GB/16260-2006),提出了比较完整全面的质量模型以及度量的指标,但质量评价成本很高,而且很多指标经依赖于人的主观评价,实用性也就大打折扣了。相对而言,对进度和成本的评价,如果借助合适的信息系统,完全可以通过计算机自动实时生成,不需要人过多的干预,非常方便。 

 

from   http://developer.51cto.com/art/201211/364725.htm



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Nginx负载均衡概览

$
0
0

一、特点

1.1 应用情况

Nginx做为一个强大的Web服务器软件,具有高性能、高并发性和低内存占用的特点。此外,其也能够提供强大的反向代理功能。俄罗斯大约有超过20%的虚拟主机采用Nginx作为反向代理服务器,在国内也有腾讯、新浪、网易等多家网站在使用Nginx作为反向代理服务器。据Netcraft统计,世界上最繁忙的网站中有11.48%使用Nginx作为其服务器或者代理服务器。基于反向代理的功能,Nginx作为负载均衡主要有以下几点理由:

  1. 高并发连接

  2. 内存消耗少

  3. 配置文件非常简单

  4. 成本低廉

  5. 支持Rewrite重写规则

  6. 内置的健康检查功能

  7. 节省带宽

  8. 稳定性高

1.2 架构

nginx在启动后,会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。工作进程以非特权用户运行。

master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

worker进程则是处理基本的网络事件。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。

开发模型:epoll和kqueue。

支持的事件机制:kqueue、epoll、rt signals、/dev/poll 、event ports、select以及poll。

支持的kqueue特性包括EV_CLEAR、EV_DISABLE、NOTE_LOWAT、EV_EOF,可用数据的数量,错误代码.

支持sendfile、sendfile64和sendfilev;文件AIO;DIRECTIO;支持Accept-filters和TCP_DEFER_ACCEP.

1.3 性能

Nginx的高并发,官方测试支持5万并发连接。实际生产环境能到2-3万并发连接数。10000个非活跃的HTTP keep-alive 连接仅占用约2.5MB内存。三万并发连接下,10个Nginx进程,消耗内存150M。淘宝tengine团队说测试结果是“24G内存机器上,处理并发请求可达200万”。

二、负载均衡

2.1 协议支持

Nginx工作在网络的7层,可以针对http应用本身来做分流策略。支持七层HTTP、HTTPS协议的负载均衡。对四层协议的支持需要第三方插件-yaoweibin的ngx_tcp_proxy_module实现了tcp upstream。

https://github.com/yaoweibin/nginx_tcp_proxy_module

此外,nginx本身也逐渐在完善对其他协议的支持:

  • Nginx 1.3.13 开发版支持WebSocket代理。

  • Nginx 1.3.15开发版支持SPDY。

2.2 均衡策略

nginx的负载均衡策略可以划分为两大类:内置策略和扩展策略。内置策略包含加权轮询和ip hash,在默认情况下这两种策略会编译进nginx内核,只需在nginx配置中指明参数即可。扩展策略有很多,如fair、通用hash、consistent hash等,默认不编译进nginx内核。

  1. 加权轮询(weighted round robin)

    轮询的原理很简单,首先我们介绍一下轮询的基本流程。如下是处理一次请求的流程图:

    图中有两点需要注意,第一,如果可以把加权轮询算法分为先深搜索和先广搜索,那么nginx采用的是先深搜索算法,即将首先将请求都分给高权重的机器,直到该机器的权值降到了比其他机器低,才开始将请求分给下一个高权重的机器;第二,当所有后端机器都down掉时,nginx会立即将所有机器的标志位清成初始状态,以避免造成所有的机器都处在timeout的状态,从而导致整个前端被夯住。

  2. ip hash

    ip hash是nginx内置的另一个负载均衡的策略,流程和轮询很类似,只是其中的算法和具体的策略有些变化,如下图所示:

    ip hash算法的核心实现如下:

    Java代码   收藏代码
    1. for(i = 0;i < 3;i++){  
    2.     hash = (hash * 113 + iphp->addr[i]) % 6271;  
    3. }  
    4. p = hash % iphp->rrp.peers->number;  

    从代码中可以看出,hash值既与ip有关又与后端机器的数量有关。经过测试,上述算法可以连续产生1045个互异的value,这是该算法的硬限制。对此nginx使用了保护机制,当经过20次hash仍然找不到可用的机器时,算法退化成轮询。因此,从本质上说,ip hash算法是一种变相的轮询算法,如果两个ip的初始hash值恰好相同,那么来自这两个ip的请求将永远落在同一台服务器上,这为均衡性埋下了很深的隐患。

  3. fair

    fair策略是扩展策略,默认不被编译进nginx内核。其原理是根据后端服务器的响应时间判断负载情况,从中选出负载最轻的机器进行分流。这种策略具有很强的自适应性,但是实际的网络环境往往不是那么简单,因此要慎用。

  4. 通用hash、一致性hash

    这两种也是扩展策略,在具体的实现上有些差别,通用hash比较简单,可以以nginx内置的变量为key进行hash,一致性hash采用了nginx内置的一致性hash环,可以支持memcache。

2.2 配置示例

  1. HTTP

    Java代码   收藏代码
    1. http {  
    2.   
    3.      upstream  www.s135.com  {  
    4.   
    5.        server   192.168.1.2:80;  
    6.   
    7.        server   192.168.1.3:80;  
    8.   
    9.      }  
    10.   
    11.   
    12.   
    13.      server{  
    14.   
    15.        listen  80;  
    16.   
    17.        server_name  www.s135.com;  
    18.   
    19.   
    20.   
    21.        location / {  
    22.   
    23.                 proxy_pass        http://www.s135.com;  
    24.   
    25.                 proxy_set_header   Host             $host;  
    26.   
    27.                 proxy_set_header   X-Real-IP        $remote_addr;  
    28.   
    29.                 proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;  
    30.   
    31.        }  
    32.   
    33.   
    34.   
    35.        location /nginx_status {  
    36.   
    37.                 stub_status on;  
    38.   
    39.                 access_log off;  
    40.   
    41.                 allow 192.168.1.1;#设置为可访问该状态信息的ip  
    42.   
    43.                 deny all;  
    44.   
    45.        }  
    46.   
    47.      }  
    48.   
    49.  }  
  2. TCP – ngx_tcp_proxy_module

    Java代码   收藏代码
    1. tcp {  
    2.   
    3.      upstream cluster {  
    4.   
    5.          # simple round-robin  
    6.   
    7.          server 192.168.0.1:80;  
    8.   
    9.          server 192.168.0.2:80;  
    10.   
    11.   
    12.   
    13.          check interval=3000 rise=2 fall=5 timeout=1000;  
    14.   
    15.   
    16.   
    17.          #check interval=3000 rise=2 fall=5 timeout=1000 type=ssl_hello;  
    18.   
    19.   
    20.   
    21.          #check interval=3000 rise=2 fall=5 timeout=1000 type=http;  
    22.   
    23.          #check_http_send "GET / HTTP/1.0\r\n\r\n";  
    24.   
    25.          #check_http_expect_alive http_2xx http_3xx;  
    26.   
    27.      }  
    28.   
    29.   
    30.   
    31.      server {  
    32.   
    33.          listen 8888;  
    34.   
    35.          proxy_pass cluster;  
    36.   
    37.      }  
    38.   
    39.  }   

三、动态负载均衡

3.1 自身监控

内置了对后端服务器的健康检查功能。如果Nginx proxy后端的某台服务器宕机了,会把返回错误的请求重新提交到另一个节点,不会影响前端访问。它没有独立的健康检查模块,而是使用业务请求作为健康检查,这省去了独立健康检查线程,这是好处。坏处是,当业务复杂时,可能出现误判,例如后端响应超时,这可能是后端宕机,也可能是某个业务请求自身出现问题,跟后端无关。

3.2 可扩展性

Nginx属于典型的微内核设计,其内核非常简洁和优雅,同时具有非常高的可扩展性。如下图所示:

Nginx是纯C语言的实现,其可扩展性在于其模块化的设计。目前,Nginx已经有很多的第三方模块,大大扩展了自身的功能。nginx_lua_module可以将Lua语言嵌入到Nginx配置中,从而利用Lua极大增强了Nginx本身的编程能力,甚至可以不用配合其它脚本语言(如PHP或Python等),只靠Nginx本身就可以实现复杂业务的处理。

3.3 配置修改

nginx的配置架构如下图所示:

Nginx支持热部署,几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。能够在不间断服务的情况下,对软件版本进行进行升级。Nginx的配置文件非常简单,风格跟程序一样通俗易懂,能够支持perl语法。使用nginx –s reload可以在运行时加载配置文件,便于运行时扩容/减容。重新加载配置时,master进程发送命令给当前正在运行的worker进程worker进程接到命令后会在处理完当前任务后退出。同时,master进程会启动新的worker进程来接管工作。

四、优势和劣势

4.1 优势

  1. 可以很好地进行http 的头处理

  2. 对http协议以及https的良好支持

  3. 有足够的第三方插件供使用

  4. 支持热部署,更改后端是平滑的

4.2 劣势

  1. 缺少对session的支持

  2. 对四层tcp的支持不够好

  3. post请求写文件系统,造成500 error

  4. 缺乏主动的后端服务器健康监测

  5. 默认的监控界面统计信息不全

五、Tengine

5.1 特性

  1. 继承Nginx-1.2.9的所有特性,100%兼容Nginx的配置;

  2. 动态模块加载(DSO)支持。加入一个模块不再需要重新编译整个Tengine;

  3. 输入过滤器机制支持。通过使用这种机制Web应用防火墙的编写更为方便;

  4. 动态脚本语言Lua支持。扩展功能非常高效简单;

  5. 支持管道(pipe)和syslog(本地和远端)形式的日志以及日志抽样;

  6. 组合多个CSS、JavaScript文件的访问请求变成一个请求;

  7. 更加强大的负载均衡能力,包括一致性hash模块、会话保持模块,还可以对后端的服务器进行主动健康检查,根据服务器状态自动上线下线;

  8. 自动根据CPU数目设置进程个数和绑定CPU亲缘性;

  9. 监控系统的负载和资源占用从而对系统进行保护;

  10. 显示对运维人员更友好的出错信息,便于定位出错机器;

  11. 更强大的防攻击(访问速度限制)模块;

  12. 更方便的命令行参数,如列出编译的模块列表、支持的指令等;

  13. 可以根据访问文件类型设置过期时间;

5.2 负载均衡

负载均衡方面,Tengine主要有以下几个特点,基本上弥补了 nginx在负载均衡方面的欠缺:

  1. 支持一致性Hash模块

  2. 会话保持模块

  3. 对后端服务器的主动健康检查。

  4. 增加了请求体不缓存到磁盘的机制



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



WebView的使用总结

$
0
0
1)       添加权限:AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错误。
2)       在要Activity中生成一个WebView组件:WebView webView = new WebView(this);或者可以在activity的layout文件里添加webview控件:
<WebView
android:id="@+id/wv"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="@string/hello"

    />


3)       设置WebView基本信息:
          如果访问的页面中有Javascript,则webview必须设置支持Javascript。
          webview.getSettings().setJavaScriptEnabled(true);  
          触摸焦点起作用
          requestFocus();
          取消滚动条
          this.setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY);
 
4)       设置WevView要显示的网页:
          互联网用:webView.loadUrl("http://www.google.com"); 

          本地文件用:webView.loadUrl("file:///android_asset/XX.html");  本地文件存放在:assets文件中


5)       如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。给WebView添加一个事件监听对象(WebViewClient)并重写其中的一些方法:

 shouldOverrideUrlLoading:对网页中超链接按钮的响应。当按下某个连接时WebViewClient会调用这个方法,并传递参数:按下的url。比如当webview内嵌网页的某个数字被点击时,它会自动认为这是一个电话请求,会传递url:tel:123,如果你不希望如此可通过重写shouldOverrideUrlLoading函数解决:

 public boolean shouldOverrideUrlLoading(WebView view,String url){

         if(url.indexOf("tel:")<0){//页面上有数字会导致连接电话
             view.loadUrl(url);
         }
            return true;           

        }



6)为了让WebView从apk文件中加载assets,Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这样的schema,就去当前包中的 assets目录中找内容。如上面的"file:///android_asset/demo.html" 


7)addJavascriptInterface方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他的线程中,这也是使用 Handler的目的。

8.webview 中使用div层会出现重叠显现.只能用dom方式操作div的删除动作.


Webview与js交互

 wv.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");

private final class DemoJavaScriptInterface

    {
 DemoJavaScriptInterface(){}

     public void clickonAndroid( final String order){
         mHandler.post(newRunnable(){
             @Override
             public void run(){
                       jsonText="{"name":""+order+""}";
                wv.loadUrl("javascript:wave("+jsonText+")");
             }
         });
     }
}




作者:jia635 发表于2014-9-8 22:26:54 原文链接
阅读:56 评论:0 查看评论

XSS的原理分析与解剖(第二篇)

$
0
0

0×01 前言: 

上节( http://www.freebuf.com/articles/web/40520.html)已经说明了xss的原理及不同环境的构造方法。本期来说说XSS的分类及挖掘方法。

当第一期出来的时候,反馈很好,但还是有很多人提出疑问,我这里就解答下。

问1:如果我输入PHP语句会不会执行。

答1:不会,因为XSS是面对前台的(用户可见部分),而PHP则是后台处理(用户不可见部分),如果可以执行PHP语句的话,那不叫XSS,叫"任意代码执行"。

问2:XSS和CSRF有什么区别么?

答2:有的,XSS是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。

问3:为什么我在chrome浏览器下测试<script>alert("xss")</script>并没有成功。

答3:chrome内核与ie内核不一样,chrome的过滤机制比ie强。现在测试xss一般都拿能过chrome的为主,所以当你输入xss的时候,可能被chrome的过滤机制给过滤了。

 

想了解反射XSS、储蓄XSS、DOM XSS,要先了解GET/POST的处理方式,不懂的话,请查考 传送门

0×02 反射型XSS:

反射XSS是XSS分类中最多的,他们原理是下面这样:

Hacker——发现存在反射XSS的URL——根据输出点的环境构造XSS代码——进行编码、缩短(可有可无,是为了增加迷惑性)——发送给受害人——受害打开后,执行XSS代码——完成hacker想要的功能(获取cookies、url、浏览器信息、IP等等)

原理搞清楚,那就说说怎么挖掘吧,

现在市面上的软件(JSky、Safe3WVS、Netsparker等)都可以挖掘出反射XSS,但是想要那些更隐蔽的XSS还是需要手工的,我先使用软件挖掘一些反射XSS,然后介绍手工挖掘。

找到后,我们来打开

http://gdjy.hfut.edu.cn/viewcomp.jsp?id=hzgz123

打开后,我们试着在参数也就是id=hzgz123后面加上woaini(或则其他字符,这串字符必须保持唯一性,也就是说在整个网站里,他必须唯一一个不和其他字符相同的字符串)输入woaini后,打开,查看源代码(ctrl+u),按下ctrl+f来搜索woaini字符串,看出现在哪个位置。

我们发现woaini字符在a标签的href属性里,那我们就可以根据这个环境来构造了,我们可以用"></a><script>alert("xss")</script>来先闭合掉a标签。然后再用script来运行js代码。也可以这样onclick="alert(1)";>123</a>//点击123触发onclick来运行js,然后把后面的内容来注释掉。构造好代码后,把url变成短连接,发送给管理员,诱惑管理员打开,就可以获取管理员的cookies了。

OK,软件挖XSS大致就这些,手工其实和这差不多,手工的话,记住一句话“见框就插、改数据包不可见部分、改URL参数、js分析”就可以了。改数据包、js分析比较深,现在我就不再阐述了,见框就插,大家应该都明白,找到一个input输入框,先输入唯一字符串,然后看源代码里有没有出现,再输入<>""/&()来看看过滤了哪些字符,根据过滤的字符,来构造xss。

下图是QQ空间一处反射XSS,因为是朋友给的,我也不清楚是否被提交,所以我就不放出了。

0×03 储蓄型XSS:

PS:有的人叫持久型,各有各的叫法,所以不用太介意。

储蓄型XSS其实和反射型XSS差不多,只是储蓄型把数据保存到服务端,而反射型只是让XSS游走在客户端上。下面是我在某处网站上检测到的储蓄XSS,大家知道原理就OK。

(因为,这个网站本人想提交,所以URL打码处理,见谅)

目标站点: http://www.*******.com/

习惯性的打开留言处(book.asp),点击留言(这里最好不要使用<script>alert("xss")</script>来测试是否存在XSS漏洞,容易被管理员发现,所以你可以使用<a></a>来测试,如果成功了,不会被管理员发现)OK,我先在留言里出输入<a>s</a>提交留言,F12打开审查元素,来看我们输入的标签是否被过滤了,

OK,发现没有过滤(如果<a>s</a>是彩色的说明没有过滤,如果是灰色就说明过滤了)

那我就在xss平台里创建一个项目,然后再次留言,里面写上,“<script src="http://xss8.pw/EFe2Ga?1409273226"></script>请问怎么报名啊”

名字是我乱起的,这样一来,只要你访问

http://www.******.com/book.asp

就可以获取你的cookies,以及后台地址(因为留言板一般都在后台做审核)。但是,管理员好像死了,已经6天了,还没看。今天上xss平台一看有个cookies,看了下,是路人的,并不是管理员的。

但是使用方法大家也应该懂了。只要你打开 http://www.******.com/book.asp 我就会在第一时间获取你的cookies。

0×04 DOM XSS:

DOM XSS是基于在js上的。而且他不需要与服务端进行交互,像反射、储蓄都需要服务端的反馈来构造xss,因为服务端对我们是不可见的(不是太清楚的,可以看看(http://www.freebuf.com/articles/neopoints/41168.html一文)

挖掘DOM XSS比较麻烦,因为有时你需要追源,对方可能会自定义函数,所以你需要一步一步来把对方自定义的函数来搞清楚。下面我举个最简单的例子:

在1.html里输入

<script>
document.write(document.URL.substring(document.URL.indexOf("a=")+2,document.URL.length));</script>

在这里我先解释下上面的意思

Document.write是把里面的内容写到页面里。

document.URL是获取URL地址。

Substring 从某处到某处,把之间的内容获取。

document.URL.indexOf("a=")+2是在当前URL里从开头检索a=字符,然后加2(因为a=是两个字符,我们需要把他略去),同时他也是substring的开始值

document.URL.length是获取当前URL的长度,同时也是substring的结束值。

合起来的意思就是:在URL获取a=后面的值,然后把a=后面的值给显示出来。

我们打开,看看

怎么会出现这个问题呢?

因为当前url并没有a=的字符,而indexOf的特性是,当获取的值里,如果没有找到自己要检索的值的话,返回-1。找到了则返回0。那么document.URL.indexOf("a=")则为-1,再加上2,得1。然后一直到URL最后。这样一来,就把file的f字符给略去了,所以才会出现ile:///C:/Users/Administrator/Desktop/1.html

大致的原理都会了,我们继续。

我们可以在1.html后输入?a=123或则#a=123,只要不影响前面的路径,而且保证a=出现在URL就可以了。

我们清楚的看到我们输入的字符被显示出来了。

那我们输入<script>alert("xss")</script>会怎么样呢?

答案肯定是弹窗。

但是,这里肯定有人无法弹窗,像下面这样。

这是因为浏览器不同,maxthon、firfox、chrome则不行,他们会在你提交数据之前,对url进行编码。这不是说DOM XSS不行了,这只是个很简单的例子,所以不用在意。

我在说下,DOM XSS 是基于javascript基础上,而且不与服务端进行交互,他的code对你是可见的,而基于服务端的反射、储蓄则是不可见的。

0×05 XSF(Flash XSS):

XSF其实不算XSS的分类中,应该算作XSS的分支,因为在XSS使用到的技巧,在XSF只有一部分可以使用,因为XSF是基于ActionScript2/3.0语言的基础上。

我写XSS系列是为了让大多数对XSS不熟悉的人知晓如何运用这门攻击手法,所以,在此我不打算深入介绍XSF,如果有机会,你们将会在后期的系列里看到关于XSF技术的。

我先简要的说明下,在ActionScript2/3.0里以下几个函数需要重点关注下:

getURL  navigateToURL  ExternalInterface.call  ExternalInterface.call  htmlText  addcallback等。有兴趣的朋友可以先自行研究下。

0×06 挖掘XSS:

挖掘XSS的技巧很多,各式各样,我这里就简要说明下容易出现XSS的地方。

之前说过了修改输入框和URL参数来实现XSS。我在这里深入一点说明下。

修改URL参数的时候,你看到的只是用GET来传输数据的,还有隐形的数据,他们是用POST来传输数据,只有在数据包里才可以看到。这里不就阐述了,不懂的可以参考之前我写的利用方法,GET和POST利用方法几乎一样。不清楚POST和GET的可以在0×01 前言里查看下我给出的链接。

废话也不说了,下面进入正题。

一:我们都知道当你浏览网站的时候,对方的服务器会记录下你的IP地址。如果我们伪造IP为XSS代码呢?这里说的修改IP为XSS不是说修改PC端的,而是在浏览器也就是网页上的客户端进行修改。

这里需要使用firefox浏览器和两个附件

附件一:X-Forwarded-For Header

因为PHP获取IP有3个函数。而X-Forwarded-For Header就是对其中一个函数X_FORWARDED_FOR起作用,X_FORWARDED_FOR有个缺陷可以使客户端伪造任意IP,当然包括字符串,但是对其他两个函数就不行了。

附件二:Modify Headers

Modify Headers可以伪造数据包内容,当然也可以伪造HTTP_CLIENT_IP来更改IP。

 

那还有一个REMOTE_ADDR获取IP函数,这个怎么修改呢?答案是无法修改。

REMOTE_ADDR是由 nginx 传递给 php 的参数,所以就是当前 nginx 直接通信的客户端的 IP ,而我们无法插手。所以一旦对方使用了REMOTE_ADDR函数来获取IP,那就没办法了。不过不要紧,一共3个函数,2个函数可以伪造,我们还是有很大的成功率的。好了,开始伪造。

伪造好后,我们打开www.ip138.com看看,

成功弹窗了。因为我在X-Forwarded-For Header里配置的是<script>alert("xss")</script>。而在Modify Headers配置的是<script>alert("xss2")</script>。也就是说ip138.com使用的是X_FORWARDED_FOR函数来获取IP的。但是DZ等著名CMS不存在,他们都过滤了。

就像漏洞盒子一样(https://www.vulbox.com),

使用的是HTTP_CLIENT_IP函数来获取IP的,但是过滤了。你们可以先把配置写好,构造成一个获取cookies的。以后就随便的浏览网站,说不定某天就可以钓上一个呢。

本方法是Misty去年告知。

0×07 结束:

由本章可以知晓XSS不一定是在input输入框和GET/POST参数修改,才可以插入XSS。还有JavaScript、ActionScript2/3.0、数据包参数。玩XSS的时候,思想不能固定,要灵活多变。

本章也就结束了,下节如果不出什么意外的话是讲XSS技巧,敬请期待。

Viewing all 15845 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>