分类目录归档:技术

系统之争

今天遇到两件事情,勾起了我对系统的思考。一件是看到一篇文章,linux和windows之争的相关文章,主要是强调windows下能干的有意义的事情linux下都能完成,而linux下能做的事情在windows下未必能完成。作者也承认了游戏不是linux的长项,但他说游戏有更成熟的替代器,如PSP等专门的游戏设备比windows下的游戏体验性要好上很多;第二件事情是思考iphone下的开发,iphone的开发环境需要在mac os下进行,这使得我目前比较难办,要么买一台mac的设备,这是比较保险的一种做法,要么尝试虚拟机安装mac os,或者在x86机器上直接安装mac os。但这几种做法都存在着一个问题,我为了iphone的开发真的就要从自己熟悉的windows系统转到mac os上去吗?

确实挺难办的,所以才成就了VMWare和VMPlayer这样的软件,因为很多时候我们都需要多个系统,有时候仅仅是满足我们一方面的要求而已。我非常赞成并支持linux下编程的做法,所有的程序或配置都能用文本的形式描述出来,而不需要复杂的ide,因为IDE毕竟需要一个庞大系统的支撑,切换成另外一个系统就不是那么简单的一件事情了。刚看完linux下处理问题的优势,就让我遇到了IOS开发的难题,真是不得不说这是一个极大的讽刺,每个系统公司都想让自己的系统占为用户的主导,这就导致了用户选择上的障碍,开发上的障碍,我为了开发.NET程序不得不装一个windows系统,我为了开发IOS程序,不得不装一个MAC OS;为了他们,我不得不在linux, windows, mac os三者之间做出选择,或者三者皆用,但这样要耗费掉我们多少精力啊

虽然虚拟软件可以解决一部分的问题,但并不能解决全部的问题,一些系统升级带来了开发不兼容的问题迟早会出现,到时候还是不得不再寻找一些这样的设备来完成自己的任务

c#对sqlserver中uniqueidentifier类型数据的as string 值为空白的问题

从数据库取数据我们习惯用以下代码:

string title = rows[0]["title"] as string;

当取的数据是uniqueidentifier类型,如id,则我们得到的数据就会为空白,可用如下方法解决:

string id = rows[0]["id"].ToString();

这个问题困扰了我近半小时,我也一直坚信uniqueidentifier是另外一种类型的string,但好像其遵循一定的规律,如果不符合这个规律也会报错,所以我不太喜欢使用它来作为ID,但困于旧代码的限制,目前只好这样做

git-svn协同工作

现在工作中已经离不了版本控制了,而作为两种目前比较流行的版本控制软件,SVN和GIT各有各的优势。SVN中小单位使用比较广泛,GIT作为分步式的版本控制更加能体现版本控制的独立性。在以往的工作中,我总是把它们分开来使用,因为现在不缺少git和svn的服务器,googlecode对两种版本控制都做了很好的支持。

但由于历史的原因,我还不能完全切换到GIT上工作,目前我们的项目大部分使用VISUAL SVN作为服务端,代码托管到WINDOWS服务器。在此之前我主要使用SVN客户端进行工作,但缺点显而易见,由于我们的SVN服务器是局域网,所以回家以后就不能再连到服务器,做的一些工作想做一个暂时性的保存是不可能的,如果能够整合GIT和SVN的各自优势,则就不会出现这些问题了。

而今天,最新版本的mysysgit和其外壳tortoisegit 已经完美支持git-svn和中文了,下面我说一下操作的步骤:

1、用git bash执行

git svn clone  https://svn-path/git

这句是针对visual svn的,因为大部分都是https协议的,又没有证书,如果不先用命令行你就没有办法选择和输入用户名密码,选择永久接受,并输入用户名密码,获取版本库

image

2、尽情使用git add, git commit ,git status, git log,然后git svn dcommit就可以了,期间你可以使用任何换基操作,最好不要跟原来的冲突,整合后再提交你的修改

3、tortoise git 的show log和diff相当好用,比命令行更加直观化,其blame可以让你看到整个文件的一生,让人有种时光穿梭的感觉

到此我才知道git提供换基与变基操作的真实含义,无论你在本地提交多少次,只要在dcommit前把这些合并一下,svn版本库里面就不会出现你合并前的操作记录,给别人看起来也更加清爽。

另外两个比较有用的设置,git bash虽然好用,但每次都要进行路径切换。可将git目录下的bin目录设置到path中,在工程目录按住shift右击,“在此处打开命令窗口”,就可以进行git操作了,如果ls会出现中文乱码,就直接用dir好了,这个保证不会有问题,使用git的相关命令也没问题,甚至你可以在任何地方使用vim编辑器了,多么酷的一个功能啊!

struts标签include页面不能显示

