ZT文萃

本博不原创,转帖自己感兴趣那些事人物,什么入眼贴什么,随心所欲。
posts - 93, comments - 5, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2014年3月28日

移动互联网,就是将移动通信和互联网二者结合起来,成为一体。
4G时代的开启以及移动终端设备的凸显必将为移动互联网的发展注入巨大的能量,2014年移动互联网产业必将带来前所未有的飞跃。

度娘百科详解:http://baike.baidu.com/view/1168245.htm

 


云计算(英语:Cloud Computing),是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息可以按需求提供给计算机和其他设备。

云 计算是继1980年代大型计算机到客户端-服务器的大转变之后的又一种巨变。用户不再需要了解“云”中基础设施的细节,不必具有相应的专业知识,也无需直 接进行控制。[1]云计算描述了一种基于互联网的新的IT服务增加、使用和交付模式,通常涉及通过互联网来提供动态易扩展而且经常是虚拟化的资源。

度娘百科详解:http://baike.baidu.com/view/1316082.htm?fr=aladdin
 


大 数据(英语:Big data),或称巨量数据、海量数据、大数据,指的是所涉及的数据量规模巨大到无法通过人工,在合理时间内达到截取、管理、处理、并整理成为人类所能解读 的信息。在总数据量相同的情况下,与个别分析独立的小型数据集(data set)相比,将各个小型数据集合并后进行分析可得出许多额外的信息和数据关系性,可用来察觉商业趋势、判定研究质量、避免疾病扩散、打击犯罪或测定实时 交通路况等;这样的用途正是大型数据集盛行的原因。

度娘百科详解:http://baike.baidu.com/subview/6954399/13647476.htm?fr=aladdin

 


O2O(Online To Offline)模式,又称离线商务模式,是指线上营销线上购买带动线下经营和线下消费。O2O通过促销、打折、提供信息、服务预订等方式,把线下商店的 消息推送给互联网用户,从而将他们转换为自己的线下客户,这就特别适合必须到店消费的商品和服务,比如餐饮、健身、电影和演出、美容美发、摄影及百货商店 等。

度娘百科详解:http://baike.baidu.com/subview/4717113/13607799.htm?fr=aladdin

一些O2O案列:Groupon、OpenTable、易到用车

posted @ 2014-11-05 23:07 ZT文萃 阅读(1343) | 评论 (0)编辑 收藏

乱讲,谁说我们2002年倒数第一的啊

不还有沙特了么

再说了,中国队多牛B洋人不知道吗

在长达84年十九届世界杯的历史上
仅有三支国家队战胜过中国国家队
分别是巴西、土耳其、哥斯达黎加

即使是巴西这样的世界强队也仅战胜过中国队一次。

而中国队从未在世界杯点球大战中失利过,
从来没有一支球队能够在世界杯上击败过中国队两次。

从数据分析中可以看的出,世界杯史上共产生八支冠军球队,
也只有巴西队曾经战胜过中国队。
欧洲诸强德西荷法英意葡等从来没有世界杯上战胜过中国。

而且,中国队在世界杯上丢球数远少于足球之国巴西和以防守见长的意大利,
在过去84年里,中国队只丢了9个球。

除此之外,世界上除了巴西,中国是另外一支敢在胸前绣五颗星的队。

posted @ 2014-06-16 21:36 ZT文萃 阅读(231) | 评论 (0)编辑 收藏

释迦牟尼在《佛譬喻经》中,讲了一段有名的譬喻,这譬喻是这样的:
      在一个寂寞的秋天黄昏,无尽广阔的荒野中,有一位旅人赶着路。突然,旅人发现薄暗的野道中,散落着一块块白白的东西,仔细一看,原来是人的白骨。
      旅人正疑惑思考时,忽然从前方传来惊人的咆哮声,随着一只大老虎紧逼而来。看到这只老虎,旅人顿时了解白骨的原因,立刻向来时的道路拔腿逃跑。
      但显然是迷失了道路,旅人竟跑到一座断崖绝壁的顶上。在毫无办法之中,幸好发现断崖上有一颗松树,并且从树枝上垂下一条藤蔓。旅人便毫不犹豫,马上抓着藤蔓垂下去,可谓九死一生。
      老虎眼看好不容易即将入口的食物,居然被逃离,可以想象它是如何懊恼地在崖上狂吼着。
      好感谢啊!幸亏有这藤蔓,终于救了宝贵一命。旅人暂时安心了。但是当他朝脚下一看时,不禁啊了一声,原来脚下竟是波涛汹涌、底不可测的深海,怒浪澎湃着,而且在那波涛间还有三条毒龙,正张开大口等待着他的坠落。旅人不知不觉全身战栗起来。
      但更恐怖的是,依靠救生的藤蔓,在其根接处出现了两只白色和黑色的老鼠,正在交互地啃着藤蔓。旅人拼命摇动藤蔓,想赶走老鼠,可是老鼠一点也没有逃开的样 子。而且每次摇动藤蔓,便有水滴从上面落下来,这是树枝上蜂巢所滴下的蜂蜜。由于蜂蜜太甜了,旅人竟完全忘记自己正处于危险万分的境地,此心陶陶然地被蜂 蜜所夺。
      这愚痴的旅人之相,便是所有人类的人生之真相。那么释迦穆尼这段譬喻意味着什么呢?

1、孤独的心灵
旅人:这旅人是指我们自己。
荒野:无尽而寂寞的荒野是譬喻我们无尽寂寞的人生。
秋天的黄昏:秋天的黄昏是譬喻人生的孤寂感。
白骨:路边的白骨是指我们人生旅途中,家族、亲属、朋友等的死亡。我们活到现在,应该看到很多白骨,那时我们有何想法?有何感触?我们可曾注意到紧逼而来的“无常之虎”?
老虎:饥饿的老虎所譬喻的,既是我们自己的死亡。

2、无力的松树
松树:接着我们攀上崖顶的松树,松树是指金钱、财产、名誉、地位等等。这些东西即使拥有再多,在死亡的面前也仍是无力的。

3、人生是梦
藤蔓:藤蔓所譬喻的是“还不会!还不会!我还不会死”的那种以为还有二十年、三十年的寿命可依恃,但即使认为还有十年、还有二十年可活着,但你认为到底人 寿几何?想想便知:已过去的十年二十年,也不过是《啊》的一声之间,便如梦如幻般地消逝了。而今后的十年二十年,也同样是《啊》的一声之间便会过去。
老鼠:咬着藤蔓的白老鼠和黑老鼠是指白天和晚上。白天的白老鼠和晚上的黑老鼠,在相互地缩短着我们的寿命。

4,后生大事
深海:深海所譬喻的便是地狱。坠入此地狱,必须承受八万劫中大苦恼,这一件事情便称为——后生一大事。
毒龙:显现地狱之苦的是这三条毒龙,这三条毒龙指我们自己内心的贪欲、嗔怒、愚痴。
      “善因善果、恶因恶果、自因自果”的因果法则是不会有丝毫差错的。由自己所不断造作的罪恶所生出的地狱,最后还是由自己坠入。

posted @ 2014-06-13 15:44 ZT文萃 阅读(194) | 评论 (0)编辑 收藏

其实都是些很简单的东西
如果有CLER认为这些东西发出来没必要那  朕只能说抱歉

如果看了帖子 对进有那么一点帮助 请cler 回帖支持下 让更多的 朋友可以了解下,很多问题,可以从开机看出问题
谢谢

