stone2083

我的评论

共3页: 上一页 1 2 3 下一页 
re: HtmlParser疑似Bug stone2083 2011-04-09 19:31  
@penngo
收到,有空的时候,我去学习下jsoup。
re: 语言杂谈(shell/python/java) stone2083 2010-11-16 11:44  
@问题
每种语言都是自身的特点(优势和弊端),以及背后的设计理念。我们要用合适的技术解决对应的需求,使用正确的思想去使用该技术。
(在我周围遇到有太多的同学,面对10来个页面的需求,也要使用java,还要使用mvc,orm framework,三,四层架构,之后再来抱怨java的复杂。)
这促使我站在自己的理解上,总结了三门具有代表性的语言特点和其适用的场景(还少一种函数式编程语言)。

之所以发到blog:
1.在目前能力范围下,总结对这些事物的理解
2.找到志同道合的人员,可以一起交流

就事论事的讨论,才能让你,我,彼此都得到成长;
没有任何理论说明的,纯属发自内心的主观性批判语言,相信对我的帮助几乎没有。

不妨说说没有毛用的理由,这有助我们进一步讨论。


re: CGlib简单介绍 stone2083 2010-11-03 13:31  
@pyzhu
得到同事指点,还有一种更好的方法:
system.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "指定输出目录"); 

详见:http://www.javaeye.com/topic/799827
re: 爬取交通违章信息的脚本 stone2083 2010-10-29 18:46  
@wuzhengju
唉,我这个土人。。。
之前思维一直停留在如何破解验证码上了。直到写完这个东东,在写脚本的时候:
curl -A "$AGENT" -e $TRAFFIC_URL -b "ASP.NET_SessionId=$SESSION_ID;isLoginedWeb=T;ImageV=$code" -d "$QUERY_PARAM" "$TRAFFIC_URL" -o $TMP_CONTENT_BASE
才发现在cookie中已经存在这个ImageV了。
不过为时已晚,米已城粥。。。 :)
================================================
好久不见了,最近工作还顺利吗?

re: 爬取交通违章信息的脚本 stone2083 2010-10-15 18:18  
@阿风
其实是周末下午没事情干,弄着玩的。
之前没有涉及过图片相关的,趁机也稍微学习下。 :)
re: CGlib简单介绍 stone2083 2010-10-09 09:27  
@pyzhu
修改源码也是一种方法 :)
我是在debug的时候,Variables窗体中,编写java代码,拿到class变量信息做自己的处理


re: CGlib简单介绍 stone2083 2010-09-29 09:18  
@pyzhu
用了比较猥琐的办法,
debug,将动态生成class的字节码 输入到文件中,然后反编译得到的.
re: java反射效率 stone2083 2010-09-16 12:57  
@Unmi
我上面的例子,仅仅是想说明反射调用方法的开销(不局限在get/set上).
如果是对java bean getters/setters的操作,可以考虑使用cglib的BulkBean类.
cglib下的fastclass和fastmethod,确实有一定的优势,但是优先并不明显(在jdk1.6上)
re: java反射效率 stone2083 2010-09-15 20:21  
@王卫华
你是指spring aop中cglib proxy的实现?
re: IBatis下DAO单元测试另类思路 stone2083 2010-08-13 11:54  
@kylin
明白你们这边的情况了.

Service层的测试相对还是容易的,我们这边也有一套测试框架(类似DDSteps,也是对一些业界测试工具的整合加改进).并且对Service依赖的外部环境,都做了隔离,主要包括:
1.Mock Dao impl
2.Mock Core Service impl (外部核心业务服务)
3.Mock Search Engine impl
4.Mock Cach impl
....
测试重心,主要集中在Service内部逻辑的测试上.
而公司使用的测试框架很好的支持了这些需求.


难点还在DAO的测试上.
数据准备的复杂度,取决于表设计的复杂度和sql的复杂度.尤其在ibatis支持dynamic语句下,要准备覆盖测试sql语句的数据.挺繁琐的.
这并不是说使用excel,还是wiki等的问题.而是数据内容的准备上.