使用struts2标签<s:include value=”bottom.jsp” />始终不能显示,但上面的<s:include value=”top.jsp” />能够正常显示,让我查了好久,原来是在bottom.jsp使用了一个标签,但语法错了,将value写成了vlaue,所以不能正常加载

这个错误浪费了我至少30分钟时间

convention-plugin struts2 零配置

相对于是其他语言来说,java的轮子实在太多了,好用的不好用的一股脑的全部上来。能用的不能用了,只要你用在了你的项目里面,就说明你牛B。struts + spring + hibernate虽然已经成为现在java开发的主流,但我却一点也不敢苟同,其学习成本高,开发效率低下,开发出来的东西速度没保证,安全性也不能得到明示提高,实在搞不明白,因为一个小功能,其他语言一天能搞定的事情,要花一周的时间拱框架,再花一周的时间开发,开发出来的功能经过测试性能又达不到!

我们现在关注的地方应该有所转变了,我认为主要有两点需要提高,中间跳来跳去的环节都免了吧:

1、提高安全性,无论数据库注入的安全性,还是XSS跨站的安全性,在开发中应该让我们多注意这些方面的东西。

2、提高用户使用的舒适度,UI的提升也是必不可少的一个环节。

也许很多人会说,没框架不能协同,没框架不能很好完成大型项目开发,但我觉得,只要有一套良好的代码规范,并且所有开发人员都按照这个规范去做,无论用什么语言,开发多么大型的项目,所得到的结果都是良好的。为了代码的安全性与可回溯性,版本控制软件也必不可少。

今天接后一同事的项目,要在这个项目上改造成另外一个项目,并提供给别人使用,SSH框架,理论上来说整个开发过程应该还是比较熟悉的,唯一不知道的是他使用了convention-plugin实现struts的零配置,0配置就代码你使用默认配置,这就导致了我在配置文件里面找不到他页面跳转的路径。当然,查看他的jsp主目录很快就能看出其中的规律,但不知道他的默认配置写到那个地方还是让我心里有点不舒服。

于是google了一下其默认路径WEB-INF/content才知道,原来这是convention-plugin的功能,其配置当然在其jar包里,对开发人员是透明的,当然你也可以在struts.xml里面修改其默认配置。

git跟金山快盘实现私人代码协同开发

使用github和googlecode都有一个问题,如果你不愿意为些付费的话,就只能把自己的代码公开。有没有一种即免费又可以使用git进行协同开发的工具呢,经过探索与技术的进步,金山快盘已经具备了这个实力

1、安装git客户端和Tortoise Git(更好支持中文)

2、安装金山快盘客户端,最好新建一个账户仅用于同步代码使用,或者新建一个目录同步代码

3、在金山快盘建项目目录,将使用

image

4、勾选Make it Bare,点击OK就建好了一个空的仓库image

5、将项目目录推送到快盘目录(要自定义快盘目录,并选用英文名称)

这样就可以实现本地代码与快盘上的bare库的同步了,现在快盘对碎小文件的同步速度也有了大大的提高,所以基本不用担心速度问题。

接下来该讲一下怎么样协同操作

1、将这个项目目录共享给快盘好友

image

 

2、填写你好友的快盘账号,赋予可编辑权限,点击应用就可以了

image

3、通过你好友的快盘,查找到共享的这个目录,并使用git clone到本地,这样就实现了两的同步

同样,加人的操作都是通过快盘来实现的。这样就完成了多人协同开发的问题。

这里有一个问题,快盘并不像github 或googlecode那样可以判断多人同时提交的问题,如果快盘出现同步提交时会出现后者覆盖前者的问题,所以在一个人提交完成未同步完成时,另外一个人千万不要同步代码,不然可能会出现不可预料的问题。

不管怎么说,这样就实现了不花钱托管私有代码的目的,而且还能通过简单的操作实现多人协同开发,不得不说是开发人员的一大福音啊

使用googlecode代替静态页面托管平台

googlecode是我常用的代码托管平台之一,由于后来git的出现,而googlecode当时不支持git托管,所以转向了github。但大概一年前,googlecode 支持了git,不过大陆访问不方便,于是也就没有及时转换,直到近期,再次发现git已经可以从大陆正常使用了,所以把部分静态的文件托管到了googlecode。

如果你的代码致力于开放,或者你的代码不需要特别的加密,或者你想共享自己的设计,那么你就可以把自己的设计或页面上传到这里来,这里提供了一个外链的窗口,可以及时给别人演示与共享。

很简单,在http://code.google.com/下方找到Create a new project,然后填写必要的信息,选择托管的方式,推荐使用Git,点击下方的image,就完成了项目的新建。

image

在项目的主页面http://项目名称.googlecode.com,点击Source,这里提供了获取和提交的方式,所以,只需要按照上述方式,通过git把代码拉下来,然后存放文件,提交就可以了。

image