为 使用电脑时间比较长的老用户,难免会到朋友或同事家帮忙维护、维修电脑,有时还要帮人购买PC,这时我们肯定会带上硬件检测软件,不过,谁也不能随身总是 带着这些软件,如果手头上没有合适的检测软件该怎么办呢?总不能因此就什么都不知道吧?那样你的高手形象大大会受损的,其实,离开这些软件我们也能明明白 白查看电脑硬件的配置情况。下面我们就来一起学习一下吧。  

  一、开机自检中查看硬件配置  

  机器组装结束后即使不装操作系统也可以进行加电测试,在开机自检的画面中就隐藏着硬件配置的简单介绍哟(由于开机画面一闪而过,要想看清楚的话,记得及时伸手按住“PAUSE”键)。

  1.显卡信息  

   开机自检时首先检查的硬件就是显卡,因此启动机器以后在屏幕左上角出现的几行文字就是有显卡的“个人资料”介绍。四行文字中,第一行“GeForce4 MX440……”标明了显卡的显示核心为GeForce4 MX440、支持AGP 8X技术;第二行“Version……”标明了显卡BIOS的版本,我们可以通过更新显卡BIOS版本“榨取”显卡性能,当然更新后这一行文字也会随之发 生变化;第三行“Copyright (C)……”则为厂商的版权信息,标示了显示芯片制造厂商及厂商版权年限;第四行“64.0MB RAM”则标明了显卡显存容量。  

  2.CPU及硬盘、内存、光驱信息  

  显示完显卡的基本信息之后,紧接着出 现的第二个自检画面则显示了更多的硬件信息,像CPU型号、频率、内存容量、硬盘及光驱信息等都会出现在此画面中。该画面最上面两行文字标示了主板 BIOS版本及BIOS制造商的版权信息;紧接着的文字一看就明白啦,当然是主板芯片组喽;其下几行文字则标明了CPU的频率及内存容量、速度。下面四行 “IDE……”则标明了连接在IDE主从接口上的设备,包括硬盘型号及光驱型号等等。
  
  3.主板信息 

  在第二 个自检画面的最下方还会出现一行关于主板的信息,前面的日期显示的是当前主板的BIOS更新日期,后面的符号则是该主板所采用的代码,根据代码我们可以了 解主板的芯片组型号和生产厂商。以往老主板的自检画面中最下方文字的中间标明的是主板芯片组,这一块板子则将其提到了自检画面的上方。  

  机器启动之后按“DEL”键进入BIOS设置页面,在基本信息中同样也可以看到机器的硬件信息,与开机画面显示的没有区别。

  二、利用设备管理器查看硬件配置  

   进入操作系统之后,在安装硬件驱动程序的情况下还可以利用设备管理器与DirectX诊断工具来查看硬件配置。下面看看如何利用设备管理器查看硬件信 息。进入桌面,鼠标右击“我的电脑”图标,在出现的菜单中选择“属性”,打开“系统属性”窗口,点击“硬件--设备管理器”,在“设备管理器”中显示了机 器配置的所有硬件设备。从上往下依次排列着光驱、磁盘控制器芯片、CPU、磁盘驱动器、显示器、键盘、声音及视频等信息,最下方则为显示卡。想要了解哪一 种硬件的信息,只要点击其前方的“+”将其下方的内容展开即可。  
  利用设备管理器除了可以看到常规硬件信息之外,还可以进一步了解主板芯片、声卡及硬盘工作模式等情况。例如想要查看硬盘的工作模式,只要双击相应的IDE通道即可弹出属性窗口,在属性窗口中可轻检看到硬盘的设备类型及传送模式。这些都是开机画面所不能提供的。  

  需要注意的是在Windows Xp之前的操作系统中所提供的设备管理器是无法用来查看CPU工作频率的,好在我们还有DirectX诊断工具。  

   三、利用DirectX诊断工具查看硬件配置  

   DirectX诊断工具可以帮助我们对硬件工作情况作出测试、诊断并进行修改,当然我们也可以利用它来查看机器的硬件配置。运行“系统信息”窗口,找到 “工具--DirectX诊断工具”(或者进入安装盘符中Windows目录下的System32目录中运行Dxdiag.exe),在窗口中可以方便地 查看硬件信息。

  1.查看基本信息  

  在“DirectX诊断工具”窗口中点击“系统”选项卡,当前日期、计算机 名称、操作系统、系统制造商及BIOS版本、CPU处理器频率及及内存容量一目了然。注意喽,虽然我将Celeron 2.0MHz超频至2.40MHz使用,但是DirectX却不认这个帐,依然显示的是未超频的原始频率。看来没有AIDA32,我们同样也可以识别奸商 是否将超频的CPU卖给我们!!  

  2.查看显卡信息  

  在“DirectX诊断工具”窗口中点击“显示”选项卡,在这里我们可以看到显卡的制造商、显示芯片类型、显存容量、显卡驱动版本、监视器等常规信息。  

  3.查看音频信息  

  音频设备往往为人所忽视,但缺了它又不行,单击“声音”选项卡,对其做一番了解吧!同样在出现的窗口中能看到设备的名称、制造商及其驱动程序等等极为详细的资料。不同的是我们还可以点击右下角的“测试DirectSound(T)”对声卡进行一下简单的测试。  
怎么样,经过这一番了解,是不是感觉很受益?

题外话,由于主板更新频繁,现在很多主板BIOS有快速启动功能,以上很多信息都被瞬间屏蔽掉了。需要看自检的信息,需要到BIOS设置。但是以上讲的信息,能让你明白,计算机如何自检。

posted @ 2014-06-10 22:57 ZT文萃 阅读(215) | 评论 (0)编辑 收藏

http://kb.cnblogs.com/page/192251/

