jiangsheng

http://www.csdn.net/develop/author/netauthor/jiangsheng/
随笔 - 142, 评论 - 629, 引用 - 27

导航

关于

 
这下要维护3个BLOG了,faint 其他的地址:

所有的文章版权归原文作者所有,任何人需要转载文章,必须征得原文作者授权。
我的MVP配置

标签

每月存档

最新留言

广告

【第1页/共5页,48条】
首页
前页
1

Office Live

Office Live Blog 5号宣布Office Live的测试者暂时不再需要产品密钥来进行注册,但是注册仍然需要一个美国地址和一个信用卡帐户。从站点内容来看,OfficeLive目前的测试版面向的用户是中小企业,提供5个邮箱、30兆空间和免费国际域名(嗯,注册了一个http://jiangsheng.net),以及FrontPage(OK,我知道这玩意现在叫Office SharePoint Designer )和Outlook的功能。

尽管站点的AJAX脚本经常出错(比如在编辑页面输入+号保存之后会消失,上传文件有时会失败),但是整个界面还是比较友好的,类似FrontPage的站点管理用起来很方便,而且类似Office助手的工具栏使得用户可以很快上手。

posted on 2006-04-09 15:57:00 by jiangsheng  评论(9) 阅读(9165)

BUG,规范,断言和调试

好长时间没更新BLOG了,向大家拜个晚年先。最近没怎么写代码,转几篇在网易虚拟社区发的文章过来充数。

对于BUG的自信

Donald E. Knuth(高德纳)在TeX: The Program的前言中说:
"我相信,在1985年11月27日,TeX代码里面的最后一个BUG已经被发现和解决了。但是,如果代码中仍旧有BUG,我很高兴付给任何第一个发现BUG的人20.48美元(这是前一个金额的两倍,而且我计划在一年内把它翻倍。你看,我很自信!)" 

想知道后来发生了什么吗?

http://truetex.com/knuthchk.htm可以看到他写出去的支票的金额是从2.56美元开始翻倍的。微基百科中关于这种支票的文章(http://en.wikipedia.org/wiki/Knuth_reward_check)说,截至2001年10月为止,他写出去了超过两千张这样的支票,但是他的BUG支票是如此有名,以至于很多人把他的支票收藏起来而不是拿出去兑现(http://www.tug.org/whatis.html)。

有多少程序员在发布产品的时候可以这样自信地声明产品没有问题?

遗憾的是,现在的程序员经常把发现BUG的责任推给测试人员——“不用担心,测试人员会发现所有BUG的,这是他们的工作”。实际上,测试人员并没有开发人员的条件,他们不可能进行源代码级别的调试,很大程度上只能靠运气——没错,是靠运气,如果一个BUG很容易被发现,程序员不太可能自己没有发现它——来发现BUG。

还有一些人干脆就认为BUG是不可避免的,或者认为不值得这么精益求精(参见网易虚拟社区http://p5.club.163.com/viewArticleByWWW.m?boardId=clanguage&articleId=clanguage_108eacc622169e7&boardOffset=0的讨论),但是实际上防止BUG出现的最好的时机,就是在编写代码的时候。在编写代码一段时间之后,即使是编写者本人也可能需要一段时间来理解代码(如果不习惯写注释的话,这段时间会更长),更别说定位问题所在了。在编写代码时,如果具有良好的习惯,可以免去很多在之后消灭BUG的困难。

规范不是语法

太多人把不要使用goto奉为圣旨,从来不想去打破。他们会争论,goto会造成难以维护的难读的代码,以及使编译器无法进行优化。这两点在很大程度上是真的,但是也有使用goto可以增加程序可读性和效率时候。在这种情况下,遵循“不使用goto语句”规范会产生更糟糕的代码。

一些人喜欢在成员函数后面加const,但是另外一些人没有养成这个习惯。一个直接的结果就是,一些看起来对对象完全没有影响的函数不能在const函数里面使用。这时候应该怎么办?看看Paul DiLascia建议的,把this指针强行转化为一个非const指针(http://www.microsoft.com/msj/archive/S126E.aspx)。如果函数实际上会对对象成员造成影响(例如CToolBar::GetItemRect),这也会带来潜在危险。

为了和ANSI标准之前编写的代码兼容,ANSI C中的memchr函数的声明为

void *memchr( const void *buf, int c, size_t count );


这里c是一个字符。很明显,标准为了兼容性放弃了明确性和更强的类型检查。如果放弃兼容性,这个函数应该声明为如下形式

void *memchr( const void *buf, unsigned char c, size_t count );



微软的很多代码使用一种叫做匈牙利表示法的命名规范。这使得标识符的含义和类型更加明确——但是这是从广义的角度来说的。考虑如下函数声明

char *strcpy( char *strDestination, const char *strSource );



如果严格遵循原始的匈牙利表示法,那么两个参数的声明应该是pch开头。但是以str开头给这两个参数更多含义:它们指向以\0为结束符的字符串。
   
规范是用来在大部分时间里遵循,以及在可以得到更好的结果时打破的。

编译警告的意义

智能化的编译器开始将语法正确的语句列为警告:

while(size-->0);//注意这里有个分号 *pTo++=*pFrom++;


编译器会报告空循环问题。
但是对于以0结尾的字符串复制

while(*pTo++=*pFrom++);


,这样的警告是多余的。
更加常见的警告是在条件判断语句中

if(ch='\0') EndOfString();


为了绕过这个警告,需要添加额外的运算或者语句,或者更正错误的赋值。

while((*pTo++=*pFrom++)!='\0'){} if(ch=='\0')


一些程序员甚至将比较语句修改成

if('\0'==ch)


这样作的原因显而易见:为了减少潜在的BUG。如果你的编译器没有这样的警告,那么你可以使用一些工具来检查那些语法正确但是有潜在BUG的代码。LintProject (http://www.codeproject.com/tools/lintproject.asp)就是其中一个。但是,良好的编程习惯还是减少BUG出现的最好的方法。

在觉得警告消息太烦人的时候,不妨想想编译器的开发人员为什么要编写这么多警告消息,而不是仅仅寻求关闭警告的方法。

P.S. Visual C++的默认警告等级是3级。发布软件之前应该改成4级,之后检查所有的编译警告。

无处不在的断言

使用编译器来捕获BUG的主意很好,Visual Studio 2005甚至会报告定义的变量不符合命名规范(Warning 1 CA1709 : Microsoft.Naming : Correct the casing of type name 'welcome'.);但是我敢打赌你检查BUG列表的时候,你会发现只有一小部分BUG会被编译器抓到。很多BUG在程序运行过程中很少会出现,例如内存分配失败的问题

char* strBuffer=new char [length]; MyZeroMemory(strBuffer,length);



这段代码在绝大多数情况下会成功,但是在虚拟内存不足的时候,Windows会报告“您的系统虚拟内存太低,WINDOWS会增加虚拟内存页面文件的大小。在这个过程中,一些应用程序的内存请求会被拒绝”然后开始增加虚拟内存,在这个过程中,new这样的内存分配可能会因为内存不足而失败,而MyZeroMemory则可能会造成访问越界。如果你足够幸运,你会在产品发布之前发现这个BUG,否则,你的用户会代替你发现这个BUG。要是用户刚好没有备份的习惯,丢失了几十分钟甚至是几小时的工作进度,用户会很生气,后果很严重。

编译器不能捕获这种运行时才会出现的错误(顺便说一下,我在CSDN上居然还看到有人抱怨编译器不会报告除0错误);也不能捕获算法中的BUG和检验参数中的数据。但要是你知道怎么做的话,这类问题很容易被发现。你可以用SetProcessWorkingSetSize函数或者msconfig工具减少虚拟内存大小,或者使用Virtual PC之类的虚拟机或者磁盘配额策略来模拟内存和磁盘空间不足的情况。

你有可能想在这种极限情况下调试你的代码,但是大多数时间内,内存分配不会失败,而设置条件断点又太麻烦了。这时候可以在代码里面加上一段用来在内存分配失败时触发调试器的断言代码

void MyZeroMemory(char* strBuffer, int length) { assert(strBuffer!=NULL); }



如果使用的是MFC或者ATL,建议使用对应的宏ASSERT和ATLASSERT。现在你可以编写健壮的代码使得程序在strBuffer这块内存分配失败时也能够正常运行。

现在的问题是,加入的这些代码增加了应用程序的大小,减慢了运行速度。在解决了内存分配失败造成的程序崩溃的问题之后,有必要在发布的版本中去掉这些断言代码。一个简单的办法是使用预处理标识符:

void MyZeroMemory(char* strBuffer, int length) { #ifdef DEBUG assert(strBuffer!=NULL); #endif }



这样你可以只维护同一份代码。当然,这也意味着调试的代码在发行版中会被去除,所以为了避免不可预料的行为,为了调试而加入的代码应该尽可能少地影响应用程序的行为。

你有可能需要重新定义assert来实现扩展的行为——例如在assert断言失败中断程序时打开源文件并且跳到assert那一行——这时候你可以编写自己的断言函数,然后重定义assert为这个断言函数。

#ifdef DEBUG /*display a dialog and if the user selected break , jump to the assert line*/ void _assert(char*,unsigned int); #define assert(f)\ if(f)\ {}\ else _assert(__FILE__,__LINE__) #else #define assert(f) #endif


空的if语句块可能看起来有点奇怪,但是这可以避免和宏外的if-else产生冲突。同样,最后一行语句没有结束的分号,因为在使用的时候再加上会更加自然。

assert最有用的地方就是用来检验函数的参数——但是也可以在其他地方起作用。在程序中的断言语句越多,异常的情况就越容易被侦测到。

既然assert是代码,它不可避免的需要注释。即使是自己写的代码,过了六个月之后再来审视也可能需要一点时间来重新理解这部分代码。一个简单的注释可以把这部分时间减少:

void MyZeroMemory(char* strBuffer, int length) { /*should not be called when buffer allocation failed*/ #ifdef DEBUG assert(strBuffer!=NULL); #endif }


在编写完函数之后,应该审视函数中的代码,之后在函数的开头验证函数正常运行所需的条件。如果你在写一个库函数,那么应该在函数的文档中加入函数正常运行所需的条件——否则就会增加使用者发现BUG的难度。举例来说,Windows API的文档不可谓不详尽,但是我在用汇编调用Windows API的时候,也花了很长时间才发现调用Windows API之前栈顶要设置成4的倍数。

注意不要把一些条件当成默认成立的了。assert(sizeof(int)==4);这样的语句在一些人看来很荒谬,但是在Windows开发中通常是32位的long在一些64位平台上已经是64位的了,而在目前还不知道sizeof(int)在什么时候会升位。如果你的代码依赖于int的大小,那么写上这行可以在未来升位之后更快发现问题。

一些保守的程序员在参数错误时会让函数继续运行——返回一个错误码——但是不报告错误。在编写核心模块时这可能很有必要,但是这也经常会把BUG藏起来——在多层函数返回之后时候,错误码经常会丢失或者被替代。尽量不要使用保守编程来替代断言,如果你认为保守编程会造成定位问题的困难,那么就加上断言代码。

在一些时候,校验参数数据似乎是不可能的事情——想象一下那些被设计来搞糊涂解密者的加密算法的中间数据——但是校验这种复杂算法的方法也不是没有。为了确认手算和心算的正确性,我们会使用电子计算器的结果来进行比较,反过来,我们也可以编写另外一个的算法来断言计算结果的正确性。这种方法也可以被用来断言一个函数的汇编版本和C版本的一致性——为了获取最大性能,函数的汇编版本的算法可能和C版本的有很大差异。当然,不是每个函数都有必要用这种方式来验证,实际上,只有极其重要的算法和对性能极其敏感的代码才会需要这种双保险来验证。同样,为了调试而加入的算法也应该尽可能少地影响应用程序的行为。

最后,你不应该在发布程序时从代码中去掉断言语句,而是把它们留在那里以供你升级或者查找BUG时使用。帖来自于网易社区:http://p5.club.163.com/viewArticleByWWW.m?boardId=clanguage&articleId=clanguage_10938d0575c4afe

消灭不可预料的行为

断言并不能抓住所有BUG——它们都是人写出来的,而是人就会犯错误。一些常见的错误包括:

  • 使用状态不确定的资源
  • 在释放资源之后继续访问资源
  • 在资源重新定位之后继续引用旧的资源
  • 申请资源之后丢失对资源的引用
  • 访问时未注意是否越界
  • 忽略错误信息

这些并不是杞人忧天的问题——实际上,这些问题属于日常开发中最常见的问题。这些问题的特点是,它们并不是时常造成程序行为的异常,并且症状不可重复。以内存为例,释放内存之后编译器和操作系统通常不会自动去擦除内存中的内容,所以继续访问内存不太可能造成程序行为的异常——直到内存被重新分配出去,而另一块代码开始重写这块数据。申请资源之后丢失对资源的引用可能只是造成长时间运行之后系统资源不足而已。另外,这些问题都是算法的问题,而编译器并不会替你校验你的算法,你自己也不太可能会怀疑你自己的算法。

不要认为职业的程序员就不会犯这类错误。举几个例子来说明这些问题。

  • 在IE4.0中,MSHTML的HTMLDocument对象的IPersistStreamInit::Load假定传入的IStream流的访问指针已经定位到开头——而在IE5.0中,IPersistStreamInit::Load会自行调用IStream::Seek
  • 在Visual C++ 6.0中,CHTMLView类有字符串资源未释放问题(http://support.microsoft.com/kb/241750)
  • 在Visual C++.Net中,CHTMLView类有两个BUG:
    • 参数传递错误:
      HRESULT CHtmlView::ExecFormsCommand(DWORD dwCommandID, VARIANT* pVarIn, VARIANT* pVarOut) { HRESULT hr = E_FAIL; CComPtr spDoc = (IHTMLDocument2*) GetHtmlDocument(); if (spDoc != NULL) { CComQIPtr spCmdTarget = spDoc; if (spCmdTarget != NULL) hr = spCmdTarget->Exec(&CMDSETID_Forms3, dwCommandID, OLECMDEXECOPT_DONTPROMPTUSER, pVarOut, pVarIn); } return hr; }
      COM指针未释放错误:
      void CHtmlView::OnFilePrint() { // get the HTMLDocument if (m_pBrowserApp != NULL) { CComPtr spDisp = GetHtmlDocument(); if (spDisp != NULL) { // the control will handle all printing UI CComQIPtr spTarget = spDisp; if (spTarget != NULL) spTarget->Exec(NULL, OLECMDID_PRINT, 0, NULL, NULL); } } }

这些不确定的行为是很大一部分不可重复(因此也很难跟踪)的BUG的根源。举例来说,释放一块内存之后,在操作系统切换到另外一个线程之前,重新分配同一块内存,并且写入数据这个事件发生的可能性十分之小。为了解决这些问题,Visual C++编译器采取了一种保护性的措施,在调试模式下再分配和释放内存时将内存用一般不会用到的值填充,例如0xccccccc,0xdddddddd和0xfefefefe(参见编译器文档中的/RTC参数的说明)。这样你可以减少不可预料的程序行为,强迫BUG重现。如果你的编译器没有这么做,你可以自己编写一个调试模式下专用的内存管理程序进行这样的工作。为什么选择这样的值?在Intel系统中,0xcc的含义是int 3中断(参见http://blogs.msdn.com/oldnewthing/archive/2004/11/11/255800.aspx)——如果不小心执行了这块数据,那么程序会马上中断并且提示用户,其他的值则是典型的非法数据。如果你在为其他环境编写程序。你可能需要查阅一些资料来决定使用什么值来在调试模式下填充内存。

MFC的另一个保护措施是内存泄漏监测器——这也是在每个文件开头要加上#define new DEBUG_NEW的原因——但是这也变更了应用程序的行为。举例来说,为了检查内存泄漏,MFC总是分配比所需要多的内存,然后加入调试信息。如果你的程序有访问越界的代码,那么有可能擦除一部分额外分配的内存,可能的结果就是在调试模式下运行正常,而在发布模式下程序崩溃。当然,这是必须的。如果你的发布版本的程序依赖于这些额外字节,那么你就有麻烦了。

在发布模式下程序的崩溃有助于你发现问题,但是也造成定位问题的困难。你可以在发布模式下加入调试信息(没错,在工程的C++和连接选项中选中Program Database和Generate Debug Info)来生成一个中间版本;MSDN文章Generating and Deploying Debug Symbols with Microsoft Visual C++ 6.0(http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp)甚至教你怎么怎么发布这样的版本,但是也要注意这样的版本和最终发布版本还是可能有区别的——特别是在程序中有BUG的情况下。另一个办法是在调试时将EIP寄存器修改成崩溃信息中的值,这样可以很容易在源代码中定位造成崩溃的代码的位置(参见http://www.codeproject.com/debug/XCrashReportPt1.asp)。

MFC开发中另一个比较有用的定位内存访问越界方法是,将数据封装成对象成员变量,尽量可能让所有类都从CObject派生,并且在代码中大量加上ASSERT_VALID。如果成员变量被越界的访问重写了,那么CObject指向AssertValid的虚函数表会被改写,而ASSERT_VALID会报告这个错误。

不要发布调试版本,这对用户来说并无意义。虽然这么说可能是多此一举,但是我在玩游戏的时候还真看见过断言对话框。调试信息是被设计用来发现问题的,不是用来隐藏问题的。如果你确实需要这么做(微软就定期发布核心模块的调试信息以供软件开发人员定位问题),那么你需要让用户认识到调试版本和最终发布版本的性能差异,例如在程序开始时显示一个消息。

广告时间:

最新Windows SDK不支持Visual C++ 6.0

可能大部分人已经知道了,但是CSDN论坛上仍旧不断出现关于这个兼容性的提问。最新的支持Visual C++ 6.0的版本是2003年2月版,下载地址是http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm

取消对Visual C++ 6.0的支持的原因是为了支持新的/GS参数。XP SP2和Windows Server 2003 SP 1都增加了很多安全特性,以致于新的Windows SDK中包含的编译器和库文件不再和Visual C++ 6.0兼容。

参见

posted on 2006-02-05 17:48:00 by jiangsheng  评论(7) 阅读(13919)

集成桌面搜索,模拟器

微软的桌面搜索API推出也有一段时间了,但是网上可以找到的相关技术资料还不多。官方的资料在http://addins.msn.com/devguide.aspx可以看到,而且网页上有SDK和一个C#的示例供下载。
使用搜索API非常的简单,首先创建一个桌面搜索对象
BOOL CWDSSampleView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs
 if(m_pSearchDesktop.CreateInstance(CLSID_SearchDesktop))
 {
  AfxMessageBox(IDS_FAILED_TO_CREATE_SEARCH_ENGINE);
  return FALSE;
 }

……
之后就可以开始执行搜索了。桌面搜索对象有两个方法,ExecuteSQLQuery和ExecuteQuery,都返回一个ADO记录集对象。ExecuteQuery是对用户比较友好的版本,参数虽然比较多,但是不需要自己构建SQL;而ExecuteSQLQuery是底层版本,只有一个参数——需要自己构造的SQL。相信我,你不会渴望自己来创建SQL的。传递给ExecuteQuery的参数就已经够长的了。字符串表中IDS_COLUMNS_GENERAL的内容是:
DocTitle,DocFormat,Url,DocAuthor,PrimaryDate,FileName, FileExt,IsAttachment,Characterization,Rank,PerceivedType, HasAttach,DocTitlePrefix,FileExtDesc,DisplayFolder, DocKeywords,DocComments,ConversationID,Size, Create,Write。

void CWDSSampleView::Search(LPCTSTR lpszQuery,LPCTSTR lpszSort)
{
 CString strQuery(lpszQuery);if(strQuery.IsEmpty())return;
 CString strSort(lpszSort);
 USES_CONVERSION;
 HRESULT hr=S_OK;
 GetListCtrl().SetItemCount(0);
 ClearCache();
 try{
  CString strColumns;
  VERIFY(strColumns.LoadString(IDS_COLUMNS_GENERAL));
  if(strSort.IsEmpty())
   m_pRecordset=m_pSearchDesktop->ExecuteQuery(T2OLE(strQuery),
    T2OLE(strColumns),NULL,NULL);
  else
   m_pRecordset=m_pSearchDesktop->ExecuteQuery(T2OLE(strQuery),
    T2OLE(strColumns),T2OLE(strSort),NULL);
  int nItemCount=m_pRecordset->GetRecordCount();
  GetListCtrl().SetItemCount(nItemCount);
  
 }
 catch(_com_error&e)
 {
  ……
 }
}

Windows Desktop Search Example(VC/MFC)
但是,访问返回的记录集的速度比访问数据库要慢。我不得不用虚列表和缓存来提高性能。在搜索结果很多(例如关键字选择"Microsoft")时程序有假死现象——当然也不排除我选择的字段过多的原因。

最近在写一个14位CPU的模拟器,CPU指令长度是固定的——13字节,十分的不吉利^_^b,而且CPU指令集中一些特定指令会根据上下文判断是否跳过下一个指令。但是在Intel系统上没有这样的指令,而且指令长度是可变的,所以无法知道下一个指令的长度来跳过它。我现在是在内存中设置一个标志,在执行每个指令之前检查这个标志来判断前一个指令是否指明跳过当前指令——低效,但是可以正常工作。

现在我知道一些模拟器为什么慢得像乌龟爬了……

posted on 2005-07-19 01:58:00 by jiangsheng  评论(3) 阅读(4380)

在线地址本服务

 我收到的来自在线地址本服务的邀请现在越来越频繁了。今天我又收到了一封这样的邮件:
Add yourself to xxx's address book!
Open your invitation

This invitation was sent to my email address on behalf of xxxxxx (xxxxxx@hotmail.com)

If you do not wish to receive invitations from this Ringo member, click here. To stop receiving invitations from all Ringo members, click here.

在我的上一篇BLOG(Please don't show your password to 3rd party.)中,我提到了一些站点的服务存在风险,因为它们要求用户提供邮箱的密码,而这样可能导致身份冒用——实际上,他们已经用我朋友——其中一些名字我比较陌生,因为我不熟悉一些网友的真实姓名——的名义给我发送了数十封这样的电子邮件,而且看起来我将会持续收到这样的邮件,即使是在我注册之后。尽管一些网站声称我可以通过提供我的电子邮件地址来停止接收他们给我发送的邀请,但是这样的方法显然没有生效——和垃圾邮件中的停止接收链接一样,这仅仅证明这个电子邮箱正在被使用,并且准备好接收更多的垃圾邮件。记得蠕虫病毒么?这种收集邮件地址的方法更加简单,而且可以绕过任何防火墙。我建议收到这样的邮件的人在注册之前看看这篇文章:http://www.anu.edu.au/people/Roger.Clarke/DV/ContactPITs.html ,以了解可能付出的代价。

OK,在继续讨论之前,让我们来看看这些网站到底是什么。有多少人在注册之前看过他们的服务条款?要使用他们的服务,你必须同意他们的服务和隐私条款并且提供你的个人信息,例如生日、性别诸如此类。第一眼看上去这些服务条块似乎是完全无害的,除了:
http://www.bebo.com/Privacy.jsp

You agree that we may use personal information about you to improve our marketing and promotional efforts, to analyze site usage, improve our content and product offerings, and customize the Site's content, layout, and services. These uses improve the Site and better tailor it to meet your needs, so as to provide you with a smooth, efficient, safe and customized experience while using the Site.

We use your personal information to: troubleshoot problems; measure consumer interest in our services, inform you about offers, products, services, and updates; customize your experience; detect and protect us against error, fraud and other criminal activity; enforce our Terms of Use; and as otherwise described to you at the time of collection.

You agree that we may use your personal information to contact you and deliver information to you that, in some cases, are targeted to your interests, such as targeted banner advertisements, administrative notices, product offerings, and communications relevant to your use of the Site. By accepting the Terms of Use and Privacy Policy, you expressly agree to receive this information. You may make changes to your email notification preferences at any time.

It is possible that as we continue to develop our website and our business, Bebo's service and/or related assets might be acquired. Notwithstanding any provision in this policy to the contrary, in event of a merger or acquisition, your personal information may be transferred to the acquiring entity, and become subject to the acquirer's data practices.

http://www.bebo.com/TermsOfUse.jsp

Bebo reserves the right at all times to monitor, review, retain, and/or disclose in good faith any information it believes in good faith that such action or disclosure is necessary to conform to legal and government requirements, or to protect and defend the rights or property of Bebo or enforce the TOU.

Bebo reserves the right to collect and distribute non-personal demographic information to third parties. As such this information would not contain any information that would allow your identity to be deduced.

不够危险?来看看这个:(http://ringo.com/about/terms.html)

Modifications to Service

These Terms & Conditions were last modified on January 25, 2005. At any time and without prior notice, Ringo shall have the right, in its sole discretion, to modify, add or remove terms of these Terms & Conditions, without notifying our customers of such modifications, additions or removals, and all such changes shall be effective immediately. Your continued participation and use of this website and/or the Ringo services following our posting of any such change on our site will constitute binding acceptance of such change. You agree that Ringo shall not be liable to you or to any third party for any modification, suspension or discontinuance of the service.

OK,看过上面的文字,我也同意Ringo不liable,所以我不会去注册。因为这个网站的拥有者是Monster.com,我所知道的世界上最大的求职网站,所以从现在开始我不会理会任何类似的邀请,不管这样的邀请来自哪里。

我更加忧虑的是那些要求电子邮箱密码的服务,例如http://www.sms.ac, http://www.bebo.comhttp://www.hi5.com 之类。一些电子邮件服务和其他服务共享密码,例如MSN Money和Yahoo Messenger,而这样的电子邮件的密码被泄漏可能造成的损失不仅仅是发送垃圾邮件而已。很多人——包括我在内——在很多站点(甚至可能是银行的网站)使用同样的用户名和密码。但是,有多少人阅读过并且对法律条文有足够认识来理解它们的服务条款?有多少人知道很多这样的密码要求页面(在我发表这篇文章的时候,我没找到一个反例)完全没有加密措施?通过任何一个路由器——如果有人愿意的话,可以是在网站服务器所在网络上的那个——都可以获得这样的用户名和密码而不违反任何任何服务条款。更不用说这样的安全防护措施是否可以阻止黑客获取服务器上的数据了。

大多数人知道垃圾邮件和连锁信息(把这个信息发送给XX个人你就可以XXXX之类)是不受欢迎的。但是我还是不断收到一些这样的无用电子邮件、MSN和QQ消息——如果我还在使用手机的话,可能还有需要付费的文字消息——这大约占我的日常通讯量的2/3。再次提醒并不会阻止那些不听劝告的人发送这样的信息,但是我希望能够让一些没有被提醒过的人认识到,免费的蛋糕并不是看起来那么美味可口。我也建议你在阅读之后,做一些你自己的搜索和研究来做出你自己的判断。

posted on 2005-05-13 12:20:00 by jiangsheng  评论(5) 阅读(3364)

Please don't show your password to 3rd party.

请勿向第三方公开你的个人密码
Please don't show your password to 3rd party.

一直以来我都持续收到一些加入在线手机社区http://www.sms.ac的邀请,因为我没有手机(要找我的人注意:我醒着的话一般都挂在MSN上),所以总是看过就算。但是今天收到了来自一个不是很熟的朋友的加入这个社区和另外一个社区http://www.bebo.com的邀请,所以上网搜索了一下一些个人BLOG对这两个网站的引用。搜索的结果触目惊心。
这些网站显然都要求用户输入邮箱和邮箱的密码,同时使用邮箱中保存的联系人信息来邀请用户的联系人加入。但是,向第三方公开你的密码意味着公开你的全部邮件、联系人的家庭地址、电话等信息。这可能不是你的朋友愿意看到的情形。

密码是私有的,并且从不应该向第三方公开。任何在注册时要求现存密码的服务都是可疑的,特别在询问你的邮箱密码而没有警告用户这样可能造成的危险的情况下。如果某个网站询问你的hotmail账户和密码,那么几乎可以肯定这是个没有和微软合作的网站,因为真正和微软合作的商业网站应该会使用.Net Passport来和微软共享用户注册信息,例如http://www.match.com

如果你收到了注册某个网站的邀请,首先搜索因特网上对这个网站的引用以确定是否值得向这个网站公开你的个人信息。如果有必要,你可以新建一个电子邮件和密码组合来参与在线社区。


参考
http://hownow.brownpau.com/archives/2005/02/spam_from_smsac
http://www.jaffacake.net/BensBlog.nsf/dx/bebo.com---update

顺便说一下,微软发布了Windows XP和Windows 2003的64位版本(Microsoft Windows XP Professional x64 Edition )Windows Server 2003 x64 Editions。

posted on 2005-04-25 18:22:00 by jiangsheng  评论(5) 阅读(3576)

十年MFC经历认识的Microsoft技术[转]

在CSDN技术社区(http://community.csdn.net)看见一个sunhui (MFC.NET) 的感想(http://community.csdn.net/expert/Topicview1.asp?id=3834281),虽然是关于MFC的讨论,但是对其他语言的开发者也有借鉴之处。

一些感想

>Microsoft内部.NET就是“COM 3.0”(OLE2就是COM 2.0)

OLE是COM的一个应用,似乎不应该称为一个升级。Net更像COM 2.0——如果硬要给COM找一个2.0版出来的话。不同的是除了跨语言的合作能力之外,.Net还有源代码级别的控制,例如跨语言的类继承,虽然这对于软件开发并无多少改善。

用插件的确很方便——但是COM太灵活了,使得实现插件的方法五花八门。集成VBA或者VBS解释器是我比较喜欢的方法,因为不用重新编译(这意味着重新制作安装程序)就可以自定义程序。如果集成浏览器控件来做界面显示的话,这一步甚至可以省略。

?

顺便说一句,Visual Studio 2002 的第一个补丁SP1已经发布。用户可以在Visual Studio主页(http://msdn.microsoft.com/vstudio),或者MSDN订阅者下载站点(http://msdn.microsoft.com/subscriptions/)下载。

posted on 2005-03-11 04:06:00 by jiangsheng  评论(18) 阅读(4831)

GOOGLE Local Beta

在Google上搜索时候突然发现Google提供了当地搜索。用关键字“microsoft seattle“搜索时,第一项结果是

Seattle, WA周边使用microsoft进行搜索所得到的当地结果

Microsoft - 0.4 英里 西南 - 114 Alaskan Way S - (206) 405-2051
Microsoft Alumni Network - 0.3 英里 西南 - 719 2nd Ave - (206) 438-1850
Microsoft - 6.5 英里 东 - 11245 Se 6th St, Bellevue - (425) 635-3078

Google当地搜索Beta版的主页是(http://www.google.com/lochp)。看起来这似乎是收购Keyhole之后的一个成果。

目前地图搜索服务的范围和内容基本和http://maps.yahoo.com一样,也只包含美国和加拿大的数据,但是用户可以通过搜索Google来找到地址,而Yahoo Map需要手动输入地址。P.S. 找半天没找到盖茨家门牌号……干扰项太多了……

中国大城市用户可以尝试Sohu和Go2Map合作开发的城市电子地图查询(http://map.life.sohu.com/client/life/search.asp

posted on 2004-12-02 04:34:00 by jiangsheng  评论(3) 阅读(2483)

微软真的注意一些小节啊

安装了Windows XP SP2之后的新发现……里面的纸牌游戏(没错,就是Windows里面那个古董游戏)这次居然也更新了……增加了一些漂亮的背景图片。

我会注意到这个是因为安装SP2时磁盘空间不足……把游戏、QQ、MSN、Yahoo! Messenger、ACDSee、WinRAR等常用软件全部删除,清空了IE的缓存才腾出来所需空间……

posted on 2004-10-30 05:19:00 by jiangsheng  评论(10) 阅读(6937)

XPSP2的安装需求

今天终于把DSL装上了,可以把MODEM扔掉了(有没有人买二手MODEM?)然后开始更新计算机,但是在偶的本本上装XPSP2的时候出现这个错误信息

---------------------------
Service Pack 2 安装程序错误
---------------------------
此 Service Pack 要求计算机使用交流电源才能开始安装程序。
---------------------------
确定??
---------------------------


想破了头也想不出来微软为什么要加这个限制。难道XPSP2的安装要好几个小时?

posted on 2004-10-28 13:12:00 by jiangsheng  评论(11) 阅读(4254)

transitions

IE4以上版本的浏览器支持滤镜(filters)和过渡(transitions)。昨天去酒吧街的时候在广告牌上看到一个效果不错,回来想了想,是可以用切割和随机分解过渡做出来的。为了偷懒起见,filter用了IE5的语法,图片暂时用文字代替,原来的双向拉开式效果改成单向,兼容性么……偶又不是搞Web开发的,暂时无视^_^。这个只是一个自娱自乐的东西,不考虑兼容性:p(抗议无效,投诉无用,谁扔的臭鸡蛋?)

要看效果的去这里:http://cn.geocities.com/sheng_jiang/Programming/Transitions.htm

点“点击这里查看效果,要重复看的自己按F5刷新。 by 懒人”那一行看效果

有人抱怨访问不到,所以把代码贴在这里

文档没有的干活,要了解原理的请自行查看源代码,有语句看不懂的自己去翻MSDN,懒人去睡觉了(今天是Labor Day,似乎是米国的劳动节^_^。在这种节日早上十一点睡觉似乎要遭天谴的……但是考虑到劳动节银行商店图书馆议会垃圾站统统关门,还是在家里睡觉比较好……希望醒的时候还没有被番茄和鸡蛋淹没……这似乎是偶很喜欢吃的一道菜,淹死就淹死吧……以上……呼呼噜……呼噜……)

喂喂喂!大家不要生气,生气会犯了嗔戒的。Yahoo你也太调皮了,我跟你说过叫你不要在我的网页后面乱扔东西,你怎么又……” “你看 我还没说完你又把script给扔掉了。script是代码,你把它扔掉会搞乱网页,要是造成脚本错误怎么办?就算没造成脚本错误,使得页面加载缓慢也是不对的!”

posted on 2004-09-07 01:14:00 by jiangsheng  评论(6) 阅读(2040)

【第1页/共5页,48条】
首页
前页
1

Powered by: Joycode.MVC引擎 0.5.2.0