那如果访问自己提交的文件呢?可以在Source->Browse里面找到,点击某个文件,然后View raw file就可以查看到了。其实地址是有规律的,就是http://项目名称.googlecode.com/git/+内部路径就可以了,这样就可以方便管理自己的静态文件了。

工作中不可缺少的工具

每个人每个时期都有自己喜欢的工具,以前的我可能不知道这些工具的作用,以后的我也可能不再喜欢再用它们,但今天它们在我的生活在扮演着重要的角色,是我吃饭的家伙:

1、先说说操作系统,目前我机器上共有两种操作系统windows(winxp win7 win8) 和linux(CentOS)。当然windows对我的影响最大,因为我绝大部分工具都是在它的上面完成的,而且现在的主要操作系统还是win7,虽然也是用的五块一张的盗版,但对微软的致敬之情溢于言表。windows上有各种我们熟悉的软件和应用,构成了我们互联网的生活。

image

2、代码编写软件Notepad++,这是我最喜欢的一款代码编写软件,现在的我已经将java,php,c#.net转变成了文本文件,可能在执行效率上有一些差异,但对于我代码的管理和编写无疑是一个福音。我不需要因为要写现行.net代码再安装个近3G的VisuStidio,也不需要因为要写两行java代码安装近1G的MyEclipse并配置各种复杂的功能,一切由于Notepad++而简单,简单的打开一个代码文件,编写两行,迅速调试并完成,高效率!

Notepad  -logo-icon

3、版本控制软件TortoiseSVN,TortoiseGit,目前基本上处于两者共用的书面,svn的便利性在于大家使用范围比较广,服务端搭建比较方便。而git在于其分布式的灵活性,再加上代码托管平台GitHub和GoogleCode,一切变得那么的完美,当然我们不能忘记元老SourceForge以及其贡献。

image

4、图像处理软件Photoshop,我使用的也是当前盗版的软件,他强大的处理图片的功能是设计师的最佳搭档,我使用它主要用来处理一些日常的图片剪切功能罢了。

image5、输入工具QQ五笔:它是除了操作系统之外最令我不舍的一款软件,当然不一定是QQ五笔,但其本身有自己特色,其快捷截图功能让我从搜狗五笔转到了QQ五笔。我们使用的也许只是简单的输入功能,但对于这样一款每天都要使用的软件还是有必要认真挑选一下的。

images

6、email信箱:gmail,qqmail,现在即时通信软件已经不是我联络客户的主要工具,而比此更重要的是电子信箱,目前我使用比较多的是gmail和qqmail,我把它们分成不同的功能,一个收一些私人信件,一个收一些国内的一些邮件,而qqmail对gmail的模仿也越来越像,不时还加入一些个性化的东西,也渐渐令我不舍

images (1)

7、虚拟软件VM Player,找到的一款非常好用的虚拟软件。现在我们的个人PC机已经足够强劲,有时候并不能发挥其全部作用,所以拿它装一些新奇的系统,或者某些软件不适合装在一个操作系统上,这样就可以虚拟出一个系统来完成想要完成的工作,最后删除也方便。如果宿主系统出现问题需要重新安装时,对虚拟机也不会产生任何影响,这样就把问题最小化。

boot

平板电脑

在我买iphone之前,最想买的并不是手机,而是ipad,只是由于身边每个人都在劝阻我才作罢。当时在国内还没有上市,水货市场的价格也比较高,大约要5000块左右。因为我当时还在用诺基亚,其实最困扰我的问题是看书,怎么样在地铁里看书更方便一些,显然我的小屏手机已经不太适合我,而iphone4和ipad都没有在大陆上市,所以就想买一个ipad来完成自己看书的愿望。

但显然听朋友的劝阻是正确的,因为在不久后,ipad登陆国内市场,价格是更有冲击力的3600左右。如果我花5000元买掉的话,可能现在要后悔了。尽管没买,但后来还一直留意着平板的发展,直到今天ipad3发布,windows8横空出世,我才渐渐发现我们都在模糊着平板与PC之间的区别。而如果此时还没有一个平板的话,显然就是比较落伍的人了,而我手上只有一个kindle fire可以拿出来充当一下平板。

不可否认,ipad在各种应用的炫丽、实用上都比竞争对手高一个等级。软件种类也可谓丰富多彩,给人的诱惑还是不小的,虽然我现在手上有了kindle fire,但还不得不承认,它们之间的差距不仅仅是价格上的,实实在在的存在功能和性能上的差异。软件种类上也不是一个层次的。