这些日子我一直在写一个实时操作系统内核,已有小成了,等写完我会全部公开,希望能够为国内IT的发展尽自己一份微薄的力量。最近看到很多学生朋友和我当年一样没有方向 ,所以把我的经历写出来与大家共勉,希望能给刚如行的朋友们一点点帮助。

  一转眼我在IT行业学习工作已经七年多了,这期间我做过网页,写过MIS、数据库,应用程序,做过通信软件、硬件驱动、协议栈,到现在做操作系统内核和IC相关开发,这中间走了很多弯路,也吃了不少苦。

  我上的是一个三流的高校,就连同一个城市的人多数都不知道。因为学校不好也就没有指望能靠学校名气找一个好工作。所有的希望都寄托在自己的努力 上了,大一开学前的假期我就开始了学习。记得我买的第一本书是《计算机基础DOS3.0》,大家别吓着了,其实当时已经普及了DOS6.22了,只是我在 书店里看到了DOS4.0/5.0/6.0的书,以为像英语那样是第四、五、六册,记得当时到处找DOS1.0,现在想想也幸好我没有找到:)。开学前我 学完了PASCAL,那时既没有计算机也没有人可以请教,我连程序是什么的概念都没有,只好死记硬背代码,然后拿纸写。我一直到大三才有了一台486,在 这之前用纸写了多少程序我也记不清楚了,只知道最长的一个我拿A4大小的草稿纸写了30多页,我的C语言、C++ 、VC都是在这样的条件下入门的。

  所以说条件是可以克服的,希望我的经历多少给条件艰苦的同学们一点信心。第一次上机是在我姐夫的机房,我的心情激动的无与伦比,但是一上机我立 刻傻了眼,他们用的是英文版的Win3.1,我的那点DOS知识都见了鬼,上机提心吊胆的一阵瞎摸,一不小心把Word弄成了全屏,怎么都还不了原,当时 真是心急如焚,我以机器被我弄坏了。第一个C语言程序,就是那个经典的HelloWorld,我调了几个星期,上机机会非常少,也没有书告诉我开发环境 (TC2.0)需要设置,而且开始我都不知道有编译器,我甚至自作聪明把写好的程序扩展名从.c改成.exe,结果可想而知。

  大一学完了C、X86的汇编、数据结构、C++ 。由于精力都花在自学上了,大一下四门课挂了彩,三类学校就是这点好,挂上一二十门也照样毕业。不过扯远点说,我那么刻苦都及不了格,可见我们国家的计算机教育有多死板。

  大二准备学VC和BC,当时难以取舍,后来选了VC,不为别的,只为书店里两本书,VC那本便宜6块钱。我的努力在班上无人能及,学的日夜不 分,大三有了计算机后更是如此,很多次父亲半夜教训我说我不要命了,我一直觉得自己基础差,记忆又不行,条件也不好 ,所以觉得只有多花点时间才能赶上别人。居然后来有许多朋友说我有学计算机的天赋,让我哭笑不得。我用的是486,16M内存,1G硬盘,当时同学们的配 置都是P166MMX,我安装一个Windows NT4.0需要一个通宵,编译一个BC5.0向导生成的程序需要近两个小时,我的显示器是个二手的,辐射非常大,开机屏幕冒火花,看起来很酷的:)。有一 次程序写的太久,觉得怎么白色的编辑器背景变成了紫色,以为显示器坏了,后来才发现眼睛不行了,不过说来也奇怪,到今天我的视力还能保持1.5,真是个奇 迹。但是就是那台破机器陪伴我两年,让我学会了VC、Delphi、SQL Server等。后来那台机器给我阿姨打字用,据她说一天她正打的开心,一股青烟夹着火苗从显示器钻出来,之后它才寿终正寝。

  大三假期找了个机会在一个计算机研究所实习,与其说实习不如说是做义工,工作了两个月一分钱没有拿。但是这两个月对我的发展帮助很大,让我早一 步了解了社会,刚去的时候我当然是一窍不通,在那里我熟悉了网络,学会了Delphi和Oracle。由于工作很认真,得到了比较好的评价,在一位长者的 引荐下,我开始和他们一起做项目,这使我在大三大四就有了自己的收入,大四又找了两家MIS公司兼职,虽然钱不多,但是在学生期间有1000多的收入我已 经非常满足了,我终于用自己赚的钱把计算机换了。

  大四下开始找工作,这时我的工作经验已经比较多(当然现在想想非常幼稚),开始听父母的想去那个研究所,实习过那个部门也希望我能去,但是不知 道为什么最后不了了之,这种单位就是比较官僚,我一气之下就到了我兼职的一个公司做MIS的Team Leader。在大三到毕业一年的时间,做过了各种MIS,从煤气、烟厂、公安、铁路、饮食到高校,什么有钱做什么,工作也很辛苦,经常加班和熬通宵,从 跟客户谈需求到设计、编码、测试、交付都要上。那时觉得很有成就感,觉得自己还不错,现在想想真是很肤浅。

  刚走上工作岗位的学生很容易被误导,各种开发工具让人眼花缭乱,同时也觉得很受公司器重,但这样工作永远是一个低层次的开发者。不要跟我说什么 系统分析有多么多么重要,多么多么难。你以为自己跟用户谈需求做设计就是系统分析和设计了吗,国内又有几个公司能够做的很到位很规范?我是ISO9000 内审员,也在Rational公司受过多次培训,拿了4个证书,还有一个公司让我去做CMM。这些我听过很多,但是很多事情到内就变了性质,一个公司不是 通过了ISO9000或者CMM就能规范了,我现在在一家有几十年历史的外企工作,里面的管理不是一般国内企业能及的。作为一个毕业不久以前没有步入过社 会的学生,几乎不可能在很短的时间掌握系统分析和设计,面向对象、UML只是一个工具,关键是人本身的思想,不是说你熟悉了C++ 、Rose就能够做出好的设计,相反如果你具备了很高的素质,你可以用C写出比别人用C++更加模块化的程序。

  话说远一些,国内软件开发行业有一个怪圈,很多人觉得VC > Delphi > VB,真是很搞笑。这几个软件我都做过开发,说白了他们都是工具,应该根据应用的需要选择采用哪个,而不是觉得哪个上层次。如果你因为用某个开发工具很有 面子而选择的话,只能说明你很浅薄。如果说层次,那么这些工具都不上层次,因为它们用来用去都是一些系统的API,微软的朋友不会因为你记住他们多少个 API或者多少个类就会觉得你很了不起,你永远只是他们的客户,他们看重的是你口袋里的银子。我也做过系统内核,我也封装过很多API,同样我也不会看重 那些使用这些API做二次开发的客户,除非他能够作出自己独到的设计。

  至于有人认为C++ > C那更是让人笑掉大牙,不妨你去打听一下,现在有几个操作系统内核是用C++写的,又有几个实时系统用的是C++,当然我也不是说C++不好,但是目前的 内核和实时系统中C++还无法与C匹敌,至于说C++适合做应用系统的开发那是另外一回事。所以我的观点是不在于你用什么工具和语言,而在于你干什么工 作。你的设计体现了你的技术层次。

  这样干了一年我觉得非常苦闷,做的大多数都是熟练工种的活,个人技术上没有太多的提高也看不到方向。所以决定离开这个城市去上海,寻求更好的发展,并且打算放弃我以前的MIS转到通信行业。

  写到这里不能不提到我女朋友,我们是在来上海前半年认识的,她大四在我公司实习,公司派她给我写文档,我们的感情发展的很快。她告诉我很多事 情,她家原本是改革开放的第一批暴发户,她母亲爱打牌,输掉了几百万,还欠了很多债,她有男朋友,但是她对他没有感情,只因为他给了她母亲两万多块钱,后 来还强迫她写了四万块的借条,她男朋友背叛过她并且不止一次打她,现在逼她结婚,不然就要她还钱。这人居然还是一个高校的老师!她母亲把父亲给她的学费花 了,因为拖欠学费她没有办法拿到毕业证。

  她母亲现在有病需要钱,我拿出了自己的一点积蓄并且跟朋友们借了一些,替她交了学费并给她母亲看病(后来才知道看病的钱又不知所终,就连她母亲 是不是有病我都不知道,但她也是没有办法)。这个时候我家知道了一些事情,坚决反对我和她在一起,她原来的男朋友也极力破坏。无奈之下我们决定早一定离开 这个伤心的城市,并且瞒着我们家。由于时间仓促,我只准备了4000块钱,她仅有的几百块钱也被她母亲要去了,我买了三张票,一张是中午的,两张是晚上 的,中午我的家人把我送上船,他们一离开我就下了船,我和她乘坐晚上的船离开了这个我和她生活了很多年的城市,带走的只是一身债务。

  没有来过上海的我们两个性倔强,都不愿意去麻烦同学和朋友。来到上海是傍晚6点半,我们都不知道该去哪里,我们找了一个20块钱的旅馆,这个房 间连窗户都没有,7月份的天气酷热难耐,房间里非常闷热。第二天我们开始租房子,因为身上的钱不多,我们基本都是步行,花了一个星期时间,不知道在浦东转 了多少圈后找到了一个400块的房子,但是我们都 不了解上海是付三压一,还要付半个月的中介费,买了一些锅碗瓢盆后,我们身上只有800块钱了。工作都还没有着落,这800块钱要支持到我们拿到第一个月 工资,为了省钱我们自己做饭,每天买菜只花两块钱,她非常喜欢吃(也可能她在大学经常挨饿的原因),看到她现在这样省吃俭用我真的很不忍心。

  她以前的男朋友也没有放过她,经常打电话来骚扰,并且来上海看她,还说了不少恐吓她的话,她过于善良,说他以前毕竟帮助过她,叫我不要与他一般 见识。以后的每天在家就是苦等面试通知,原本我想迅速找一家MIS公司解决眼前的困难,但是她坚持让我不要放弃自己的理想,终于功夫不负有心人,我找到了 一家通信公司,4000块的工资虽然赶不上MIS公司给我开出的价位,但也够在上海生存。她也找到了工作,第一天上班她哭了,这是她来上海第一次流泪,我 心里很难受也很感动。

  由于是全新的行业,我把自己降到了零点,我学的VC、Delphi、数据库派不上用场,摆在我面前的是嵌入式、协议、信令一些我从未接触过的知 识。我知道我没有退路,于是拼命的学习,我把自己当做一个应届毕业生一样,一分努力一分收获,半年过去我终于熟悉了工作,并且得到了公司的表彰,薪水也加 了一级。后面的日子里我们省吃俭用,把欠朋友的1万多块钱还了,日子终于上了正轨。这时女朋友告诉我她想考研究生,我也很支持,于是她辞职在家备考。

  另外,在这里我要感谢我的Project Manager,他原来是一个大通信公司的产品经理,对人非常和善,我从他那里学到了很多知识,而且他也给了我许许多多无私的帮助。在工作上他给我充分的 空间和信任。记得公司安排我维护一个接入服务器软件,由于代码量不算太小(5万行),资料和文档都不齐全,我维护起来非常吃力,所以想重新把它做一遍,公 司领导不太支持,可能觉得工作量太大,但是他极力支持我,私下里他让我放手去做,我的维护工作他挤时间做。在他的支持下,我花了半年时间完成了接入服务器 的软件,并且实现了一个相对完整的TCP/IP协议栈。在这里我学会了嵌入式系统设计、驱动开发、TCP/IP和很多通信的知识,我花了一年时间终于使自 己从MIS开发转到了通信行业,并且站稳了脚跟。我的开发大量是对硬件的直接操作,不再受微软的操作系统,VC、Delhpi这些开发工具的约束,我终于 看到了另外一片天空。

  我做事情喜欢追根问底,随着开发的深入,软件开发与硬件联系越来越紧密,硬件知识的匮乏又对我的发展产生了障碍,而且芯片技术基本上掌握在国外 公司的手里,这对做系统级设计是一个非常大的制约,一个新产品出来,第一道利润(也往往是最丰厚的利润)常常都被IC公司如Intel、Motorola 赚去了,国内的厂商只能喝点汤。所以我决心解决自己的硬件技术障碍,并打算离开通信行业,进入IC设计相关领域。

  当然我明白如果我对硬件了解的非常少,没有哪家IC公司会仁慈到招我这样一个一窍不通的人来培训。所以我必须努力打好基础,学一些相关知识为以 后做准备。就像我开始从MIS转到通信一样,我看过大量通信方面的书,并且给一个ISP做过RADIUS计费分拣台,在这样的背景下这家通信公司才给了我 这个机会。我在的通信公司是做系统设计的,有不少PCB  Layout硬件人员,平常我就注意向他们学习,由于我做的是软件,在公司看硬件资料不好意思,所以开始只好在家看,刚来上海工作我连续一年都在加班, 后来不加了,因为我要挤出时间学习,通常我12点左右睡,第二天5点半起,我上班比较早,地铁上如果人不多,我也用来看书。

  学习当然不会是一帆风顺的,有些实在不懂的问题就积累起来问硬件人员,他们的帮助使我学习进度快了很多。因为在没有人点拨的情况下自学,我的一 半时间是花在解决疑难问题上,但这种问题经常是别人的一句话就可以让我豁然开朗,我非常庆幸我有这样的学习环境。在后面的一年里,我学会了看硬件原理图, 学会了简单的硬件设计 (模拟电路方面还有不小的差距),事情就是这样的,当你安安份份做软件,别人永远认为你是软件开发人员,在你开始学习硬件时别人未必会认同,有位中兴通讯 的朋友还对我说过,一个人不可能把所有东西都学完。

  我也明白这一点,但我希望自己做的更好。但当你熟悉硬件后大家又会觉得你好像原本就是软硬件都懂的,同事们也都习以为常了。这个时候我可以把硬 件资料堂堂正正的拿到公司看,没有人再大惊小怪了。让我比较自豪的是我通过自己的努力做了一个IAD(软交换的终端设备)系统方案,包含软硬件的选型、设 计等内容,这个方案得到了公司和同事们的认同,让我感到非常欣慰。

  技术是相辅相成的,当我的硬件有了一定的进步后,我的软件设计也有了很大的提高 ,我可以从更深层次理解问题。我做的接入服务器CPU是Motorola PowerPC 860,熟悉的朋 友都知道860 QMC与软件的批量数据传输通常采用BD表的方式,硬件人员做驱动的时候习惯采用固定BD表,每接收或发送数据都将数据从BD表拷贝到用户Buffer, 或从用户Buffer拷 贝到BD表。由于理解的比较深入,我自己重新实现了这个过程,采用动态BD表的方式,驱动从一个网口接收数据,提交给我的软件进行三层交换,直至从另外的 接口发送出去,没有进行一次拷贝。这样的设计大大提高了性能,使系统的指标接近理论值。

  软硬件的结合使我的设计水平上了一个台阶。我现在写的这个操作系统,编译后我把程序反编译成汇编,找出其中不优化的代码,然后在C程序中进行调 整。举个例子,很多CPU没有专门的乘法指令,这个大家应该都知道,在这种CPU上进行一个乘法操作常常会花费大量的指令周期,有的朋友会说这个我知道。 我会尽量避免采用×号,但是事情往往不是那么简单,你知道C语言中数组的下标操作是怎么实现的吗?仔细看看反汇编的代码你就会明白,同样是通过下标的定位 操作,C编译器会有时候会产生位移指令,但有时候会用乘法实现,两者效率往往是天壤之别,所以明白这些问题你才能将系统性能提升到极致。这些问题就不多说 了,有兴趣的话以后可以共同探讨。

  话说远一点,我由衷的希望在软件上做的比较深入的朋友们有机会学学硬件以及其它相关知识,尤其是做底层开发和嵌入式设计的。这对软件技术的提高 有非常大的帮助,否则很多事情你只知道该这样但不会明白为什么该这样。我这个观点在我现在的IC公司Project Manager那里也得到了验证。他告诉我们公司现在802.11芯片产品的软件经理原本是做该芯片硬件设计的,某某某原本是做软件的,现在在做IC,类 似的例子还有很多,只是在国内这样的风气不是非常流行。

  我有一些心得体会与大家分享,只有当我干好本职工作后,我才会学习与工作关系不大的技术,这样公司的上司才不至于反感。在入门 阶段的问题我通常不去问那些资深人士 ,而是问一些资历比较浅的朋友,比如刚毕业不久的学生,因为他们往往会跟你详细的讲解,而资深人士通常觉得你的问题太简单,所以回答的也很简单,我又不好 意思多问。

  等技术上了一定的层次后我才会问他们,他们也能给你比较深入的回答。另外,有些朋友说我机会比较好,他们也希望能从事新的工作可惜没有机会,我 听了只有苦笑,我的机会了 解的人都应该知道,我没有出生在什么IT世家:)也没有谁一路提拔我,所有的路都是自己走出来的,我母亲去世比较早,我的后母(我叫她阿姨)看着我努力过 来的,一次她看我大年30还在写程序,她说像我这样努力木头都能学出来。

  我的最终目的是IC而不是PCB,所以我下一步的准备开始学习IC设计的知识。公司的同事没有懂IC设计的,后面的路又要靠自己了。我买了不少 相关的书,在网上也查了很多的资料,我花了大量的时间去学习VHDL,并且用软件进行了一些简单的设计和仿真(没有设 计ASIC,只是针对FPGA)。随着学习的深入,我渐渐明白了IC设计的基本流程,同时也明白了这条路的艰辛。这个时候我已经做好了跳槽的准备,我向一 家业界又一定知名度的IC设计公司投了简历,并通过了漫长的面试(4个多小时)。其他的一切我都比较满意,唯独薪资差强人意,我也明白原因,因为我是这个 行业的新人,我没有经验,我再一次将自清零了。公司老板问我6000多一个月能不能接受,我知道他也是照章办事。想想我通信行业的朋友们,基本上都是年薪 10万以上,月薪过万的也比比皆是,朋友们也帮我介绍了不 少待遇不错的公司。我该怎么选择,当时我很犹豫,我热爱我的事业,我向往我的追求,但我也是一个普通的人,我也需要养家糊口,我也想早一点买房买车。生活 给我出了一道难题。

  爱因斯坦在63岁时说过一个人没有在30岁以前达成科学上的最大成就,那他永远也不会有。这句话给了我很大 的压力和震动,我马上就26岁了,离30只有四年时间,我必须抓紧这几年宝贵的时间,努力达到我技术上的最高峰。为了这个理想,为了能离自己的梦更近一 些,我选择了这家IC公司,我明白自己的薪资和公司刚进来的硕士研究生相差无几,但为了今后的发展只能忍受,一切又得重新开始。换行业是一个非常痛苦的过 程,尤其从一个春风得意的位置换到一个陌生的岗位,感觉象从温暖的被子里钻出来跳进冰水中,让人难以接受。在原来那家通信公司,我是唯一两年时间涨了五次 工资的员工,公司和同事都给了我极大的认可,工作上也常常被委以重任。但现在这一切都成了过去,在新的公司 我只是一个新人,没有人知道也没有人在意我过去的成绩。我决定重新开始,我把自己看作 新毕业的学生,我要用自己的努力得到公司的认可。进入新的行业是非常痛苦的,我告诉自己必须忍受这一切,虽然外面有很多诱惑,但是既然作出了选择我就不允 许自己轻易放弃。

  我现在已经在这家新公司上了一个多月的班,开始非常艰难,现在慢慢适应了。第一个月结束时,Team Leader找我谈话,说我是新进员工中最优秀的一个,我心里很欣慰,这也算对我努力的一个肯定吧。在这里还要感谢我的女朋友,她给了我很大的支持和鼓 舞, 每次在我动摇的时候她都在鼓励我,让我坚持自己的理想,刚来上海是她让我不要勉强去做MIS,这次也是她让我顶住了月薪过万的诱惑,没有她我可能不会有今 天的成绩。现在的公司有自己的操作系统,自己的CPU、DSP和其它芯片,在这里我能学到世界上最先进的技术,我们的设计开发不再完全依赖别人的硬件和系 统,这让我很开心。我打算等工作步入正轨后,全力学习新的知识,实现我的理想。
  在后面的两年里我给自己定下了几个目标:

  1、努力做好本职工作,在工作上得到公司和同事们的认同;
  2、努力学习IC硬件设计知识,多向同事请教,并利用一切机会多实践;
  3、实现我的实时操作系统的主要部分,完成TCP/IP协议栈模块,并免费发布源代码;
  4、和我女朋友结婚并买一套小房子,这是最重要的,因为我明白事业是可以重来的,但是珍贵的感情很难失而复得。

  在这里提一下我现在开发的操作系统,它是一个实时嵌入式系统,目前支持以下特性:

  a. 支持时间片轮转调度和基于优先级调度,最多64个优先级;
  b. 抢占式实时内核;
  c. 为了便于移植,主体用标准C实现;
  d. 汇编代码非常少,不到100行;
  e. 支持任务管理,各任务有独立的堆栈;
  f. 进程同步和通信目前完成了Semaphore,Message Queue正在调试;
  g. 实现了定时系统调用;
  h. 可以在Windows上仿真调试。

  我还打算下一步实现优先级反转保护,Event Flag,Data Pipe,内存管理(以前实现过) ,驱动接口等。在这之后我还会努力完善它,比如加入文件系统,协议栈、调试接口等。希望朋友们提出自己的意见和建议,在此不胜感激!
  后记:

  就像有的朋友说的,我的经历或许会给一些朋友产生误导,在这里我必须说明一下。我来上海以前学习过于拼命,常常晚上只睡3个多小时,我身高1米 71,那时只有108斤(我现在130多),家人也说我这样拼命活不过60岁,但是当时的我太固执,我对他们说只要能实现理想活50岁我就够了。那时的拼 命使我的身体受到了影响,有一次早上突然腰肌剧痛难忍,痛的我倒在床上站不起来。虽然我现在已经比较注意,但有时候还会隐隐作痛。后来在女朋友说服了我, 来上海以后我不再如此。我经常引用父亲的一句话身体是革命的本钱。

  而且我也发现拼命不是办法,我可以熬一两个通宵,最多的一次我连续工作了三天三夜, 但是我半个月都没有恢复过来,这样是不是得不偿失?学习工作应该是一个长期的过程, 像马拉松而不是百米冲刺。我现在非常注意调整学习和工作的强度,我要保证每天尽量有相对充沛的精力,一些年轻的朋友觉得自己也应该拼命努力,这让我多少有 些担心,如果我的故事能让你在学习工作上多一点兴趣,我会感到很开心,但如果误导了某些朋友,让你做一些不值得的付出,我会感到很内疚。

  技术没有贵贱之分,我以前换行业是因为自己的兴趣所致,而不是对哪个行业有什么偏见。我希望我的经历不要给朋友一个错误的导向,觉得我始终向更 高的技术发展。其实各行各业做到顶尖都是很困难的。话又说回来虽然技术没有贵贱,但是门槛是有高低的,无论如何,做IC的门槛要比做网页的高,这一点无可 否认。国家各种人才都是需要的,但是作为个人奋发向上的想法还是应该有的,努力在自己喜欢的行业上做的更好,而不应该停留在比较肤浅的层次上。

  我是一个自己觉得比较有自知之明的人,或许我最大的优点就是知道自己有很多缺点 :)。我的故事中很多的曲折和错误都是由我的缺点造成的,希望大家用审慎的眼光看待我的经历,不要被我的花言巧语所迷惑。我学习有些随心所欲,这给我带来 了无尽的麻烦,也大大阻碍了我的发展。记得我小时候成绩比较出色,但是后来学习严重偏科,导致我中学成绩一再滑坡,也没有考上什么好的学校,小时候的一个 朋友,当时的成绩和我相仿,但是没有我这个缺点,她上了清华,后来在去了美国深造,在一个著名导师手下研究理论科学,这未尝不是一条更好的出路。

  另外我的学习方法也是在不断改善中的,过去的学习过于讲究数量和时间,那样学习既苦而已效率不高。现在我非常注意学习的效率和技巧,这样才是学 习的捷径(当然不是指投机取巧),比如说学一相对陌生的技术,如果有条件,不妨问一问有经验的人,不需要问很多,往往他不经意的几句话会给你非常大的帮 助,甚至超过你看一个星期的书。带着这样的思想再去学习你会节省很多时间,这样何乐不为呢?

  这些年中我学了不少的东西,由于开始非常盲目,所以学的东西杂乱无章,现在回想起来让我啼笑皆非,我把大量的时间浪费在一些没有必要深入了解的 知识上,毕竟一个人的精力是有限度的。很多朋友和我一样都背过五笔字形,的确它是个不错的输入法,但是对一个研发人员它绝对不值得你去背,你的时间应该花 在有价值的地方。我这样的事情还做过很多,我背过CCED、WPS的命令和快捷键,在dBase基本退出历史舞台后我还花了很多时间去学习它的使用。所以 我的学习在前期缺乏规划,没有明确的短期目的、中期目标,只有一个虚无飘渺的长期的理想。这就像做设计一样,好的设计是从需求抽象到代码有很多过程,而不 能得到了需求就立刻开始开始编码。

  当然这么些年的学习和工作多多少少有些收获,下面我说说我的一些学习的心得,这些方法未必正确,我也在不断探索和改进中。我的学习和工作有相对 明确的目标,我不会一时心动而去学习某一技术,在下决定之前我会考虑很多,包括长期的发展,个人路线的规划,需要付出的代价、可能遇到的困难及解决的办法 等等;在决定后还会制定更加明确的计划,包括短期、中期和长期的,身边可以利用到的资源(包括好的书籍、资料、软硬件环境,也包括有经验的朋友或者师 长),以及每一个阶段是怎么过渡到高一阶段的计划 ;往往在一个学习阶段一旦上路后会走的相对顺利,但是跨阶段通常比较麻烦,比如从学习基础知识转到实践。另外我买书也有自己的方法,现在世面上高质量的书 远不如低质量书多,对于一个陌生的技术,往往在第一次买书会选择错误,即使买到一本好书但是它的方向也未必适合你,所以我通常会先在网上查找一些该技术的 介绍,有了一点点概念后再去买一本比较薄、相对便宜并且内容相对泛泛而谈的书,这是国内作者最善于写的书:) ,再把它浏览一遍后我就会基本明白这门技术的要点,后面买书和制定计划就会明确的多 。否则一开始就想找本好书往往比较困难,而且买回来后努力学习,有时候学了一半才发现是本低质量的书或者是相对过时技术,让人非常懊恼。另外让有经验的人 帮你介绍,通常也是一个不错的选择。