每个测试数据的准备,都是为了一个特定的testcase设计目的的.而当字段多,并且表设计相对复杂的时候,这个准备意图,挺难被传承下去的.
随着项目,小需求的进行,我们这边,差不多几十人,都有可能修改同一个sql代码 :(
re: Java Exception性能问题 stone2083 2010-08-13 09:08  
@啊宝
控制流程用Exception(try..catch)也好,还是ResultModel(if..else)也罢.只是不同的设计理念而已.
都可以,都对

至于提到异常烦,如果是为性能问题.我以为大可不必.
1.异常的性能没那么差.在上面的测试中,一个异常的产生,0.02ms而已
2.大多数的应用,对性能要求并非很高
3.引起性能瓶颈的,往往是不合理的设计,错误的使用同步等业务代码产生的.
4.实在不行,就是用改进后的异常

如果再不行,那么只好抛弃业务异常吧
如果再不行,那么只好抛弃java改用c等语言吧.

选择一种语言也好,选择一种设计也罢,只是为了更好的处理需求而已.

至于上文,只是为了描述异常的本质.在了解原理的基础上,让业务异常的使用不出现性能的浪费而已.
绝不是表明,异常性能真得对系统产生了影响 :)
re: IBatis下DAO单元测试另类思路 stone2083 2010-08-13 08:46  
提供这个思路,并不是说替代之前的方案,更不是对传统测试方案的否定. 仅仅是为了多一种选择.

re: IBatis下DAO单元测试另类思路 stone2083 2010-08-13 08:31  
@蓝剑
DAO业务逻辑不复杂只指:在DAO方法中,不会有复杂的分支流程,往往只会调用一条SqlID执行sql.但是这不意味sql不复杂.
打个比方,报表的生成,业务逻辑非常简单(根据什么样的条件,能看到什么样的数据),但是sql绝对的复杂. :)
dao方法,也只会有一句 getSqlMapClientTemplate.queryForList("....",param); // 简单吧 :)

数据准备的工作量低吗?维护成本低吗?至少在我实践的项目中,没有像sample那样低(dbfit,dbunit,dbutil等sample,都是单表的说明,单表字段往往少于5个字段). 实际情况是:
1.字段多
2.表关联 (尤其在tree结构的表,父节点的依赖,光是这样的准备,都非常容易写错)
3.对于查询的语句(尤其是分页),需要根据动态条件,准备好需要的数据
4.数据准备意图需要被传承
在我看来,并且实践过来,挺不容易的.

sql的assert,只要根据条件参数的不同,做不同预计sql的assert,成本绝对比结果数据校验,来得低.

至于最后一点.
是用ibatis,还是jdbc;不是单元测试成本(方案)决定的;而是需求,应用,架构设计,部门岗位情况等决定的.
我们有专业的dba,对所有sql要做review,总不能给一堆jdbc的文件给他们吧.ibatis就挺好了.
再说了,对于ibatis下dao编码,错误率是sql写错的高呢?还是row mapper错误高呢?所以如果因为这点,来否决全部,挺不公平的.
re: IBatis下DAO单元测试另类思路 stone2083 2010-08-12 17:02  
@sgz
大多数时候,想法是被现实逼出来的 :)
在我们这边,dao几乎没有复杂的业务逻辑,仅仅是对SqlMapClientTemplate的使用而已.
但是在针对DB的单元测试时,代价又是如此的巨大(主要还是在数据准备上).
成本,收益比,不划算,开发们抱怨多.

分析现状和开发们实际需求(写dao,主要是担心sql写错)后,才萌生了这个想法.
re: IBatis下DAO单元测试另类思路 stone2083 2010-08-12 16:58  
@kylin
简单地看了下ddsteps,它是一套集成测试工具.主要包括:
dbunit,selenium,mock web(http) server,easymock和spring.
它对DB的支持,也是采用传统的方式.(没猜错的话,是使用了,最多封装了dbunit)
并不能解决我现在遇到的问题:
1.背负数据库环境
2.准备测试数据
3.准备预计结果数据
这些麻烦的工作量.