但差也有差的好处,他7吋屏让我们携带起来更方便。没有3G,没有摄像,没有MIC,都能让你更专注于阅读,当然我现在还真正开始把它用于阅读,大部分时候我还拿他看美剧,打发无聊时间。其实地铁上的时间不仅无聊,而且有时候还是一种煎熬,所以我从来不能缺少打发时间的武器,书,杂志,报纸,手机,平板,哪个都行,即使有时候这些都没带或者都不便于拿出来的时候,观察周围的人也成为了一种生活的态度。还要回到kindle fire上面来,如果能够在国内顺利访问到amazon的话,且你有那么多钱的话,你可以直接从上面找一些电子书来看,不过都是英文的。如果你再有些钱的话,可以上面下载歌曲,电影。这些也要在你有高速网络支撑的情况下,如果像我们现在单位的这种网速,怕再好的服务也没办法提供。

今天ipad3(暂且让我们这样叫他)推出,给出了更高的性能,还算平民化的价格,替代PC的趋势都让人有兴趣入手一台来玩玩。前段时间我也在考虑是否更换一台手机,智能机的寿命两年已经算是比较长了,一直在关注galaxy note,但后来由于经济原因不能成行,现在感觉自己还是庆幸的,任何电子产品都是消费器,买过来不可能会增值,这点要看清楚。

最后,今天是“38”,所有的女性同事已经提前放假回家了,祝节日快乐

swfupload和asp.net接合需要注意的问题

如果直接运行官方所给的示例是能够成功运行的。但如果想运行在“无dll”文件的环境里面还需要注意以下几点:

1、页面session和flash session是不相同的,所以在操作的时候还要把Global.asax里面的内容放到工程下。因为这个示例是将上传的图片存放到内存中的,所以每次都要从session中取信息,如果不在request开始前进行操作,页面跟flash取到的是两个不同的会话,这就会成就图片上传成功,但看不到上传的内容。

void Application_BeginRequest(object sender, EventArgs e)
    {
        /* Fix for the Flash Player Cookie bug in Non-IE browsers.
         * Since Flash Player always sends the IE cookies even in FireFox
         * we have to bypass the cookies by sending the values as part of the POST or GET
         * and overwrite the cookies with the passed in values.
         *
         * The theory is that at this point (BeginRequest) the cookies have not been read by
         * the Session and Authentication logic and if we update the cookies here we’ll get our
         * Session and Authentication restored correctly
         */

        try
        {
            string session_param_name = "ASPSESSID";
            string session_cookie_name = "ASP.NET_SESSIONID";

            if (HttpContext.Current.Request.Form[session_param_name] != null)
            {
                UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
            }
            else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
            {
                UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
            }
        }
        catch (Exception)
        {
            Response.StatusCode = 500;
            Response.Write("Error Initializing Session");
        }

        try
        {
            string auth_param_name = "AUTHID";
            string auth_cookie_name = FormsAuthentication.FormsCookieName;

            if (HttpContext.Current.Request.Form[auth_param_name] != null)
            {
                UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
            }
            else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
            {
                UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
            }

        }
        catch (Exception)
        {
            Response.StatusCode = 500;
            Response.Write("Error Initializing Forms Authentication");
        }
    }
    void UpdateCookie(string cookie_name, string cookie_value)
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
        if (cookie == null)
        {
            cookie = new HttpCookie(cookie_name);
            HttpContext.Current.Request.Cookies.Add(cookie);
        }
        cookie.Value = cookie_value;
        HttpContext.Current.Request.Cookies.Set(cookie);
    }

当然,另外还需要通过ASPSESSID参数将sessionid传递给服务端

post_params : {
    "ASPSESSID" : "<%=Session.SessionID %>"
},

2、如果将Thumbnail.cs的内容改成Thumbnail.txt然后分别引入到upload.aspx和thumbnail.aspx中,也会造成问题,因为两个页面对应是并不是同一个类,所以会造成转换失败同样取不到所上传的图片。解决方法可以是将upload.aspx和thumbnail.aspx两个页面的内容合并,也可以是使用App_Code。

3、将文件保存目录中,通过Directory.Exists来判断目录是否存在,通过Directory.CreateDirectory来创建目录

HttpPostedFile file_upload = Request.Files["Filedata"];

display_file_name = file_upload.FileName;
file_size = file_upload.ContentLength;

string dir = DateTime.Now.ToString("yyyyMMdd");
string filename = DateTime.Now.ToString("yyyyMMddHHmmssfff");

string serverpath = Server.MapPath("file/") + dir + "/";
if (!Directory.Exists(serverpath))
{
    DirectoryInfo dirinfo = Directory.CreateDirectory(serverpath);
}
string ext = file_upload.FileName.Substring(file_upload.FileName.LastIndexOf("."));
physical_file_name = filename + ext;
physical_file_path = serverpath + filename + ext;
file_upload.SaveAs(physical_file_path);

4、在用input file模拟时,还要记得在form的提交方式

<form id="form1" action="upload.aspx" method="post" enctype="multipart/form-data">

5、补充一下html头部的信息写法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="author" content="tohours.com" />
        <title>后台管理登录</title>
    </head>
<body>
</body>
</html>