posted @ 2014-05-07 14:22 ZT文萃 阅读(230) | 评论 (0)编辑 收藏

下文转载自:
http://www.sbanzu.com/topicdisplay.asp?BoardID=8&Page=1&TopicID=4136822
转载不代表赞同作者,仅仅是记录。

有一个名字,全世界所有的独裁者听到都会惊慌。
有一个名字,一切热爱自由的人民听到都要赞扬。
有一个名字,躲在阴暗中谋杀百姓的歹徒对她咬牙切齿。
有一个名字,阳光下渴望和平的人们对她寄予厚望。
是她一次又一次的把世界从恶魔手中拯救,
是她一次又一次的给予恐惧中的人类希望。
是谁挡住了纳粹的铁蹄?
是谁支援了远东的战场?
是谁把集中营解放?
是谁迫使日寇投降?
是谁将那隔开同胞的高墙推倒?
是谁击毙了伊阿独裁流氓?
她高举着火炬,在黑暗中指引我们方向!
她宣言的真理,时时回响在我们耳旁!
虚伪者越是污蔑她虚伪,
正直者越是坚定对她的信仰!
她的伟大我们一刻不忘!
你问我她长的什么模样?
她是炙热通红的火焰,
她是宽广蔚蓝的大海,
她是纯洁耀眼的白光!
你问我她的名?
正告你!
美利坚!
人类的希望!
壮哉,我大美利坚!