而且在公司中,也已经有一套测试框架,我们要做的,并不是选择框架(替换框架),而是选择一种合适敏捷单元测试的思路和方案. 让框架支持敏捷的方案而已.
突然记起来了.请参考这篇文章:
http://sdh5724.javaeye.com/blog/619130

在自己电脑上,一直无法重现这个问题(无论加大循环,或者增加线程数),明天回公司再去看看.
"Thread-1" prio=6 tid=0x00c70bd8 nid=0x914 runnable
两个线程都是runnable状态.

这程序,理论上,不应该出现死锁的.
@BearRui(AK-47)
Sorry,Sorry.
你底下的几个button做的不错,发觉挺有意思的,就多点了几下.没想到居然是发评论用的. :)
re: 单元测试下简易性能测试工具 stone2083 2010-06-21 19:10  
@TestThug
1.要看公司政策了;
2.要看JTester作者意愿了;

从目前看,开源的可能并不大 :(
re: 编程方式实现SpringBean LazyInit stone2083 2010-06-19 01:11  
今天又细看了代码,发现覆写
AbstractXmlApplicationContext.initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) 方法更为合理.
re: ubuntu如何用adsl上网 stone2083 2010-06-18 08:36  
@周
理论上说,源上肯定存在着两个package的.是否是你自己设置了其他源导致的?

不过没关系,手工下载包,再安装好了.
http://packages.ubuntu.com/
找到你ubuntu版本,点击所有产品包(例如:http://packages.ubuntu.com/lucid/allpackages),查找pppoe和pppoeconf.手工下载,安装即可.

当然,ubuntu cd自带也有.插入ubuntu cd.使用apt安装也可.

有一份详细的文档,不妨看看:https://help.ubuntu.com/community/ADSLPPPoE



re: Tomcat(6.0.14) Session创建机制简介 stone2083 2010-06-11 20:23  
@小菜花
理论上来说,传递jsessionid,只要value是一致的,服务端不会创建多份session.
可以在测试环境下通过debug 或者 监控工具,跟踪下创建多份session的情况.
re: 单元测试下简易性能测试工具 stone2083 2010-06-11 08:51  
@BeanSoft
接受观点.
之所以考虑使用毫秒,是因为不同的开发机性能参差不齐,对性能的影响远远大于本身计算的精确性.
而这个简易工具,本意只是提供感性的性能数据.所以提供的数据并不精确(当然,之后会随着项目开发中提出的需求做完善),而是相对于程序员更友好的单位.
re: J2EE压力测试的性能问题 stone2083 2010-04-17 22:09  
为什么不考虑使用JSESSIONID,来模拟更真实的用户并发情况?
re: 支付宝接口demo代码读后感 stone2083 2010-03-17 10:15  
@出错
比较遗憾.我第一时间和支付宝工程师联系反馈了这个问题.没想到他们到现在还没有跟进...
re: Tomcat(6.0.14) Session创建机制简介 stone2083 2010-03-07 15:30  
@小菜花
准确地讲,除非你的应用完全不需要保存状态(无状态应用),不然地话,只要有一个新的连接过来,web容器都需要创建Session概念,维护状态信息.
但是Session是什么?Session仅仅是一个概念:"Provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user."--简单地讲,保存用户状态信息.
所以说,我们完全可以根据应用的需求,定制Session的实现:
a. Session保存到JVM内容中--Tomcat默认的实现
b. Session保存到Cookie中--Cookie-Based Session
c. Session保存到本地文件--Tomcat提供的非默认实现之一
d. Session保存到Cache Store中--比如常见的Memcached
e. Session保存到数据库中--比如保存到mysql数据库session表,中间对于活跃的Session 缓存到cached中.
......
那么,假如一个应用有大量一次性不同用户的请求(仅仅是一次性的,比如上述文章描述的场景),那么选择c,d,e方案都能有效解决文中所描述的问题.
"业务比技术重要“看怎么去理解了,要理解业务的边界;技术的边界
我虽然比较看重技术,但是也认可”业务比技术重要“。
我所理解这句话的含义:业务是本,技术为业务服务。

问题是什么?
业务包含哪些范围(边界),我认为的业务,不仅仅是原始需求,包括:
*原始业务需求
*需求分析
*业务建模
这些都属于业务规划(或者是产品规划)的一部分。

技术包含哪些范围(边界),我认为:
*选用技术语言
*技术架构
*实现模型
*实现编码

只是现在,很多需求分析,业务建模(或者说领域建模)都是技术团队在做,会误以为这些都是属于技术的范围。
真正能做好业务规划的团队和单位,真的是太少了,往往只提供原始需求,就让技术去实现罢了。


re: CGlib简单介绍 stone2083 2009-10-10 10:38  
@名扬/六耶子
cglib底层依赖了asm,它主要是在“动态代理”场景下增加易用性。
如果要动态生成字段,方法,那么asm或者javassist这两个技术,更合适你。
re: Struts2.1.6--想用通配符,不容易 stone2083 2009-09-27 19:44  
刚去struts官方网站溜达了下:
http://issues.apache.org/struts/browse/WW-3024

已经有人提交了bug,在struts2.1.8中,修复。

查看了xwork trunk的代码,发现修复方式,跟我原文的一样。先这么用一段时间吧。 :)

