Posted by Kevin Luo at 9 March 2010

Category: 新闻

Tags: ,

成都深龙软件有限公司由加拿大外商于2005年夏天在成都高新区孵化园创办。主要从事软件外包服务业务。我们的顾客来自美国,加拿大和台湾。我们的外包业务主要是软件产品开发和实施全过程:需求分析,软件设计,软件开发,软件质量检测,和软件维护和支持。深龙软件经过过去几年的创办、磨炼、调整、发展艰难过程,公司基本在中国的北美外包产业迈开了第一步,形成了自己独特的一整套外包业务流程和规范,培养一批英语沟通熟练的技术骨干。最近公司和几家美国公司签约了长期合作协议,将承担大量的软件开发业务。因此公司急需一批能力强,经验丰富,英语流畅,敢于挑战的开发人员和管理人员。

.NET (Silverlight/C#) 高级软件工程师

职位概括

参与深龙软件和加拿大公司合作开发、设计的仓库管理ERP软件。利用微软的最新.NET 3.5和即将推出的.NET 4.0平台和Silverlight技术,把传统的软件体系改善成为与互联网有机结合的SaaS模式。我们急需两名在.NET,尤其是Silverlight/WPF,有多年丰富经验的中级以上的软件工程师和架构师。

任职资格

1、 计算机或相关专业本科学历;
2、 5年以上.NET/C#/ASP.ENT工作经验;有几年大型企业软件开发设计经验。优先考虑ERP开发经验;
3、 3年以上Silverlight/WPF工作经验。有网络企业软件(基于Web2.0,SaaS,RIA)经验优先;
4、 较强的语言表达能力和文档撰写能力,良好的英文阅读书写能力;
5、 熟悉构造网页网站的基本技能和原理,具有网页或者界面美工设计的能力;
6、 较强的发现问题,分析问题的能力;
7、 工作责任心强,细致,耐心;
8、 熟悉SQL语言和SqlServer 2008数据库操作和使用。对数据结构的关系、理论,有着深刻的理解和实践;
9、极强的团队协作精神、优秀的学习能力与创新能力,工作认真,态度端正;


QTP自动化测试高级工程师(急聘)

岗位职责

1、 制定、编写软件测试方案与计划;
2、 根据测试计划,使用HP Quick Test Pro (QTP) 编写自动测试程序;
3、 每日运行测试程序,检查测试结果,编写测试报告,提交测试结果;
4、 测试环境的设计、设置,完善测试规范流程、创建和维护测试用例;
5、 改进软件测试流程、工具、和质量。
6、 参与测试结果评审; 

任职资格

1、 计算机或相关专业本科学历;
2、 3年以上自动化测试工作经验;有几年大型软件手动测试经验也可以考虑;
3、 熟练编写QTP(或者其他)测试脚本,熟练操作和使用QTP开发环境,熟悉QTP开发语言VB;
4、 了解软件工程学思想和方法,了解基本数据库系统及网络知识;
5、 较强的发现问题,分析问题的能力;
6、 较强的语言表达能力和文档撰写能力,良好的英文阅读书写能力;
7、 工作责任心强,细致,耐心;
8、 其他自动化测试脚本(例如WinRunner)经验或大型自动化测试工具使用经验者优先;
9、 熟悉SQL和Oracle数据库系统优先;
10、熟悉VB, Flex/AIR, Java, C#, C++开发环境和编程工具优先;

工作地点在成都,有兴趣的朋友请与我联系:

kevin.luo@siloon.com


Posted by Kevin Luo at 4 March 2010

Category: 我的事

朋友的公司想要开发一个类似http://www.mycanvas.com的桌面版客户端,客户端的基本流程如下:

用户模式:

  1. 用户选择想要的相册产品,尺寸。
  2. 选择主题,进入相册编辑
  3. 编辑相册的过程中可以本地保存相册,可以随时打开编辑。
  4. 制作完成后生成PDF文档,文档上传服务器开始打印流程

管理员模式:

  1. 管理员可以制作,保存主题,保存的主题可以供普通用户客户端下载使用。

我们已经完成了项目的技术难点部分:

  1. 完成了相片的编辑控件,控件和Mycanvas的相片控件器用法相同(旋转,裁剪,缩放,滤镜,遮罩,边框等)。
  2. 文字控制器完成(对嵌入文字的粗体设置有bug)
  3. 大分辨率画布的设置
  4. 大分辨率PDF打印

你们可以在项目中使用该控件,对控件进行任意的修改,对控件不明白的地方,我们提供帮助。下面是控件Demo的截图。

照片控制器

1

文字控制器1

2

文字控制器2

3

这个控制器是我和我的团队年前帮朋友做的,但由于我时间的问题,现在不能再继续这个项目。现寻求团队(个人或者公司)对客户端进行开发,关于整个项目的体验,你可以直接尝试mycanvas.com. 我们和他的操作流程差不多。具体的需求我们谈过以后会提供给你。如果你有兴趣请用以下方式联系我。

  1. Email: kevin.luo.sl@gmail.com (随时在线)
  2. QQ: 10863511
  3. MSN: kevin.luo.sl@hotmail.com

Posted by Kevin Luo at 1 March 2010

Category: 我的事

Tags: , ,

今天看了Jan写的Flash Player: CPU Hog or Hot Tamale? It Depends. 有感而发,Jan的文章明显是回应水果老大乔布斯同志之前的关于Flash player是CPU杀手的言论发出的。也许还有个同学不知道事情的始末,我来简单说一下。

近期苹果发布了一款掌上电脑iPad, 但是作为一款电脑来说他不支持全球使用虑达9X.XX%的Flash Player。乔布斯一开始直说Adobe的人都太懒,Flash Player漏洞很多,等等等等。但后来乔布斯同志说他们之所以不用Flash是因为Flash太消耗CPU,如果ipad引入Flash Player, 他们的电池只能用1.5小时(不用的话号称10小时)所以他们选择了支持HTML 5 而放弃Flash,除此之外乔布斯还到处又说别人也不要使用Flash, 有传言说和苹果合作的纽约时报已经决定完全放弃Flash。

我们接着说Jan的这篇文章,这位Jan也是牛人,从1990年就开始从事视频相关工作,有13本关于视频方面的书出版。他的这篇文章很客观的指出了HTML5 与Flash Player 10/10.1在视频方面对CPU消耗的情况。还是毛XX说的好(我不清楚加上主席后我的博客会不会被河蟹,还是算了),实践是检验真理的最佳标准。

也许还有同学不了解HTML5, 简单说一下

HTML5是新的HTML标准,目前被最新的Safari, Chrome, IE8, FireFox 支持。HTML5中增加了许多新特性,例如嵌入音频、视频和图片的函数、客户端存 储数据、交互式文档等。HTML 5也是传说中要终结Flash Player的新标准。为什么需要终结Flash Player呢?理由很简单,Flash Player已经成为一种标准,但是他却是Adobe一家的产品,这怎么能行呢。于是HTML 5的产生是必须的。乔布斯同志说不用Flash Player而用HTML5是因为CPU问题,这个实验也证明了在苹果自己的系统上,HTML 5在Safrai上的效率确实要强过Flash 2被有余,但是在Windows 平台上,HTML 5 的效率却远远低于Flash Player。虽然如此,我觉得乔布斯通知不接受Flash Player根本原因还是他的App store。 iphone OS是一个平台,Flash 也是一个平台,乔布斯在ipad或者iphone中引入Flash, 无疑会对App Store造成非常大的冲击。Adobe和苹果也许永远也不可能成为合作关系,Flash平台和苹果App Store从根本上产生冲突。他们也许永远是对手!

Jan在以下环境对HTML 5和Adobe进行了测试

浏览器

windows:

- Apple Safari – 4.0.4 (531.21.10).

- Mozilla Firefox – version 3.6

- Google Chrome – 4.0.249.89

- Microsoft Internet Explorer – 8.0.7600.16385

- Adobe Flash Player – 10.0.45.2 first, then 10.1.51.95

Mac

- Apple Safari - 4.0.4 (6531.21.10,55180).

- Mozilla Firefox – version 3.6

- Google Chrome – 5.0.307.9 beta

- Microsoft Internet Explorer – 8.0.7600.16385
- Adobe Flash Player - 10.0.45.2 first, then 10.1.51.95

下面是对比结果

windows:

dc2hxh8z_308rgf7kxhg_b

Mac

dc2hxh8z_305n7dc9whh_b

我们可以看出,在Mac上,Flash Player在Safari上的表现确实不如HTML 5, 效率低了2倍,即使换上了Flash player 10.1. 还有有1.5倍的差距。由此看来乔布斯的说法还是有根据的。但除此之外Flash player的表现完全胜出HTML5, 当然这也许是由于其他浏览器对HTML 5的支持还有待提高。但Flash player在Windows平台上各种浏览器下的表现都是相当不错,尤其是Flash player 10.1,不知道这是否可以说明,如果是基于Windows平台的电脑,手机或者掌上电脑,Flash Player 还是浏览器视频播放的首选。

最后要说的是Flash player在Linux环境下的表现差也不是一天两天了,真希望这个情况在未来可以好转,我长期在Mac环境下开发Flex程序,这个问题确实是比较头疼。我支持Adobe,同时也是乔布斯通知的忠实粉丝。所以我决定HTML 5, Flex两手都要抓,两手都要硬!

Posted by Kevin Luo at 24 February 2010

Category: Flex 迷你教程, P2P, 未分类

Tags: , , ,

终于有时间试下Strtaus 2的p2p多播功能了。之前看的视频介绍中,Adobe描述一个非常理想的多人P2P数据共享方式。但是今天试了一下后发现视频的速度非常慢(视频的发布和接收端都在一台机器上),感觉上视频被发送到了什么地方后才传了回来。这这……好吧,就当是BETA的问题了,WAIT AND SEE. (2/25日更新,2/23日发布的Flash player 10.1 beta 3 看来解决了这个问题,Demo的速度现在非常正常)

准备工作:

先了解一下什么是stratus以及什么是RTMFP,你可以到http://labs.adobe.com/technologies/stratus/看下官方的解释或者直接看我原来的 Flex 迷你教程 — 基于Stratus的P2P网络电话 (1)(2)(3) 先学习一下Flash p2p的基础. 简单的说原来的Stratus 实现了flash player之间点对点的传输数据,而今天要讲的stratus 2 不仅支持单个的点对点数据传说,还引入了多播的概念。

在原来的stratus中如果我们要做一个多人同时在线的应用,比如多人视频。那么我们需要把在线的所有人都链接起来,类似蜘蛛网的结构,网中的每个人需要与其他所有人链接,这样数据才能在所有人中共享。这种模式在多人连线中是不可取的。假设我们用户A发布一个视频想让其他10个用户观看,那么10个用户都需要链接到他。就中国的普通用户的网络带宽来说,这就是极限了。而Stratus 2 中 “组” 的概念解决了这个问题。用户A发布视频让同一个组中的其他10个人观看。他们并都从A处获取视频。而有可能通过组中的其他用户获取A的视频。这也就是P2P的模式了,每个人都可以作为数据的发出者,数据以最优的方式被观看者收到,参与的人越多,数据的副本就越多。视频的速度也就越快。 (more…)

Posted by Kevin Luo at 10 February 2010

Category: 新闻

Tags:

2010年的2月2日,Adobe发布了AIR 2 beta 2. 由于当前的一个项目需要操作到硬件,所以早早的使用的AIR 2 beta 1进行开发。不过也确实体验到了Beta 1 中Bug的厉害。

1. 在1.5 中运行很好的程序刚换上AIR 2并打包成exe后,立马在退出程序时导致windows爆出程序关闭异常。
2. 在1.5中运行得很好的数据库操作部分(transaction),在AIR 2中出了莫名其妙的错误。找不到具体原因。只有暂时放弃它的transation, 改用了自己的代替。在正式版发布后再替换回来吧只有。

此次AIR 2 beta 2的更新包括

1. 打印增强。
2. TTL/SSL sokcets.
3. 等等

详细信息请看这里 http://labs.adobe.com/wiki/index.php/AIR_2:Release_Notes

Posted by Kevin Luo at 27 January 2010

Category: 我的事

Tags:

这个和Flex没什么关系,凌晨是Apple的一年一度的发布会,很激动。

谁能捐钱给我买平板电脑,我接受任何形式的捐赠,哈哈……..

Posted by Kevin Luo at 23 January 2010

Category: P2P

Tags: , ,

太激动了,等这天等了好久了,Adobe 2008年发布了Stratus服务器的Beta版,支持flash player之间的点对点链接,今天,Adobe再次更新Status服务,这一更新也使Flash真正进入P2P的世界。现在Adobe的例子还没有出来,感兴趣的朋友可以关注以下几个地方 (引自 http://www.flashrealtime.com/updated-stratus-with-groups-and-multicast/):

- Read more about new Stratus here at Kevin’s blog.
- Also check new Labs page about RTMFP Groups.
My article about Multicast in Flash Player 10.1
Read about differences between Stratus and LCCS

Posted by Kevin Luo at 21 January 2010

Category: AIR 迷你教程

Tags: ,

AIR 2.0 有很多令人期待和振奋的功能,使得AIR向成熟的桌面应用程序开发环境又进了一大步。上一篇文章里介绍了ServerSocket的用法,这篇教程中将向大家介绍NativeProcess,在AIR2.0中我们可以使用程序默认的打开方式直接打开一个外部的应用程序 (file.openWithDefaultApplication()) 或者 通过今天要讲的启动进程方式运行一个程序。

AIR与本地应用程序的交互是AIR 2.0的一个重要更新,这个功能的实现可以帮助我们做到在AIR 1.5时代很难完成的事情,比如我在项目中就需要操作一些硬件,但AIR不能直接操作端口,所以只能借助其他的小程序来实现,现在我们就可以很容易的操作这些小程序以达到操作硬件的目的,而Flex (AIR)与JAVA的结合很早就已经开始了,但由于早期AIR的局限性,想要把JAVA直接部署在客户端还是比较麻烦的事情,但是从AIR2.0开始我们不用担心了。现在我们用很简单的方式就可以在AIR程序中集成TOMCAT, 一次性的将后台与AIR部署到客户端。

程序的原版(Flash Builder 4版)同样是从http://coenraets.org/获得,有兴趣的朋友可以关注这个博客。我的例子仍然使用FLEX 3.

Demo过程

  1. 下载安装 AIR 2.0 beta runtime.
  2. 下载AIRAppWithEmbeddedTomcat..exe 或者 AIRAppWithEmbeddedTomcat.dmg (NativeProcess 必须在程序发布为相应平台的应用程序后才可以使用,发布的方法这里就不介绍了,可以参看http://help.adobe.com/en_US/FlashPlatform/develop/air/building_apps/WS789ea67d3e73a8b22388411123785d839c-8000.html)
  3. 安装运行AIRAppWithEmbeddedTomcat.exe, 修改JAVA_HOME,如果默认的路径不对
  4. 点击 “启动” 可以开启TOMCAT(端口是8080)。在JSP实例和RemoteObject实例中可以看见加载JSP页面和使用RemoteObject获取数据的测试。

(more…)

Posted by Kevin Luo at 6 January 2010

Category: AIR 迷你教程, 未分类

Tags: ,

AIR 2.0 一个非常重要的更新是支持了对Socket的监听,包括TCP (ServerSocket)以及UDP(DatagramSocket)。另外也支持了以UDP方式对外发送信息。这两个功能的增加无疑大大的增加了AIR的应用范围,比如………..这一下想个具体的还是比较困难,比如协作型的应用程序。

这篇教程将使用ServerSocket功能做一个HTML服务器,这个不是我原创的,是看到一个老外写的,觉得很有意思,是一个ServerSocket的好例子,原文在 http://coenraets.org/blog/2009/12/air-2-0-web-server-using-the-new-server-socket-api/. 原文是Flash Builder 4 版本的,这里我给大家的是Flex 3版本, 使用源代码请先下载AIR 2.0 SDK

Demo过程

  1. 下载安装 AIR 2.0 beta runtime.
  2. 下载MiniAIRWebServer.air
  3. 安装运行 MiniAIRWebServer.air.
  4. 运行 http://localhost:8765/HelloWorld.html (端口以你在运行MiniAIRWebServer.air后输入的为准, 注意安装MiniAIRWebServer.air后安装文件夹下的webroot/HelloWorld.html, 我们运行的就是这个文件)

运行效果如下:

airserver

源代码

?View Code ACTIONSCRIPT3
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" close="closeHandler()" creationComplete="init()">
	<mx:Script>
		<![CDATA[
			import flash.events.Event;
            import flash.events.ProgressEvent;
            import flash.events.ServerSocketConnectEvent;
            import flash.net.ServerSocket;
            import flash.net.Socket;
            import flash.utils.ByteArray;
 
            import mx.controls.Alert;
 
 
            //ServerSocket,用于监听TCP下的链接
            private var serverSocket:ServerSocket;
 
            private var mimeTypes:Object = new Object();
 
            private function init():void
            {
                // 支持的类型
                mimeTypes[".css"]     = "text/css";
                mimeTypes[".gif"]     = "image/gif";
                mimeTypes[".htm"]     = "text/html";
                mimeTypes[".html"]     = "text/html";
                mimeTypes[".ico"]     = "image/x-icon";
                mimeTypes[".jpg"]     = "image/jpeg";
                mimeTypes[".js"]     = "application/x-javascript";
                mimeTypes[".png"]     = "image/png";
 
                // 初始化服务器文件夹
                var webroot:File = File.applicationStorageDirectory.resolvePath("webroot");
                if (!webroot.exists)
                {
                    File.applicationDirectory.resolvePath("webroot").copyTo(webroot);
                }
            }
 
            private function listen():void
            {
                try
                {
 
                    serverSocket = new ServerSocket();
                    //监听链接
                    serverSocket.addEventListener(Event.CONNECT, socketConnectHandler);
                    //绑定端口
                    serverSocket.bind(Number(port.text));
                    //开始
                    serverSocket.listen();
                    log.text += "正在监听 " + port.text + "端口...\n";
                }
                catch (error:Error)
                {
                    Alert.show("端口 " + port.text + 
                        " 也许正在被使用,请尝试另一个端口.\n(" +
                        error.message +")", "错误");
                }
            }
 
            private function socketConnectHandler(event:ServerSocketConnectEvent):void
            {
                var socket:Socket = event.socket;
                //监听数据
                socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
            }
 
            private function socketDataHandler(event:ProgressEvent):void
            {
                try
                {
                    var socket:Socket = event.target as Socket;
                    var bytes:ByteArray = new ByteArray();
                    socket.readBytes(bytes);
                    var request:String = "" + bytes;
                    log.text += request;
                    var filePath:String = request.substring(4, request.indexOf("HTTP/") - 1);
                    var file:File = File.applicationStorageDirectory.resolvePath("webroot" + filePath);
                    if (file.exists && !file.isDirectory)
                    {
                        var stream:FileStream = new FileStream();
                        stream.open( file, FileMode.READ );
                        var content:ByteArray = new ByteArray();
                        stream.readBytes(content);
                        stream.close();
                        socket.writeUTFBytes("HTTP/1.1 200 OK\n");
                        socket.writeUTFBytes("Content-Type: " + getMimeType(filePath) + "\n\n");
                        socket.writeBytes(content);
                    }
                    else
                    {
                        socket.writeUTFBytes("HTTP/1.1 404 Not Found\n");
                        socket.writeUTFBytes("Content-Type: text/html\n\n");
                        socket.writeUTFBytes("<html><body><h2>Page Not Found</h2></body></html>");
                    }
                    socket.flush();
                    socket.close();
                }
                catch (error:Error)
                {
                    Alert.show(error.message, "错误");
                }
            }
 
            private function getMimeType(path:String):String
            {
                var mimeType:String;
                var index:int = path.lastIndexOf(".");
                if (index > -1)
                {
                    mimeType = mimeTypes[path.substring(index)];
                }
                return mimeType == null ? "text/html" : mimeType;
            }
 
 
            private function closeHandler():void{
            	if(serverSocket){
            		serverSocket.close()
            	}
 
            }
		]]>
	</mx:Script>
 
	<mx:HBox verticalAlign="middle">
        <mx:Label text="Port:"/>
        <mx:TextInput id="port" text="8765" width="50"/>
        <mx:Button label="Listen" click="listen()"/>
    </mx:HBox>
 
    <mx:TextArea id="log" width="100%" height="100%" />
</mx:WindowedApplication>

下载:

MIniAIRWebServer.air (99) MIniAIRWebServer.zip (100)

Posted by Kevin Luo at 20 December 2009

Category: Flex 迷你教程, 开源控件

Tags: , , ,

在项目中我们对DataGrid的要求是很高的,但很不幸的Flex 的DataGird的功能是很傻的,这就催生了AdvancedDatgrid, 它确实解决了很多DataGrid不能做的事,比如多级排序,单元格选择,树状显示数据,合并表头等,但是不知道为什么它确忘记了 “合并单元格”这么重要的事。好在牛人是很多的,于是出现了MecGrid, NecGrid这样不错的能解决单元格合并的DataGrid, 不过他们都各有缺点。

MecGrid: (http://www.mechansp.com/index.php)

1. 不支持itemrender。
2. 单元格选择时无法获知整行数据。
3. 不支持xxxFunction设置比如(labelFunction)
4. 设置很不方便。在column设置中大量使用 number作为参数,非常非常的不利于使用,在线文档对这个ResourceXML的设置也没有提到具体细节,这个很头痛.

总结: MecGrid的使用非常不方便,而且完全不支持复杂数据类型,虽然实现了很多功能但都是固定功能,扩展性不强。这让他局限在只能作为表格使用。
NEC Grid (http://www.necst.co.jp/product/ibiz/column/ibizblock/chap7.html)

nec

1. 不能改变行高。
2. 破换了itemrender的使用,我增加了一个ComboBox作为itemrender,但是他的显示完全不正常。如果itemrender的高度大于他的默认行高,显示会被切断。
3. 不支持单元格选择。

总结:这个DataGrid的使用非常方便,不过缺点也比较明显,尤其是对itemrender这条,要命的是他不能改变行高,但实际中我们的数据是很有可能换行的。另外他居然不支持单元格选择,作为一个AdvancedDatagird,单元格选择在很多时候是必要的。总的来说这个DataGrid用于对数据操作没有特殊要求的用户是不错的选择。

—————————-废话结束,教程开始的分割线—————————————

(more…)