posted @ 2014-05-06 12:02 ZT文萃 阅读(318) | 评论 (0)编辑 收藏

下文转帖自:
http://www.cnblogs.com/chenssy/p/3651218.html
版权归作者所有。

hashCode的作用

      要想了解一个方法的内在原理,我们首先需要明白它是干什么的,也就是这个方法的作用。在讲解数组时(java提高篇(十八)------数组),我们提到数组是java中效率最高的数据结构,但是“最高”是有前提的。第一我们需要知道所查询数据的所在位置。第二:如果我们进行迭代查找时,数据量一定要小,对于大数据量而言一般推荐集合。

      在Java集合中有两类,一类是List,一类是Set他们之间的区别就在于List集合中的元素师有序的,且可以重复,而Set集合中元素是无序不可重 复的。对于List好处理,但是对于Set而言我们要如何来保证元素不重复呢?通过迭代来equals()是否相等。数据量小还可以接受,当我们的数据量 大的时候效率可想而知(当然我们可以利用算法进行优化)。比如我们向HashSet插入1000数据,难道我们真的要迭代1000次,调用1000次 equals()方法吗?hashCode提供了解决方案。怎么实现?我们先看hashCode的源码(Object)。

public native int hashCode();

      它是一个本地方法,它的实现与本地机器有关,这里我们暂且认为他返回的是对象存储的物理位置(实际上不是,这里写是便于理解)。当我们向一个集合中添加某 个元素,集合会首先调用hashCode方法,这样就可以直接定位它所存储的位置,若该处没有其他元素,则直接保存。若该处已经有元素存在,就调用 equals方法来匹配这两个元素是否相同,相同则不存,不同则散列到其他位置(具体情况请参考(Java提高篇()-----HashMap))。这样 处理,当我们存入大量元素时就可以大大减少调用equals()方法的次数,极大地提高了效率。

      所以hashCode在上面扮演的角色为寻域(寻 找某个对象在集合中区域位置)。hashCode可以将集合分成若干个区域,每个对象都可以计算出他们的hash码,可以将hash码分组,每个分组对应 着某个存储区域,根据一个对象的hash码就可以确定该对象所存储区域,这样就大大减少查询匹配元素的数量,提高了查询效率。