trunk代码:
http://svn.opensymphony.com/svn/xwork/trunk/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManager.java
re: Struts2.1.6--想用通配符,不容易 stone2083 2009-09-27 19:09  
@Simon
没有放之四海而皆准的技术,任何技术,总是有利弊的,关键是看怎么权衡了。
用通配符也好,zero config plugin也好,都可以,我只有一个要求,就是COC。
做为程序员,封装变化,抽取共性,减少一切可以减少的重复劳动力。

在我看来,一个一个配置action,就是重复劳动力。至少在80%的场景下,配置都是差不多的。
试想一下,当一个应用,有上千个action时,光是action的配置文件,就是几千甚至上万行。这个维护工作量,不敢想象。

至于拦截器,同理,我以为,80%的情况下,action配置的拦截器都是同样的。所以就算使用通配符,我可以用其他的方案解决特殊(20%)的需求。

Annotation,额,这个玩意,我不敢滥用。只有20%的需求才有的特殊需求场景下,我还会考虑(仅仅是考虑)使用Annotation。
Struts2中,Action上的annotation设计,我一直不敢恭维。所以我绝对不会使用annotation的。
其实从我原文中,一直在描述如何寻找Validatior文件的方法,没有说我用了annotaion。在很多场景下,我一直是xml的拥护者,当然最拥护的,是Convertion。 :)
re: Struts2.1.6--想用通配符,不容易 stone2083 2009-09-27 12:39  
@梁章坪
没错,最正宗的格式是ActionName--validation.xml。
请看,AnnotationActionValidatorManager中的buildValidatorConfigs方法片段:
validatorConfigs.addAll(buildClassValidatorConfigs(clazz, checkFile));
在buildClassValidatorConfigs方法中,
String fileName = aClass.getName().replace('.', '/') + VALIDATION_CONFIG_SUFFIX;
就是你说的ActionName--validation.xml格式。
在一个Action只有一个方法(execute)的时候,这样是够用的。

但是Struts2为了支持一个Action有多个方法(CRUD)的时候,那么怎么为不同的方法寻找它需要的校验文件呢?
于是乎,继续看AnnotationActionValidatorManager中的buildValidatorConfigs方法片段:
if (context != null) {
validatorConfigs.addAll(buildAliasValidatorConfigs(clazz, context, checkFile));
}
将Action名和context做组合,作为校验文件的别名(alias)。

至于context是什么?我一开始以为是method名,结果看了代码,发现不是。struts2是传了${配置中的action name=""}中的名字
看来它的本意是希望同一个action的方法,在不同使用场景下,也允许不同的校验规则。

所以就有了这样的格式定义。 :)




re: 支付宝接口demo代码读后感 stone2083 2009-09-21 13:10  
其实本身并没有非常强制的标准,比如一定得:3<参数<类 用map
原则只有一个,方便客户端的调用。