hashCode对于一个对象的重要性

      hashCode重要么?不重要,对于List集合、数组而言,他就是一个累赘,但是对于HashMap、HashSet、HashTable而言,它变 得异常重要。所以在使用HashMap、HashSet、HashTable时一定要注意hashCode。对于一个对象而言,其hashCode过程就 是一个简单的Hash算法的实现,其实现过程对你实现对象的存取过程起到非常重要的作用。

      在前面LZ提到了HashMap和HashTable两种数据结构,虽然他们存在若干个区别,但是他们的实现原理是相同的,这里我以HashTable为例阐述hashCode对于一个对象的重要性。

      一个对象势必会存在若干个属性,如何选择属性来进行散列考验着一个人的设计能力。如果我们将所有属性进行散列,这必定会是一个糟糕的设计,因为对象的 hashCode方法无时无刻不是在被调用,如果太多的属性参与散列,那么需要的操作数时间将会大大增加,这将严重影响程序的性能。但是如果较少属相参与 散列,散列的多样性会削弱,会产生大量的散列“冲突”,除了不能够很好的利用空间外,在某种程度也会影响对象的查询效率。其实这两者是一个矛盾体,散列的 多样性会带来性能的降低。

      那么如何对对象的hashCode进行设计,LZ也没有经验。从网上查到了这样一种解决方案:设置一个缓存标识来缓存当前的散列码,只有当参与散列的对象改变时才会重新计算,否则调用缓存的hashCode,这样就可以从很大程度上提高性能。

      在HashTable计算某个对象在table[]数组中的索引位置,其代码如下:

int index = (hash & 0x7FFFFFFF) % tab.length;

      为什么要&0x7FFFFFFF?因为某些对象的hashCode可能会为负值,与0x7FFFFFFF进行与运算可以确保index为一个正 数。通过这步我可以直接定位某个对象的位置,所以从理论上来说我们是完全可以利用hashCode直接定位对象的散列表中的位置,但是为什么会存在一个 key-value的键值对,利用key的hashCode来存入数据而不是直接存放value呢?这就关系HashTable性能问题的最重要的问 题:Hash冲突!

      我们知道冲突的产生是由于不同的对象产生了相同的散列码,假如我们设计对象的散列码可以确保99.999999999%的不重复,但是有一种绝对且几乎不 可能遇到的冲突你是绝对避免不了的。我们知道hashcode返回的是int,它的值只可能在int范围内。如果我们存放的数据超过了int的范围呢?这 样就必定会产生两个相同的index,这时在index位置处会存储两个对象,我们就可以利用key本身来进行判断。所以具有相索引的对象,在该 index位置处存在多个对象,我们必须依靠key的hashCode和key本身来进行区分。

hashCode与equals

      在Java中hashCode的实现总是伴随着equals,他们是紧密配合的,你要是自己设计了其中一个,就要设计另外一个。当然在多数情况下,这两个 方法是不用我们考虑的,直接使用默认方法就可以帮助我们解决很多问题。但是在有些情况,我们必须要自己动手来实现它,才能确保程序更好的运作。

      对于equals,我们必须遵循如下规则:

      对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。

      反射性:x.equals(x)必须返回是“true”。

      类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。

      一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。

      任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。

      对于hashCode,我们应该遵循如下规则:

      1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。

      2. 如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。

      3. 如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。

      至于两者之间的关联关系,我们只需要记住如下即可:

      如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。

      如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。

      理清了上面的关系我们就知道他们两者是如何配合起来工作的。先看下图:

2014040701_thumb2

      整个处理流程是:

      1、判断两个对象的hashcode是否相等,若不等,则认为两个对象不等,完毕,若相等,则比较equals。

      2、若两个对象的equals不等,则可以认为两个对象不等,否则认为他们相等。

      实例:

复制代码
public class Person {     private int age;     private int sex;    //0:男,1:女     private String name;      private final int PRIME = 37;      Person(int age ,int sex ,String name){         this.age = age;         this.sex = sex;         this.name = name;     }      /** 省略getter、setter方法 **/      @Override     public int hashCode() {         System.out.println("调用hashCode方法...........");          int hashResult = 1;         hashResult = (hashResult + Integer.valueOf(age).hashCode() + Integer.valueOf(sex).hashCode()) * PRIME;         hashResult = PRIME * hashResult + ((name == null) ? 0 : name.hashCode());          System.out.println("name:"+name +" hashCode:" + hashResult);          return hashResult;     }      /**      * 重写hashCode()      */     public boolean equals(Object obj) {         System.out.println("调用equals方法...........");          if(obj == null){             return false;         }         if(obj.getClass() != this.getClass()){             return false;         }         if(this == obj){             return true;         }          Person person = (Person) obj;          if(getAge() != person.getAge() || getSex()!= person.getSex()){             return false;         }          if(getName() != null){             if(!getName().equals(person.getName())){                 return false;             }         }         else if(person != null){             return false;         }         return true;     } }
复制代码

      该Bean为一个标准的Java Bean,重新实现了hashCode方法和equals方法。

复制代码
public class Main extends JPanel {      public static void main(String[] args) {         Set<Person> set = new HashSet<Person>();          Person p1 = new Person(11, 1, "张三");         Person p2 = new Person(12, 1, "李四");         Person p3 = new Person(11, 1, "张三");         Person p4 = new Person(11, 1, "李四");          //只验证p1、p3         System.out.println("p1 == p3? :" + (p1 == p3));         System.out.println("p1.equals(p3)?:"+p1.equals(p3));         System.out.println("-----------------------分割线--------------------------");         set.add(p1);         set.add(p2);         set.add(p3);         set.add(p4);         System.out.println("set.size()="+set.size());     } }
复制代码

       运行结果如下:

2014040702_thumb

      从上图可以看出,程序调用四次hashCode方法,一次equals方法,其set的长度只有3。add方法运行流程完全符合他们两者之间的处理流程。

posted @ 2014-05-04 06:23 ZT文萃 阅读(265) | 评论 (0)编辑 收藏

下文来自:
http://www.cnblogs.com/chenssy/archive/2012/12/09/2809874.html
版权归作者所有。

      电子邮件用于网上的信心传递和交流,它是最重要的Internet服务之一。据统计Internet30%的业务是电子邮件有关的。同时我们也不可否认它在我们的日常生活、工作办公方面扮演着很重要的角色。譬如:许多办公自动化项目(OA)中都要附带发送邮件的功能,如果还要使用OutLook等手工方式就不适合,在这个高速的时代,我们需要提供工作效率,让工作能够自动化。同时在许多网站中也都需要附带发送邮件的功能:给新注册的用户发送一封包含其注册信息的欢迎E-Mail、将网站的最新活动信息通过E-Mail发送给所有的注册会员等等。

 

       在开始电子邮件开发前:我们需要明白一下几个概念:电子邮件系统、邮件服务器、电子邮件、邮件客户端软件、邮件传输协议、电子邮件的传输过程。

 

       电子邮件系统

       与 传统的邮政服务相类似,电子邮件系统由电子邮局、电子邮件发送、接收系统组成。发送者和接收者通过电子邮件发送、接收系统来发送和接收电子邮件,他们实际 上是运行在计算机上的邮件客户端程序。电子邮局起着一个桥梁的作用,它实际上是运行在服务器上的邮件服务器程序。电子邮件的处理流程也和邮政服务相类似。

 

          

       邮件服务器

       邮件服务器是一种用来负责电子邮件收发管理的设备。在Internet上提供了大量的电子邮件服务器,如:126163hotmail…

       电子邮件服务器主要提供的功能:

           1、  接收用户投递的邮件。

           2、  将用户投递进来的邮件转发给目标邮件服务器。

           3、  接收其他电子邮件服务器转发来的邮件并该邮件存储到其管理的用户邮中。

           4、  为前来读取邮件的用户提供读取邮件的服务。

       邮 件服务器构成了电子邮件系统的核心。每个收信人都有一个位于某个邮件服务器上的邮箱(mailbox)。Bob的邮箱用于管理和维护已经发送给他的邮件消 息。一个邮件消息的典型旅程是从发信人的用户代理开始,邮件发信人的邮件服务器,中转到收信人的邮件服务器,然后投递到收信人的邮箱中。当Bob想查看自 己的邮箱中的邮件消息时,存放该邮箱的邮件服务器将以他提供的用户名和口令认证他。Alice的邮件服务器还得处理Bob的邮件服务器出故障的情况。如果 Alice的邮件服务器无法把邮件消息立即递送到Bob的邮件服务器,Alice的服务器就把它们存放在消息队列(message queue)中,以后再尝试递送。这种尝试通常每30分钟左右执行一次:要是过了若干天仍未尝试成功,该服务器就把这个消息从消息队列中去除掉,同时以另 一个邮件消息通知发信人(即Alice)。

 

       电子邮件

       电子邮件是一种通过网络实现相互传送和接收信息的现代化通信方式。它是种用电子手段提供信息交换的通信方式,是Internet应用最广的服务,通过网络的电子邮件系统,用户可以用非常低廉的价格,以非常快速的方式,与世界上任何一个角落的网络用户联系,这些电子邮件可以是文字、图像、声音等各种方式。同时,用户可以得到大量免费的新闻、专题邮件,并实现轻松的信息搜索。

       电子邮件由信封和内容两个部分组成。信封又称邮件头,电子邮件服务器根据信封上的信心来传递邮件的。内容称为邮件体,它用于提供邮件的具体内容。

       Internet上的电子邮件地址全球唯一,其格式为“邮箱名@邮件服务器域名”。域(邮件域)是电子邮件服务器的基本管理单位,邮件服务以域为基础,每个邮箱对应一个用户。其中邮件服务器域名必须是已注册的DNS域名,并且必须要与MX(邮件交换机)记录匹配。DNS用于将域名、主机名解析为IP地址。MX记录指向该域名的邮件服务器主机记录,为邮件服务专用。

 

       邮件客户端软件

       邮件客户端软件负责与邮件服务器通讯,主要用于帮助用户将邮件发送给SMTP服务器和POP3/IMAP邮件服务器读取用户的电子邮件。邮件客户端软件通常集撰写、发送、接收邮件于一体。

 

 

       电子邮箱

       每一个电子邮件服务器之上都可以开始多个电子邮箱,电子邮箱也称之为E-Mail地址。它类似于现实生活中的通讯地址,用户通过它接受别人发来的电子邮件和向别人发送电子邮件。

       电子邮箱的获得需要在电子邮件服务器上进行申请,确切的说,电子邮箱其实就是用户在邮件服务器上申请的一个账户。邮件服务器把接收到的邮件保持到为某个账户所分配的邮箱空间中,用户通过其申请的用户名和密码登陆到邮件服务器上查看该地址已经收到的电子邮件。

 

       电子邮件的传输过程

       电子邮件系统采用客户/服务器模式。电子邮件传送需要用到以下3个重要模块:

       MUAMail User Agent,邮件用户代理):用户通过它与电子邮件服务器打交道。MUA实际上就是邮件客户端软件。

       MTAMail Transfer Agent,邮件传输代理):它主要负责处理所有接收和发送的邮件,为MUA或者MTA提供邮件发送服务,接收其他MTA发送过来的邮件。

       MDAMail Delivery Agent,邮件投递代理):它负责邮件本地投递。当MTA决定某邮件发送本地用户时,MTA将邮件交给MDA程序进行分发,也就是说投递到用户的。

       具体的传递过程如下:

            1、  发件人利用MUA将邮件发送给MTA

            2、 MTA收到邮件后判断收件人是不是本地账户,如果是本地账户,交由MDA投送到该账户的邮箱中,完成发送过程,跳到第5步。如果不是则执行下一步骤。

            3、 MTA根据其邮件中继转发设置来决定如何转发邮件。

            4、  最终目的的MTA将受到的交给他的MDA处理,有MDA将邮件投递到收件人的邮箱中。

            5、  收件人利用MUA通过POP/IMAP协议连接到邮箱所在的服务器,请求查看自己的收件箱是否有邮件,如果有邮件,将会通过它传送个收件人的MUA

       注意:提示邮件访问服务的是POP或者IMAP服务器软件,而并非当初收下邮件的MTA,两者的角色是分离的。

 

       邮件传输协议

       电子邮件服务传输主要是用到以下3中网络协议

        SMTP(简单邮件传输协议)

       SMTPSimple Mail Transfer Protocol。标准TCP端口是25MUA将邮件发送到MTAMTA将邮件发送给下一个MTA,都是要使用SMTPSMTP的目标是可靠高效地传送邮件,它独立于传送子系统而且仅要求一条可以保证传送数据单元顺序的通道。

       SMTP是一个“单向”的协议,它不能用户从其他邮件服务器收取邮件。它本身是采用客户/服务器模式,负责发送邮件的SMTP进程就是SMTP客户端,负责接收邮件的SMTP进程就是SMTP服务器。一个完整的SMTP通信过程主要包括建立连接、传送邮件、释放连接三个过程。

       建立连接:首先由发件人将要发送的邮件发送到邮件缓存,SMTP客户端定期扫描邮件缓存,一旦发现有邮件,就与SMTP服务器建立TCP连接,然后发送HRLLO命令以附上发送方的主机名。

       传送邮件:SMTP客户端使用MAIL命令开始传送邮件,该命令提供发件人的地址;然后执行RCPT命令,并提供收件人地址;最后执行DATA命令传送邮件内容。

       释放连接:邮件传送完毕后,SMTP客户端发送OUT命令请求关闭TCP连接。

         POP(邮局协议)

         POPPost Office Protocol。标准TCP端口为110。主要用于电子邮件的接收。MUA经由POP协议连接到MTA的用户收件箱,以读取或下载用户在收件箱中邮件。

    目前用的较多的POP协议是POP3POP3使用 TCP 作为传输协议。

       IMAPInternet信息访问协议)

       IMAPInternet Message Access Protocol。标准TCP端口为143,它也是让MUAMTA收取邮件。目标球IMAP协议的版本为IMAP4

       POPIMAP两者都可以用于收取邮件,都是采用客户/服务器模式,两者最主要的区别就在于他们检索邮件的方式不同。使用POP时,邮件驻留在服务器中个,一旦接收邮件,邮件都从服务器上下载到用户计算机上。而IMAP则能够然该用户了解到服务器上存储邮件的情况,已下载的邮件仍然滞留在服务器中,以便于实现邮件归档和共享。

posted @ 2014-05-04 06:19 ZT文萃 阅读(409) | 评论 (0)编辑 收藏

转载自:
http://www.cnblogs.com/chenssy/p/3308489.html
版权归作者所有。

      首先来看看浅拷贝和深拷贝的定义:

      浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝。

      深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。这个方式称为深拷贝

      也就是说浅拷贝只复制一个对象,传递引用,不能复制实例。而深拷贝对对象内部的引用均复制,它是创建一个新的实例,并且复制实例。

      对于浅拷贝当对象的成员变量是基本数据类型时,两个对象的成员变量已有存储空间,赋值运算传递值,所以浅拷贝能够复制实例。但是当对象的成员变量是引用数据类型时,就不能实现对象的复制了。

      存在一个对象Person,代码如下:

复制代码
public class Person {     private String name;     private String sex;     private int age;          public Person(String name,String sex,int age){         this.name = name;         this.sex = sex;         this.age = age;     }          public Person(Person p){                   //拷贝构造方法,复制对象         this.name = p.name;         this.sex = p.sex;         this.age = p.age;     } }
复制代码

      上面的对象Person有三个成员变量。name、sex、age。两个构造方法。第二个的参数为该对象,它称为拷贝构造方法,它将创建的新对象初始化为形式参数的实例值,通过它可以实现对象复制功能。

      又有一个对象Asian,如下:

复制代码
public class Asian {     private String skin;     Person person;          public Asian(String skin,Person person){         this.skin = skin;         this.person = person;                    //引用赋值     }      public Asian(Asian asian){                 //拷贝构造方法,复制对象         this(asian.skin,asian.person);                } }
复制代码

      上面对象也存在着两个成员变量,skin 和Person对象

      对于person对象有如下:

Person p1 = new Person("李四","mam",23);   Person p2 = new Person(P1);

      当调用上面的语句时。P2对象将会对P1进行复制。执行情况如下如下图:

      对于Asian对象有:

Asian a1 = new Asian("yellow",new Person("李四","mam",23)); Asian a2 = new Asian(a1);

      New Asian(a1)执行Asian类的拷贝构造方法,由于对象赋值是引用赋值。使得a1和a2引用同一个对象

      如下图:

      当a1执行某条可以改变该值的语句时,那么a1将会通过这个语句也可以改变a2对象的成员变量

      如果执行以下语句:a2.name = new Person(a1.name)

      这时将会创建一个新的Person对象

      如下图:


posted @ 2014-05-04 06:15 ZT文萃 阅读(369) | 评论 (0)编辑 收藏

转帖:

http://www.cnblogs.com/chenssy/p/3695271.html
版权归作者所有。