比如上面举的例子,一共有19个参数,调用者能方便的调用吗?哪个参数在哪个位置,能方便找到吗?

所以,自定义map(定义了key常量的map)或者parameter Class,更合适上面的场景。
@林茂
能兼容outlook的事件邀请。至于是否100%,不敢保证,从我使用情况看,outlook 2003,2007的事件邀请,都能兼容。
但是不兼容发送的实践邀请,我使用lightning发送的邀请,在outlook上查看,只能显示一堆源码。
个人不希望仅仅因为猥琐解决这个bug,而引入对spring-web的依赖。
手写一个CharacterEncodingFilter也是比较方便的事情。

当然,切会org.apache.struts2.dispatcher.FilterDispatcher,也是一个可选方案。
当时自己不选择FilterDispatcher的原因是:
在应用测试的时候,顺带测试struts2 StrutsPrepareAndExecuteFilter(官方推荐)方案.免得等2.1.7发布后,在换回StrutsPrepareAndExecuteFilter时,又发现其他问题。
相对来说,删除一个Filter的风险更小一些 :)
re: Tomcat重定向传中文 stone2083 2009-06-11 12:44  
url参数中带中文的应用场景还是很多的。
关键是采用某种技术手段去实现的问题了。
url encoder就是用来做这样的事情的:
java.net.URLEncoder.encode(urlParams, encoding);

re: 区分Action, Service 和 Dao功能 stone2083 2009-05-21 13:25  
比喻很形象,也比较能说明问题。站在技术角度上,我非常认同你说的观点。
对于一家长期发展的公司,系统演变会越来越复杂,前期为了贪图方便的设计,总有一天,会带来无穷的痛楚。这些俺都明白。目前也在经历这些痛楚。

但是,确实也存在很多系统,本身业务并不复杂(比如外包公司接手的一次性的小项目),并且也很难看到未来的发展方向(比如针对一些创业型公司的项目),之后重写+数据迁移的方案代价远远小于系统重构的代价,那么我,决不会采用复杂的架构,把简单问题复杂化。
PHP,ROR(使用action+model,没有过多分层)的项目,在中小型项目中,比较流行的,也能说明一些问题。

很多的系统,如果能标标准准按照action->biz->dao的结构写,已经是相当不错了(通过一些应用抛出的错误异常看,很多甚至在jsp上书写大量的业务逻辑,或者在action属性大量的业务逻辑)。要在biz层抽象出biz->service的概念的系统,并不是太多。(至少是中型公司及以上,才需要考虑的)

我说这些,不是为了否决楼上的说辞--其实我是非常认同的观点。
我只是想表明,任何的架构设计,都是需要根据需求以及未来的发展,来决定的。
re: 区分Action, Service 和 Dao功能 stone2083 2009-05-15 12:23  
一般应用中,biz层和service层的概念就是同一个,硬做分层,是脱了裤子放屁 ,自找麻烦。 :)

当公司规模大了,应用庞大了,复杂了:
比如,当web应用有几十,上百个;task应用几十,上百个。。。
该如何控制和维护业务人员编写的biz和dao呢?

于是乎,就需要抽象出service层(核心组件服务/核心产品服务),service依赖dao api,search engine api,dw api等等,并且通过某些协议,暴露自己的service api

前台应用(web应用,task应用等),通过biz层,调用不同service api(不再涉及dao等底层服务)

如此一来,底层实现发生变化,比如数据库重构等,只要维持service api不变,不会涉及前台应用的变动。

如同上面说的,要不要biz,service,还是根据应用规模来决定的。

re: 区分Action, Service 和 Dao功能 stone2083 2009-05-14 20:49  
根据需求来决定的。
系统分层,和公司设立部门的概念是同样的。

一个创业型公司,很可能整个公司就一个人:即是老板,又是程序员,同时还是业务员,等等,
如同一个系统中,一个action做了所有的业务;

一个中型公司,有一个老板,有一个技术人员,有一个业务人员,有一个运营人员,等等,
如同一个系统中,有action层,biz层,service层,dao层等,通过jar包依赖调用;