     今天朋友问我String的内容是真的不可变吗?我肯定告诉他是的?因为在我的主观意识里String就是一个不可变的对象。于是他给我发了这段程序:

复制代码
public class StringTest {     public static void main(String[] args) throws Exception {         String a = "chenssy";         System.out.println("a = " + a);         Field a_ = String.class.getDeclaredField("value");         a.setAccessible(true);         char[] value=(char[])a.get(a);         value[4]='_';   //修改a所指向的值         System.out.println("a = " + a);     } }
复制代码

      看到这个简单的程序,我笑了,你这不是从底层来修改String的值么?从这里来理解String的值肯定是可以改变的啦(我们应该始终相信String的不可变性)!接着他再给我一段程序:

复制代码
public class StringTest {     public static void main(String[] args) throws Exception {         String a = "chenssy";         String b = "chenssy";         String c = new String("chenssy");         System.out.println("--------------修改前值-------------------");         System.out.println("a = " + a);         System.out.println("b = " + b);         System.out.println("c = " + c);         //修改String的值         Field a_ = String.class.getDeclaredField("value");         a_.setAccessible(true);         char[] value=(char[])a_.get(a);         value[4]='_';   //修改a所指向的值                  System.out.println("--------------修改后值-------------------");         System.out.println("a = " + a);         System.out.println("b = " + b);         System.out.println("chenssy");         System.out.println("c = " + c);     } }
复制代码

      乍看这程序是异常的简单,无非就是赋值、改值、输出嘛!可能你现在就会毫不犹豫的说太简单了结果就是……。但是!!你的毫不犹豫会害死你,而且你的结果很可能错误。那么运行结果是什么呢?

复制代码
--------------修改前值------------------- a = chenssy b = chenssy c = chenssy --------------修改后值------------------- a = chen_sy b = chen_sy chen_sy c = chen_ssy
复制代码

      修改前值很容易理解,但是修改后值呢?是不是有点儿不理解呢?你可能会问:为什么System.out.println("chenssy");的结果会是chen_ssy,System.out.println("c = " + c);也是chen_ssy呢?

      要明白这个其实也比较简单,掌握一个知识点:字符串常量池。

      我们知道字符串的分配和其他对象分配一样,是需要消耗高昂的时间和空间的,而且字符串我们使用的非常多。JVM为了提高性能和减少内存的开销,在实例化字 符串的时候进行了一些优化:使用字符串常量池。每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回 常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串(这点对理解上面至关重要)。

      我们再来理解上面的程序。

      String a = "chenssy";

      String b = "chenssy";

      a、b和字面上的chenssy都是指向JVM字符串常量池中的”chenssy”对象,他们指向同一个对象。

      String c = new String("chenssy");

      new关键字一定会产生一个对象chenssy(注意这个chenssy和上面的chenssy不同),同时这个对象是存储在堆中。所以上面应该产生了两 个对象:保存在栈中的c和保存堆中chenssy。但是在Java中根本就不存在两个完全一模一样的字符串对象。故堆中的chenssy应该是引用字符串 常量池中chenssy。所以c、chenssy、池chenssy的关系应该是:c--->chenssy--->池chenssy。整个 关系如下:

      201404271001

      通过上面的图我们可以非常清晰的认识他们之间的关系。所以我们修改内存中的值,他变化的是所有。

      总结:虽然a、 b、c、chenssy是不同的对象,但是从String的内部结构我们是可以理解上面的。String c = new String("chenssy");虽然c的内容是创建在堆中,但是他的内部value还是指向JVM常量池的chenssy的value,它构造 chenssy时所用的参数依然是chenssy字符串常量。

      为了让各位充分理解常量池,特意准备了如下一个简单的题目:

String a = "chen"; String b = a + new String("ssy");
         创建了几个String对象??

posted @ 2014-05-04 06:10 ZT文萃 阅读(207) | 评论 (0)编辑 收藏

Class的getResource方法,实际上是靠调入这个类的ClassLoader的getResource方法来实现的,如果调入这个类的ClassLoader是原生的BootStrap ClassLoader,这个ClassLoader是用C++写成的,在Java中没有相对应的物件。这时候的实现靠的是ClassLoader的静态方法getSystemResource。

只有当使用Class类的getResource方法的时候,才会有下面介绍的那种算法。

这种算法就是说,如果你指定的路径以/开头,那么就是从ClassPath的起点开始寻找这个路径。如果直接以某个名字开头,那么就是从当前包名的目录为起点开始寻找。
所以大家如果用过hibernate就知道,有些表示类到数据库表的映射关系的xml文件就和这个类的class文件放在一起,这样它就直接使用这个类.class.getResource方法来得到这个xml文件。

而在使用ClassLoader的getResource方法的时候,永远是以Classpath为直接起点开始寻找资源的。不用担心从什么包开始寻找的问题。

用Class.getResource不加/就是从当前包开始找,用ClassLoader.getResource不加/就是直接从Classpath的起点开始寻找。

当然,如果觉得麻烦,你定位资源的时候全部都使用/开头的方式就好了

posted @ 2014-05-02 15:48 ZT文萃 阅读(543) | 评论 (0)编辑 收藏







查找带有给定名称的资源,查找给定类相关的资源的规则是通过定义类的 class loader 实现的。此方法委托给此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResource(java.lang.String)

在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:

  • 如果 name'/'  开始,则绝对资源名是 '/' 后面的 name 的一部分。
  • 否则,绝对名具有以下形式:
       modified_package_name/name 

    其中 modified_package_name 是此对象的包名,该名用 '/' 取代了 '.' ('\u002e')。

Class.getResource(""); 获取classpath

 

Class.getResource("JMF.class"); 代表获取相于类路径当前包下的SendService.class的类路径.

/D:/bak/upload/upload/WebRoot/WEB-INF/classes/jmf/JMF.class-------->打印出的结果

Class.getResource("/jmf/WebCamSwing.class"); /jmf/WebCamSwing.class->代表相于类路径的绝对路径

file:/D:/bak/upload/upload/WebRoot/WEB-INF/classes/jmf/JMF.class  -------->打印出的结果

 

我们怎么获得Object的类路径:

Class.getResource("/java/lang/Object.class") 因为Object是通过引导类加载器 (BootStrapClassLoader)加载的,所以此方法通过系统类加载器来查找资料, 所以我们要指定类的绝对路径/java/lang /Object.class

public java.net.URL getResource(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResource(name);
        }
        return cl.getResource(name);
    }

 

我们来看看如何通过系统类加载器来查找Object:

Class.getClassLoader().getSystemResource("java/lang/Object.class")

 

打印出来的结果多是:

jar:file:/E:/Program/Java/jdk1.5.0_15/jre/lib/rt.jar!/java/lang/Object.class

 

为什么getResource("")前面要加"/",而getSystemResource("")前面不用加呢?

private String resolveName(String name) {
        if (name == null) {
            return name;
        }
        if (!name.startsWith("/")) {
            Class c = this;
            while (c.isArray()) {
                c = c.getComponentType();
            }
            String baseName = c.getName();
            int index = baseName.lastIndexOf('.');
            if (index != -1) {
                name = baseName.substring(0, index).replace('.', '/')
                    +"/"+name;
            }
        } else {
            name = name.substring(1);
        }
        return name;
    }

 

其实最后还是要把"/"去掉的...

posted @ 2014-05-02 15:34 ZT文萃 阅读(285) | 评论 (0)编辑 收藏

转载自:

1 JButton 图片和文字按钮的实现



JButton btn1 = new JButton("打开", new ImageIcon(ImageView.class.getResource("10.png"))) ;

btn1.setHorizontalTextPosition(SwingConstants.CENTER);

btn1.setVerticalTextPosition(SwingConstants.BOTTOM);

 

效果图 :

clip_image003

2 JButton 图片透明按钮的实现



setLayout(new FlowLayout(FlowLayout.RIGHT, 30, 0));

btn1.setIcon(UIConfig.getImgUrl("常用交易字.png"));

btn1.setRolloverIcon(UIConfig.getImgUrl("常用交易.png"));

btn1.setBorderPainted(false);

btn1.setFocusPainted(false);

btn1.setContentAreaFilled(false);

btn1.setFocusable(true);

btn1.setMargin(new Insets(0, 0, 0, 0));

btn1.setText("常用交易");

 

clip_image006

3JRadioButton 图片透明按钮的实现

JRadioButton radio = new JRadioButton(UIConfig.getImgUrl("常用交易字.png") );

radio.setContentAreaFilled(false);

radio.setRolloverIcon(UIConfig.getImgUrl("常用交易.png"));

radio.setSelectedIcon(UIConfig.getImgUrl("常用交易.png"));

clip_image006[1]

posted @ 2014-04-27 11:12 ZT文萃 阅读(497) | 评论 (0)编辑 收藏

posted @ 2014-03-28 08:56 ZT文萃 阅读(137) | 评论 (0)编辑 收藏