一个大型公司,有CEO,有技术部们,有业务部门,有运营部门,等等,
如同系统模型中,每个模块存在独立service系统服务,依赖dao api,依赖search engine api,依赖DW api等;
前台又有不同的业务系统,有自己的action,依赖biz层,biz层又依赖独立模块的service api;
系统之间的依赖,采用SOA架构等

不同的企业规模,决定不同的公司组织架构;
不同的产品需求,决定不同的系统架构;



re: 事件消息通知系统 stone2083 2009-05-11 20:29  
多谢指点。细节部分,确实没有仔细思考过。
平时忙于项目,太少有空余时间,来思考这些技术性问题。 :(
re: JAXB vs XStream stone2083 2009-03-16 19:25  
我还有一个问题不明白:
如果需要捆绑Object,类似RPC调用,那为什么不选择hessian等二进制序列化方式的组件。
毕竟二进制序列化/反序列化效率比xml转化高多了。

当然hessian不同版本在协议上的不兼容,是一件很头疼的事情 :(
re: SLF4J+logBack, 日志领域中的新秀 stone2083 2009-03-14 13:16  
第二次看到SLF4J的介绍了。有了感性的认识。不免有些心动。等有空闲的时候,深入了解下这东东。
心态要摆正,如果纯粹为了面试而去看面试题,是没多少意义的。
真正在面试过程中,对于一些仅仅看过面试题却没有深入掌握的人,只要多问几个为什么,往往就回答不上来了。
re: 基于java实现的多层目录结构 stone2083 2009-03-07 11:08  
其实这玩意,也是临时之作,有很多不完善的地方。
主要是提供一个思路,供大家一起讨论。
re: JAXB vs XStream stone2083 2009-03-07 10:42  
@叱咤红人
我不太明白,在远程通信上,使用xml作为中间传输内容,就是为了做系统(甚至是异构系统)之间的解耦。
如果xml内容上,还捆绑了类信息,那么既要求两个系统为同语言系统,又将两个系统都捆绑到具体的一个model上。未必是一件好事。
不推荐使用tomcat默认的session机制。
基于内存的session,无可避免GC带来的问题,何况在集群环境下,同步开销太大。
推荐使用基于memcached,或者database的session。
re: Ubuntu的速度这么快? stone2083 2009-02-28 23:32  
这套桌面主题看上去不错 :)
re: 推荐Java编码工具:FindBugs stone2083 2009-02-16 12:41  
一直在用,性价比超高的一款工具。
想法是好的,做法是不可取的。
任何对第三方组件的扩展,需要遵循开放-封闭原则:只能寻找组件的扩展点进行功能扩展,不允许直接修改源码。

试想一下,你修改了源代码,以后如何解决与官方网站版本升级的同步问题?
没有团队敢使用你的包。

很早之间,我就有这个想法。但是发觉MappedStatement,SqlMapExecutorDelegate都是面向实现编程;
并且SqlMapClient也是通过:
public SqlMapConfiguration() {
errorContext = new ErrorContext();
delegate = new SqlMapExecutorDelegate();
typeHandlerFactory = delegate.getTypeHandlerFactory();
client = new SqlMapClientImpl(delegate);
registerDefaultTypeAliases();
}
直接new出来的。
所以,似乎找不到扩展的地方来实现“分页”的需求。

不知道大家是否有更好的方案,欢迎讨论。
re: What is Spring? stone2083 2008-12-02 09:49  
现在,对spring是越来越难下定义了。
通过mvnrepository看看spring的范围:
http://mvnrepository.com/search.html?query=spring
做的是越来越庞大了。

想想早几年的时候,对Spring的概念,还停留在ioc容器上。接下来又出现了AOP的概念。
如今呢?感觉spring对任何第三方组件,都要插一手。不过,话又说回来,spring对第三方组件的封装,确实提高了开发效率。

关键看,你要用spring什么了?

re: 学习Common BeanUtils stone2083 2008-09-28 23:06  
推荐使用cglib的beancopier替代beanutil做copy工作。
共3页: 上一页 1 2 3 下一页