??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲熟妇无码AV不卡在线播放,亚洲AV无码成人精品区在线观看,亚洲国产成人片在线观看http://www.tkk7.com/chenweicai/zh-cnTue, 13 May 2025 10:29:17 GMTTue, 13 May 2025 10:29:17 GMT60web2.0http://www.tkk7.com/chenweicai/archive/2007/08/07/135067.htmlchenweicaichenweicaiTue, 07 Aug 2007 12:46:00 GMThttp://www.tkk7.com/chenweicai/archive/2007/08/07/135067.htmlhttp://www.tkk7.com/chenweicai/comments/135067.htmlhttp://www.tkk7.com/chenweicai/archive/2007/08/07/135067.html#Feedback0http://www.tkk7.com/chenweicai/comments/commentRss/135067.htmlhttp://www.tkk7.com/chenweicai/services/trackbacks/135067.html引子 Web 2.0,在过ȝ一q里也许q是一个新的名词,曑և何时它像|上核武一L发了Qƈ以不可阻挡之势燃烧了整个互联|,其热度不压于当年的超奻I又曾几何时它悄悄地走q了我们的生z,从陌生走向了熟悉Q从概念走向了应用。今天,Web 2.0构成了我们网l生zM可缺的一部分Q今天,你Web 2.0了吗Q?/span>

什么是Web2.0Q?br>如果你是一只老网虫但q不知道什么是Web2.0Q赶紧去xv吧,不怕死的就去蟩Q记得带个救生圈Q出事了我不负责哈!Q,怕死的还不赶紧补补课Q免得被人看I了让hW话。如果你是个善于表现自己的hQ多学点东西吧,学了Web 2.0你可以不分对象地大谈特谈地讲qC的Web 2.0观点Q?嘿嘿Q想象一下别人对你崇拜的表情吧?br>

Web2.0是以 Flickr、Craigslist、Linkedin、Tribes、Ryze?Friendster、Del.icio.us?3Things.com{网站ؓ代表Q以Blog、TAG、SNS、RSS、wiki{应用ؓ核心Q依据六度分隔、xml、ajax{新理论和技术实现的互联|新一代模式?/p>

 1. 什么是Wiki

  WIKI的来?/strong>

  WIKI概念的发明h是Ward CunninghamQ该词来源于夏威夯?#8220;wee kee wee kee”Q原本是“快点快点” (quick)的意思?/p>

  Wiki--一U多人协作的写作工具。Wiki站点可以有多?甚至M讉K?l护Q每个h都可以发表自q意见Q或者对共同的主题进行扩展或者探讨?/p>

  Wiki指一U超文本pȝ。这U超文本pȝ支持面向C的协作式写作Q同时也包括一l支持这U写作的辅助工具。有为,Wikipȝ属于一Uhcȝ识网格系l,我们可以在Web的基上对Wiki文本q行览、创建、更改,而且创徏、更攏V发布的代hq比HTML文本?同时Wikipȝq支持面向社的协作式写作,为协作式写作提供必要帮助;最后,Wiki的写作者自然构成了一个社,Wikipȝ个社提供简单的交流工具。与其它文本系l相比,Wiki有用方便及开攄特点Q所以Wikipȝ可以帮助我们在一个社内׃n某领域的知识?/p>

      WIKI可以做什?/strong>

  WIKI最适合做百U全书、知识库、整理某一个领域的知识{知识型站点Q几个分在不同地区的人利用wiki协同工作共同写一本书{等。Wiki技术已l被较好的用在百U全书、手?FAQ~写、专题知识库斚w?/p>

  Wiki的特?/font>

  使用方便

  l护快捷:快速创建、存取、更改超文本面(q也是ؓ什q叫?#8220;wiki wiki”的原??/p>

  格式?用简单的格式标记来取?HTML 的复杂格式标记?cM所见即所得的风格)

  链接方便:通过单标讎ͼ直接以关键字名来建立链接(面、外部连接、图像等)?/p>

  命名qx:关键字名是面名称Qƈ且被|于一个单层、^直的名空间中?/p>

  有组l?/strong>

  自组l的:同页面的内容一P整个文本的l织l构也是可以修改、演化的?/p>

  可汇聚的:pȝ内多个内定w复的面可以被汇聚于其中的某个,相应的链接结构也随之改变?/p>

  可增?/strong>

  可增?面的链接目标可以尚未存在,通过点击链接Q我们可以创些页面,从而ɾpȝ得到增长?/p>

  修订历史:记录面的修订历Ԍ面的各个版本都可以被获取?/p>

  开放?/strong>

  开攄:C的成员可以Q意创建、修攏V删除页面?/p>

  可观?pȝ内页面的变动可以被访问者观察到?br>
2.

  什么是RSS

  RSS是站点用来和其他站点之间׃n内容的一U简易方?也叫聚合内容)的技术。最初源自浏览器“新闻频道”的技术,现在通常被用于新d其他按顺序排列的|站Q例如Blog?/p>

  RSS可以q什?

  1、订阅BLOG(BLOG上,你可以订阅你工作中所需的技术文?也可以订阅与你有共同爱好的作者的日志QMQBLOG上你对什么感兴趣你就可以订什?

  2、订阅新?无论是奇L事、明星消息、体坛风云,只要你想知道的,都可以订?

  如何使用RSS

  ·下蝲和安装一个RSS新闻阅读?/p>

  ·从网站提供的聚合新闻目录列表中订阅您感兴的新闻栏目的内?/p>

  ·订阅后您会及时获得所订阅新闻频道的最新内?/p>

  RSS的几个羃写来?/font>

  1、Really Simple Syndication(真正易的聚合)

  2、Rich Site Summary(丰富的站Ҏ?

  3、RDF Site Summary(RDF站点摘要)

  RSS新闻特点

  对网民而言:对网站而言:

  1.没有q告或者图片来影响标题或者文章概要的阅读?/p>

  2.RSS阅读器自动更C定制的网站内容,保持新闻的及时性?/p>

  3.用户可以加入多个定制的RSS提要Q从多个来源搜集新闻整合到单个数据流中。 1.扩大了网站内容的传播面,也增加了|站讉K量,因ؓ讉K者调阅的RSS文g和浏览的|页Q都是从|站服务器上下蝲的?/p>

  2.RSS文g的网址是固定不变的Q网站可以随时改变其中的内容。RSS内容一旦更斎ͼ览者看到的内容也随xC


3.什么是Tag?

  Tag(标签)是一U更为灵zR有的分类方式Q您可以为每日志、每个帖子或者每张图片等d一个或多个Tag(标签)Q你可以看到|站上所有和您用了相同Tag的内容,由此和他Z生更多的联系。Tag体现了群体的力量Q得内容之间的相关性和用户之间的交互性大大增强?/p>

  比如Q你在一日志上d?#8220;M”?#8220;Tag”两个标签Q就能通过q两个tag看到和你有相同兴的其他日志。同P如果你给自己的网l书{脓上不同标{,那么Q在下一ơ去LӞ会轻易找到自己想要的信息?/p>

  那么Q如果我贴了TagQ能产生什么效果呢?首先Q信息将会条理化。其ơ,当你U篏了一定数量的Tag之后Q你会发现自己最兛_的话题。GOOGLE?我的搜烦历史"功能是采用了标{,你的每次搜烦关键词都可以成ؓtagQ之后,你会了解自己q一天在兛_什么?/p>

  当然Q你也可以看到有哪些人和自己使用了一LTag(标签)Q进而找到和您志相投的人?/p>

  2、TagI竟有哪些不?

  Tag不是关键词,因ؓQ一个机器就没有办法提取一张照片的关键字,但h可以l它讑֮一个或多个Tag。而Tag真正不同的地方在于,你可以随意用M词来标记一件事物,只要方便你找到它。因此,q一标志是活跃的、无序的、个人化、相当自我的一U标记方式?/p>

  当我可以为我自己的言Z己想要的标志Q而不是别人给予我的分c,那么Q我说些什么呢?我又会通过q种标志扑ֈ什么样的h什么样的文章、图片呢?Tag创造了一个新的无序但充满生机的网l联合体Q通过q个联合Qh们找到和自己最接近的内宏V?/p>

  3、如何用Tag?

  现在很多|站都用了Tag模式Q只要用者自w打开了界限,随心所Ʋ地l自己注释标{,不被旧有思维局限住Q就对了。简单地_Tag是一U随心所Ʋ的标签Q当我读一文章或者看一张图片的时候想什么就写什么,不受原有分类的束~,怎么惛_怎么使用?/p>

chenweicai 2007-08-07 20:46 发表评论
]]>
葛底斯堡演说http://www.tkk7.com/chenweicai/archive/2007/06/30/127209.htmlchenweicaichenweicaiSat, 30 Jun 2007 03:23:00 GMThttp://www.tkk7.com/chenweicai/archive/2007/06/30/127209.htmlhttp://www.tkk7.com/chenweicai/comments/127209.htmlhttp://www.tkk7.com/chenweicai/archive/2007/06/30/127209.html#Feedback0http://www.tkk7.com/chenweicai/comments/commentRss/127209.htmlhttp://www.tkk7.com/chenweicai/services/trackbacks/127209.html
Delivered on the 19th Day of November, 1863

Cemetery Hill, Gettysburg, Pennsylvania

Fourscore and seven years ago, our fathers brought forth upon this continent a new Nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now, we are engaged in a great Civil War,testing whether that Nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war. We have come to dedicate a portion of that field as a final resting-place for those who gave their lives that Nation might live. It is altogether fitting and proper that we should do this.

But, in a larger sense, we cannot dedicate, we cannot consecrate, we cannot hallow this ground. The brave men, living and dead, who struggled here, have consecrated it far above our power to add or detract. The world will little note nor long remember what we say here, but it can never forget what they did here. It is for us, the living, rather to be dedicated to the great task remaining before us; that from these honored dead, we take increased devotion to that cause for which they gave the last full measure of devotion; that this Nation, under GOD, shall have a new birth of freedom; and that government of the People by the People and for the People shall not perish from the earth.

葛底斯堡演说

亚伯拉罕·林肯Q?963q?1?9?br>
87q前Q我们的先辈们在q个大陆上创立了一个新国家Q它孕育于自׃中,奉行一切h生来q等的原则。现在我们正从事一Z大的内战Q以考验q个国家Q或者Q何一个孕育于自由和奉行上q原则的国家是否能够长久存在下去。我们在q场战争中的一个伟大战Z集会。烈士们Zɘq个国家能够生存下去而献Z自己的生命,我们来到q里Q是要把q个战场的一部分奉献l他们作为最后安息之所。我们这样做是完全应该而且是非常恰当的?br>
但是Q从更广泛的意义上来_q块土地我们不能够奉献,不能够圣化,不能够神化。那些曾在这里战斗过的勇士们Q活着的和M的,已经把这块土地圣化了Q这q不是我们微薄的力量所能增减的。我们今天在q里所说的话,全世界不大会注意Q也不会长久地记住,但勇士们在这里所做过的事Q全世界却永q不会忘记。毋宁说Q倒是我们q些q活着的hQ应该在q里把自己奉献于勇士们已l如此崇高地向前推进但尚未完成的事业。倒是我们应该在这里把自己奉献于仍然留在我们面前的伟大d??我们要从q些光荣的死者n上݅取更多的献n_Q来完成他们已经完全dZ献n的事业;我们要在q里下定最大的军_Q不让这些死者白白牺Ԍ我们要国家在上帝福佑下得到自由的新生,要ɘq个民有、民沅R民享的政府怸长存?

chenweicai 2007-06-30 11:23 发表评论
]]>
肯尼qȝp演说http://www.tkk7.com/chenweicai/archive/2007/06/30/127208.htmlchenweicaichenweicaiSat, 30 Jun 2007 03:18:00 GMThttp://www.tkk7.com/chenweicai/archive/2007/06/30/127208.htmlhttp://www.tkk7.com/chenweicai/comments/127208.htmlhttp://www.tkk7.com/chenweicai/archive/2007/06/30/127208.html#Feedback0http://www.tkk7.com/chenweicai/comments/commentRss/127208.htmlhttp://www.tkk7.com/chenweicai/services/trackbacks/127208.htmlInaugural Address of John F. Kennedy  肯尼qȝp演说
January 20, 1961

Vice President Johnson, Mr. Speaker, Mr. Chief Justice, President Eisenhower, Vice President Nixon, President Truman, Reverend Clergy, fellow citizens:

We observe today not a victory of party but a celebration of freedom, symbolizing an end as well as a beginning, signifying renewal as well as change. For I have sworn before you and Almighty God the same solemn oath our forebears prescribed nearly a century and three-quarters ago.

我们今天所看到的,q是某一党派的胜利,而是自由的庆典。它象征着l束Q亦象征着开始;意味着更新Q亦意味着变化。因为我已在你们及万能的上帝面前Q依着我们先辈175q前写下的誓a宣誓?/p>

The world is very different now. For man holds in his mortal hands the power to abolish all forms of human poverty and all forms of human life. And yet the same revolutionary beliefs for which our forebears fought are still at issue around the globe -- the belief that the rights of man come not from the generosity of the state but from the hand of God.

世界已然今非昔比Q因ZhcL中已l掌握了巨大的力量,既可以用来消除各UŞ式的贫困Q亦可用以毁灭hcȝ会。然而,我们先辈曾ؓ之战斗的那些革命性的信念q依然在世界上受Z议——那是Q每个h享有的各Ҏ利决非来自国家政权的h赐予Q而是上帝之手?/p>

We dare not forget today that we are the heirs of that first revolution. Let the word go forth from this time and place, to friend and foe alike, that the torch has been passed to a new generation of Americans -- born in this century, tempered by war, disciplined by a hard and bitter peace, proud of our ancient heritage -- and unwilling to witness or permit the slow undoing of those human rights to which this nation has always been committed, and to which we are committed today at home and around the world.

今天Q我们不敢有忘,我们乃是那第一ơ革命的后裔。此Ӟ让这个声音从q里同时向我们的朋友和敌Z达:火炬现已传递到C代美国h手中——他们生于本世纪Q既l受q战火的锤炼Q又l历q艰难严ȝ和^岁月的考验。他们深为我们古老的遗所自豪——决不愿目睹或听任诸h权受到无形的侵蚀Q这些权利不仅ؓq个国家始终信守不渝Q亦是我们正在国内和世界上誓L卫的东西?/p>

Let every nation know, whether it wishes us well or ill, that we shall pay any price, bear any burden, meet any hardship, support any friend, oppose any foe to assure the survival and the success of liberty.

让每一个国安知道Q无论它们对我们抱有善意q是恶意Q我们都准备付出M代h、承受Q何重仅R迎战Q何艰险、支持Q何朋友、反对Q何敌人,以自由得以l系和胜利?/p>

This much we pledge -- and more.

q是我们矢志不移的承诺,且远不止此!

To those old allies whose cultural and spiritual origins we share, we pledge the loyalty of faithful friends. United there is little we cannot do in a host of cooperative ventures. Divided there is little we can do, for we dare not meet a powerful challenge at odds and split asunder.

对于那些与我们共享同一文化和精源头的老朋友,我们总朋友的忠诚。在许许多多的合作事业中Q我们会己所能以促进我们的团l,而决不故意制造分裂,因ؓ我们不敢L面对由分歧或体系崩溃而导致的巨大挑战?/p>

To those new states whom we welcome to the ranks of the free, we pledge our word that one form of colonial control shall not have passed away merely to be replaced by a far more iron tyranny. We shall not always expect to find them supporting our view. But we shall always hope to find them strongly supporting their own freedom -- and to remember that, in the past, those who foolishly sought power by riding the back of the tiger ended up inside.

对于那些新成立的国家Q我们欢q它们加入自由阵营,q在此许以忠告:某种形式的殖民控制决不会仅仅因ؓ被另一U更为残L霸权所取代消声匿qV我们不会期待他们始l支持我们的观点Q但我们希望他们能始l坚定地l护他们自己的自由——ƈ且牢讎ͼ在过去,那些愚蠢地骑上独~裁的虎背以谋求权力的h最l都以葬w虎腹而告l?/p>

To those people in the huts and villages of half the globe struggling to break the bonds of mass misery, we pledge our best efforts to help them help themselves, for whatever period is required -- not because the communists may be doing it, not because we seek their votes, but because it is right.

对于那些寄居于大半个地球上的草舍村落、ؓ着挣脱无尽苦难的枷锁而奋斗的人民Q我们承诺将我们最大的努力Q以使他们获得自助的能力。因是时代对我们提出的要求——不是因为共~~党人可能如此行事、不是因为我们需要他们的选票Q仅仅是因ؓq样做是正当的?/p>

If a free society cannot help the many who are poor, it cannot save the few who are rich.

如果一个自qC会不能帮助贫穷的多敎ͼ它就不能拯救那富裕的数?/p>

To our sister republics south of our border, we offer a special pledge: to convert our good words into good deeds, in a new alliance for progress, to assist free men and free governments in casting off the chains of poverty. But this peaceful revolution of hope cannot become the prey of hostile powers. Let all our neighbors know that we shall join with them to oppose aggression or subversion anywhere in the Americas.

对于我们的南部邻邦共和国Q我们许以特D的承诺Q将我们的良a转ؓ善行Q在Zq步而结成的新盟邦里Q帮助自q人民和自q政府摆脱贫困。但q一希翼中的和^革命不能成ؓ敌对势力的牺牲品Q让我们所有的邻邦都知道,我们与他们一道,反对发生在美zQ何地区的늕和颠覆?/p>

And let every other power know that this hemisphere intends to remain the master of its own house.

让所有其他势力都知道Q这一半球的h民致力于l护他们作ؓ自己家园Mh的地位?/p>

To that world assembly of sovereign states, the United Nations, our last best hope in an age where the instruments of war have far outpaced the instruments of peace, we renew our pledge of support -- to prevent it from becoming merely a forum for invective, to strengthen its shield of the new and the weak, and to enlarge the area in which its writ may run.

对于那个L国家的世界性会议组l——联合国Q我们最后一ơ良好祝愿是发生在战争机器远q超q和qx器的时代。ؓ了防止它沦ؓ仅仅用来谩骂攻讦的论坛,Z加强它对新成立国家及弱小国家的保障功能、ؓ了扩展其权力늛的领域,我们现在重申对它的支持承诺?/p>

Finally, to those nations who would make themselves our adversary, we offer not a pledge but a request: that both sides begin anew the quest for peace -- before the dark powers of destruction unleashed by science engulf all humanity in planned or accidental self-destruction.

最后,对于那些d站到我们敌对面的国家Q我们提出的不是许诺Q而是xQ在被科学释攑և的、黑暗的破坏力量以有计划的或偶然性的自我毁灭方式吞噬全hcM前,x双方再一ơ地开始谋求和q的努力?/p>

We dare not tempt them with weakness. For only when our arms are sufficient beyond doubt can we be certain beyond doubt that they will never be employed. But neither can two great and powerful groups of nations take comfort from our present course -- both sides overburdened by the cost of modern weapons, both rightly alarmed by the steady spread of the deadly atom, yet both racing to alter that uncertain balance of terror that stays the hand of mankind's final war. So let us begin anew -- remembering on both sides that civility is not a sign of weakness, and sincerity is always subject to proof.

我们不敢以Yp惑它们,因ؓ只有当我们的军备充到确切无疑的E度Ӟ我们才能切无疑地肯定它们永q不会被投入使用。但q两个强大的国家集团都无法从彼此当前的做法中得到安慰——双斚w背负了过高的C武器pȝ的成本、双斚w理所当然地对致死性原子武器的持箋扩散感到惊恐不安Q但双方都竞相改变不定的恐怖均衡,q种均衡恰恰抑制了hcL后摊牌的冲动?/p>

Let us never negotiate out of fear. But let us never fear to negotiate.

让我们永q不要因为惧怕而谈判,让我们永q不要惧怕谈判?/p>

Let both sides explore what problems unite us instead of belaboring those problems which divide us.

让双Ҏ寻那些能我们团l在一L因素Q而不是那些刻意挑出那些分裂我们的因素?/p>

Let both sides, for the first time, formulate serious and precise proposals for the inspection and control of arms, and bring the absolute power to destroy other nations under the absolute control of all nations.

让双斚w先提真细致的Ҏ来核查及控制军备Qƈ毁灭其他国家的l对力量|于所有国家的l对控制之下?/p>

Let both sides seek to invoke the wonders of science instead of its terrors. Together let us explore the stars, conquer the deserts, eradicate disease, tap the ocean depths, and encourage the arts and commerce.

让双方努力去Ȁ发科学的奇迹Q而非U学的恐怖。让我们一同探索星I、征服沙漠、消除疾病、开发vz深处,鼓励艺术和商业?/p>

Let both sides unite to heed, in all corners of the earth, the command of Isaiah -- to "undo the heavy burdens... [and] let the oppressed go free."

让双方在世界每一个角落,都共同信守《圣l.以赛亚书》中的教诜y?#8220;怸重负……让被压迫者自由?#8221;

And if a beachhead of cooperation may push back the jungle of suspicion, let both sides join in creating a new endeavor -- not a new balance of power, but a new world of law -- where the strong are just, and the weak secure, and the peace preserved.

如果合作的W头堡能够遏制重重猜疑Q让双方携手q行新的努力——不是ؓ了徏立新的势力均衡,而是Z建立新的规则体系——以使强者正义,p安全,和^l系?/p>

All this will not be finished in the first one hundred days. Nor will it be finished in the first one thousand days; nor in the life of this Administration; nor even perhaps in our lifetime on this planet. But let us begin.

所有这些工作将不会在从现在L一癑֤、一千天内完成,也不会在本届行政分支L内完成,甚至可能不会在我们的有生之年完成Q但是,误我们现在开始工作?/p>

In your hands, my fellow citizens, more than mine, will rest the final success or failure of our course. Since this country was founded, each generation of Americans has been summoned to give testimony to its national loyalty. The graves of young Americans who answered the call to service surround the globe.

我的同胞们,我们事业的最l成败将掌握在你们的手中而不仅仅是我的手中。从q个国家被创建那天vQ每一代美国h都被召唤去证实自己对国家的忠诚。那些响应号召献w国家的q轻国人的安息之所遍布全球?/p>

Now the trumpet summons us again -- not as a call to bear arms, though arms we need -- not as a call to battle, though embattled we are -- but a call to bear the burden of a long twilight struggle, year in and year out, rejoicing in hope, patient in tribulation, a struggle against the common enemies of man: tyranny, poverty, disease, and war itself.

现在Q召唤的可又一ơ吹响——不是号召我们扛h器,虽然武器是我们所需要的——也不是号召我们d加战斗,虽然我们准备战斗——而是号召我们q复一q地去进行一场O长而未分胜负的搏斗Q在希望中欢乐,而患难中忍耐,以反对hcd同的敌hQ暴ѝ困、疾病以及战争本w?/p>

Can we forge against these enemies a grand and global alliance, North and South, East and West, that can assure a more fruitful life for all mankind? Will you join in that historic effort?

Z反对q些敌hQ我们能够将南方与北斏V东方与西方团结hQ熔铸成一个伟大的和全球性的联盟Q以保全hcd享更为成果篏累的生活吗?你们愿意参与q项历史性的努力吗?

In the long history of the world, only a few generations have been granted the role of defending freedom in its hour of maximum danger. I do not shrink from this responsibility -- I welcome it. I do not believe that any of us would exchange places with any other people or any other generation. The energy, the faith, the devotion which we bring to this endeavor will light our country and all who serve it. And the glow from that fire can truly light the world.

在世界历史的长河里,只有数几代赋予了在自由面最大危机时捍卫自由的命,我不会畏~于q一责Q——我Ƣ迎它!我也不相信我们中的Q何h会愿意与其他国家的h民或其他世代的h民易地而处。我们在q场努力中所倾注的精力、信念和奉献照耀我们的国家以及所有ؓ之献w的人,火焰所攑ְ出的光芒必将普照全世界?/p>

And so, my fellow Americans, ask not what your country can do for you; ask what you can do for your country.

所以,我的国同胞们,不要问你的国家ؓ你做了什么,而应问你能ؓ你的国家做些什么?/p>

My fellow citizens of the world, ask not what America will do for you, but what together we can do for the freedom of man.

我的世界同胞们,不要问美国将Z做些什么,而应问我们应该一起ؓ了全人类的自由做些什么?/p>

Finally, whether you are citizens of America or citizens of the world, ask of us here the same high standards of strength and sacrifice which we ask of you. With a good conscience our only sure reward, with history the final judge of our deeds, let us go forth to lead the land we love, asking His blessing and His help, but knowing that here on earth God's work must truly be our own.

最后,无论是美国公民还是世界其他国家的公民Q请用我们要求于你们的关于力量和牺牲的高标准来要求我们,本着我们唯一可以指望有所回报的善意良知,依着能最l裁x们功业的历史Q让我们着手领导我们所热爱的国Ӟ在祈求神的赐和的帮助的同Ӟ也能深切体认Q在q片土地上,的工作必定也是我们自己所应承担的使命?/p>

chenweicai 2007-06-30 11:18 发表评论
]]>
sessionhttp://www.tkk7.com/chenweicai/archive/2007/06/27/126667.htmlchenweicaichenweicaiWed, 27 Jun 2007 14:36:00 GMThttp://www.tkk7.com/chenweicai/archive/2007/06/27/126667.htmlhttp://www.tkk7.com/chenweicai/comments/126667.htmlhttp://www.tkk7.com/chenweicai/archive/2007/06/27/126667.html#Feedback0http://www.tkk7.com/chenweicai/comments/commentRss/126667.htmlhttp://www.tkk7.com/chenweicai/services/trackbacks/126667.html

摘要:

虽然session机制在web应用E序中被采用已经很长旉了,但是仍然有很多h不清楚session机制的本质,以至不能正确的应用这一技术。本文将详细讨论session的工作机制ƈ且对在Java web application中应用session机制时常见的问题作出解答?/div>
 
一、术语session
在我的经验里Qsessionq个词被滥用的程度大概仅ơ于transactionQ更加有的是transaction与session在某些语境下的含义是相同的?br>
sessionQ中文经常翻译ؓ会话Q其本来的含义是指有始有l的一pd动作/消息Q比如打电话时从拿v电话拨号到挂断电话这中间的一pdq程可以UCZ?session。有时候我们可以看到这L?#8220;在一个浏览器会话期间Q?..”Q这里的会话一词用的就是其本义Q是指从一个浏览器H口打开到关闭这个期?①。最混ؕ的是“用户Q客LQ在一ơ会话期?#8221;q样一句话Q它可能指用L一pd动作Q一般情况下是同某个具体目的相关的一pd动作Q比如从d到选购商品到结账登样一个网上购物的q程Q有时候也被称Z个transactionQ,然而有时候也可能仅仅是指一ơ连接,也有可能是指含义①,其中的差别只能靠上下文来推断②?br>
然而当session一词与|络协议相关联时Q它又往往隐含?#8220;面向q接”??#8220;保持状?#8221;q样两个含义Q?“面向q接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到Ҏ接了电话通信才能开始,与此相对的是写信Q在你把信发出去的时候你q不能确认对方的地址是否正确Q通信渠道不一定能建立Q但对发信h来说Q通信已经开始了?#8220;保持状?#8221;则是指通信的一方能够把一pd的消息关联v来,使得消息之间可以互相依赖Q比如一个服务员能够认出再次光的老顾客ƈ且记得上ơ这个顾客还Ơ店里一块钱。这一cȝ例子?#8220;一个TCP session”或?“一个POP3 session”③?br>
而到了web服务器蓬勃发展的时代Qsession在web开发语境下的语义又有了新的扩展Q它的含义是指一cȝ来在客户端与服务器之间保持状态的解决Ҏ④。有时候session也用来指q种解决Ҏ的存储结构,?#8220;把xxx保存在session ?#8221;⑤。由于各U用于web开发的语言在一定程度上都提供了对这U解x案的支持Q所以在某种特定语言的语境下Qsession也被用来指代该语a的解x案,比如l常把Java里提供的javax.servlet.http.HttpSessionUCؓsession⑥?br>
鉴于q种混ؕ已不可改变,本文中session一词的q用也会Ҏ上下文有不同的含义,请大家注意分辨?br>在本文中Q用中?#8220;览器会话期?#8221;来表辑֐义①Q?#8220;session机制”来表辑֐义④Q?#8220;session”表达含义⑤,使用具体?#8220;HttpSession”来表辑֐义⑥

二、HTTP协议与状态保?/strong>
HTTP 协议本n是无状态的Q这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器h下蝲某些文gQ无论是客户端还是服务器都没有必要纪录彼此过ȝ行ؓQ每一ơ请求之间都是独立的Q好比一个顾客和一个自动售货机或者一个普通的Q非会员Ӟ大卖Z间的关系一栗?br>
然而聪明(或者贪心?Q的Z很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用Q就像给有线电视加上Ҏ功能一栗这U需求一斚wqHTML逐步d了表单、脚本、DOM{客L行ؓQ另一斚w在服务器端则出现了CGI规范以响应客L的动态请求,作ؓ传输载体的HTTP协议也添加了文g上蝲?cookieq些Ҏ。其中cookie的作用就是ؓ了解决HTTP协议无状态的~陷所作出的努力。至于后来出现的session机制则是又一U在客户端与服务器之间保持状态的解决Ҏ?br>
让我们用几个例子来描qC下cookie和session机制之间的区别与联系。笔者曾l常ȝ一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠Q然而一ơ性消?杯咖啡的Z微乎其微Q这时就需要某U方式来U录某位֮的消Ҏ量。想象一下其实也无外乎下面的几种ҎQ?br>1、该店的店员很厉宻I能记住每位顾客的消费数量Q只要顾客一走进咖啡店,店员q道该怎么对待了。这U做法就是协议本w支持状态?br>2、发l顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每ơ消ҎQ如果顾客出C张卡片,则此ơ消费就会与以前或以后的消费相联pv来。这U做法就是在客户端保持状态?br>3、发l顾客一张会员卡Q除了卡号之外什么信息也不纪录,每次消费Ӟ如果֮出示该卡片,则店员在店里的纪录本上找到这个卡号对应的U录d一些消费信息。这U做法就是在服务器端保持状态?br>
׃HTTP协议是无状态的Q而出于种U考虑也不希望使之成ؓ有状态的Q因此,后面两种Ҏ成为现实的选择。具体来说cookie机制采用的是在客L保持状态的ҎQ而session机制采用的是在服务器端保持状态的Ҏ。同时我们也看到Q由于采用服务器端保持状态的Ҏ在客L也需要保存一个标识,所以session机制可能需要借助于cookie机制来达C存标识的目的Q但实际上它q有其他选择?br>
三、理解cookie机制
cookie机制的基本原理就如上面的例子一L单,但是q有几个问题需要解冻I“会员?#8221;如何分发Q?#8220;会员?#8221;的内容;以及客户如何使用“会员?#8221;?br>
正统的cookie分发是通过扩展HTTP协议来实现的Q服务器通过在HTTP的响应头中加上一行特D的指示以提C浏览器按照指示生成相应的cookie。然而纯_的客户端脚本如JavaScript或者VBScript也可以生成cookie?br>
而cookie 的用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器查所有存储的cookieQ如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置Q则把该cookie附在h资源的HTTPh头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示Q如果某家分店还发行了自q会员卡,那么q这家店的时候除了要出示麦当劳的会员卡,q要出示q家店的会员卡?br>
cookie的内容主要包括:名字Q|q期旉Q\径和域?br>其中域可以指定某一个域比如.google.comQ相当于d招牌Q比如宝z公司,也可以指定一个域下的具体某台机器比如www.google.com或者froogle.google.comQ可以用飘柔来做比?br>路径是跟在域名后面的URL路径Q比?或?foo{等Q可以用某飘柔专柜做比?br>路径与域合在一起就构成了cookie的作用范围?br>如果不设|过期时_则表C个cookie的生命期为浏览器会话期间Q只要关闭浏览器H口Qcookie消׃。这U生命期为浏览器会话期的 cookie被称Z话cookie。会话cookie一般不存储在硬盘上而是保存在内存里Q当然这U行为ƈ不是规范规定的。如果设|了q期旉Q浏览器׃把cookie保存到硬盘上Q关闭后再次打开览器,q些cookie仍然有效直到过讑֮的过期时间?br>
存储在硬盘上的cookie 可以在不同的览器进E间׃nQ比如两个IEH口。而对于保存在内存里的cookieQ不同的览器有不同的处理方式。对于IEQ在一个打开的窗口上?Ctrl-NQ或者从文g菜单Q打开的窗口可以与原窗口共享,而用其他方式新开的IEq程则不能共享已l打开的窗口的内存cookieQ对?Mozilla Firefox0.8Q所有的q程和标{N都可以共享同Lcookie。一般来说是用javascript的window.open打开的窗口会与原H口׃n内存cookie。浏览器对于会话cookie的这U只认cookie不认人的处理方式l常l采用session机制的web应用E序开发者造成很大的困扰?br>
下面是一个goolge讄cookie的响应头的例?br>
HTTP/1.1 302 Found
Location: http://www.google.com/intl/zh-CN/
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Content-Type: text/html


image
q是使用HTTPLookq个HTTP Sniffer软g来俘LHTTP通讯U录的一部分

image
览器在再次讉Kgoolge的资源时自动向外发送cookie

image
用Firefox可以很容易的观察现有的cookie的?br>使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理?br>
image
IE也可以设|在接受cookie前询?br>
四、理解session机制

session机制是一U服务器端的机制Q服务器使用一U类g散列表的l构Q也可能是使用散列表)来保存信息?br>
当程序需要ؓ某个客户端的h创徏一个session的时候,服务器首先检查这个客L的请求里是否已包含了一个session标识 - UCؓ session idQ如果已包含一个session id则说明以前已lؓ此客L创徏qsessionQ服务器按照session id把这?session索出来用(如果索不刎ͼ可能会新Z个)Q如果客Lh不包含session idQ则为此客户端创Z个sessionq且生成一个与此session相关联的session idQsession id的值应该是一个既不会重复Q又不容易被扑ֈ规律以仿造的字符Ԍq个 session id被在本ơ响应中q回l客L保存?br>
保存q个session id的方式可以采用cookieQ这样在交互q程中浏览器可以自动的按照规则把q个标识发挥l服务器。一般这个cookie的名字都是类gSEEESIONIDQ而。比如weblogic对于web应用E序生成的cookieQJSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764Q它的名字就?JSESSIONID?br>
׃cookie可以被h为的止Q必L其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一U技术叫做URL重写Q就是把session id直接附加在URL路径的后面,附加方式也有两种Q一U是作ؓURL路径的附加信息,表现形式为http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一U是作ؓ查询字符串附加在URL后面Q表现Ş式ؓhttp://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
q两U方式对于用h说是没有区别的,只是服务器在解析的时候处理的方式不同Q采用第一U方式也有利于把session id的信息和正常E序参数区分开来?br>Z在整个交互过E中始终保持状态,必d每个客户端可能请求的路径后面都包含这个session id?br>
另一U技术叫做表单隐藏字Dc就是服务器会自动修改表单,d一个隐藏字D,以便在表单提交时能够把session id传递回服务器。比如下面的表单
<form name="testform" action="/xxx">
<input type="text">
</form>


在被传递给客户端之前将被改写成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>


q种技术现在已较少应用Q笔者接触过的很古老的iPlanet6(SunONE应用服务器的前n)׃用了q种技术?br>实际上这U技术可以简单的用对action应用URL重写来代ѝ?br>
在谈论session机制的时候,常常听到q样一U误?#8220;只要关闭览器,session消׃”。其实可以想象一下会员卡的例子,除非֮d对店家提出销卡,否则店家l对不会L删除֮的资料。对session来说也是一LQ除非程序通知服务器删除一个sessionQ否则服务器会一直保留,E序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会d在关闭之前通知服务器它要关闭Q因此服务器Ҏ不会有机会知道浏览器已经关闭Q之所以会有这U错觉,是大部分session机制都用会话cookie来保存session idQ而关闭浏览器后这?session id消׃Q再ơ连接服务器时也无法找到原来的session。如果服务器讄的cookie被保存到盘上,或者用某U手D|写浏览器发出的HTTPh_把原来的session id发送给服务器,则再ơ打开览器仍然能够找到原来的session?br>
恰恰是由于关闭浏览器不会Dsession被删除,q服务器ؓseesion讄了一个失效时_当距dL上一ơ用session的时间超q这个失效时间时Q服务器可以认为客L已经停止了活动,才会把session删除以节省存储空间?br>
五、理解javax.servlet.http.HttpSession
HttpSession是Javaq_对session机制的实现规范,因ؓ它仅仅是个接口,具体到每个web应用服务器的提供商,除了对规范支持之外,仍然会有一些规范里没有规定的细微差异。这里我们以BEA的Weblogic Server8.1作ؓ例子来演C?br>
首先QWeblogic Server提供了一pd的参数来控制它的HttpSession的实玎ͼ包括使用cookie的开关选项Q用URL重写的开关选项Qsession持久化的讄Qsession失效旉的设|,以及针对cookie的各U设|,比如讄cookie的名字、\径、域Q?cookie的生存时间等?br>
一般情况下Qsession都是存储在内存里Q当服务器进E被停止或者重启的时候,内存里的session也会被清I,如果讄了session的持久化Ҏ,服务器就会把session保存到硬盘上Q当服务器进E重新启动或q些信息能够被再次使用Q?Weblogic Server支持的持久性方式包括文件、数据库、客Lcookie保存和复制?br>
复制严格说来不算持久化保存,因ؓsession实际上还是保存在内存里,不过同样的信息被复制到各个cluster内的服务器进E中Q这样即使某个服务器q程停止工作也仍然可以从其他q程中取得session?br>
cookie生存旉的设|则会媄响浏览器生成的cookie是否是一个会话cookie。默认是使用会话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解?br>
cookie的\径对于web应用E序来说是一个非帔R要的选项QWeblogic Server对这个选项的默认处理方式得它与其他服务器有明昄区别。后面我们会专题讨论?br>
关于session的设|参考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869

六、HttpSession常见问题
Q在本小节中session的含义ؓ⑤和⑥的混合Q?br>
1、session在何时被创徏
一个常见的误解是以为session在有客户端访问时p创徏Q然而事实是直到某server端程序调?HttpServletRequest.getSession(true)q样的语句时才被创徏Q注意如果JSP没有昄的?<% @page session="false"%> 关闭sessionQ则JSP文g在编译成Servlet时将会自动加上这样一条语?HttpSession session = HttpServletRequest.getSession(true);q也是JSP中隐含的 session对象的来历?br>
׃session会消耗内存资源,因此Q如果不打算使用sessionQ应该在所有的JSP中关闭它?br>
2、session何时被删?br>l合前面的讨论,session在下列情况下被删除a.E序调用HttpSession.invalidate();或b.距离上一ơ收到客L发送的session id旉间隔过了session的超时设|?或c.服务器进E被停止Q非持久sessionQ?br>
3、如何做到在览器关闭时删除session
严格的讲Q做不到q一炏V可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作,然后向服务器发送一个请求来删除session。但是对于浏览器崩溃或者强行杀死进E这些非常规手段仍然无能为力?br>
4、有个HttpSessionListener是怎么回事
你可以创Llistenerȝ控session的创建和销毁事Ӟ使得在发生这L事g时你可以做一些相应的工作。注意是session的创建和销毁动作触发listenerQ而不是相反。类似的与HttpSession有关的listenerq有 HttpSessionBindingListenerQHttpSessionActivationListener?HttpSessionAttributeListener?br>
5、存攑֜session中的对象必须是可序列化的?br>不是必需的。要求对象可序列化只是ؓ了session能够在集中被复制或者能够持久保存或者在必要时server能够暂时把session交换出内存。在 Weblogic Server的session中放|一个不可序列化的对象在控制C会收C个警告。我所用过的某个iPlanet版本如果 session中有不可序列化的对象Q在session销毁时会有一个ExceptionQ很奇怪?br>
6、如何才能正的应付客户端禁止cookie的可能?br>Ҏ有的URL使用URL重写Q包括超链接Qform的actionQ和重定向的URLQ具体做法参见[6]
http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770

7、开两个览器窗口访问应用程序会使用同一个sessionq是不同的session
参见W三节对cookie的讨论,对session来说是只认id不认人,因此不同的浏览器Q不同的H口打开方式以及不同的cookie存储方式都会对这个问题的{案有媄响?br>
8、如何防止用h开两个览器窗口操作导致的session混ؕ
q个问题与防止表单多ơ提交是cM的,可以通过讄客户端的令牌来解冟뀂就是在服务器每ơ生成一个不同的idq回l客LQ同时保存在session里,客户端提交表单时必须把这个id也返回服务器Q程序首先比较返回的id与保存在session里的值是否一_如果不一致则说明本次操作已经被提交过了。可以参看《J2EE核心模式》关于表C层模式的部分。需要注意的是对于用javascript window.open打开的窗口,一般不讄q个idQ或者用单独的idQ以防主H口无法操作Q徏议不要再window.open打开的窗口里做修Ҏ作,q样可以不用设|?br>
9、ؓ什么在Weblogic Server中改变session的值后要重新调用一ơsession.setValue
做这个动作主要是Z在集环境中提示Weblogic Server session中的值发生了改变Q需要向其他服务器进E复制新的session倹{?br>
10、ؓ什么session不见?br>排除session正常失效的因素之外,服务器本w的可能性应该是微乎其微的,虽然W者在iPlanet6SP1加若q补丁的Solaris版本上倒也遇到q;览器插件的可能性次之,W者也遇到q?721插g造成的问题;理论上防火墙或者代理服务器在cookie处理上也有可能会出现问题?br>出现q一问题的大部分原因都是E序的错误,最常见的就是在一个应用程序中去访问另外一个应用程序。我们在下一节讨个问题?br>
七、跨应用E序的session׃n

常常有这L情况Q一个大目被分割成若干项目开发,Z能够互不q扰Q要求每个小目作ؓ一个单独的web应用E序开发,可是C最后突然发现某几个项目之间需要共享一些信息,或者想使用session来实现SSO(single sign on)Q在session中保存login的用户信息,最自然的要求是应用E序间能够访问彼此的session?br>
然而按照Servlet规范Qsession的作用范围应该仅仅限于当前应用程序下Q不同的应用E序之间是不能够互相讉KҎ的session的。各个应用服务器从实际效果上都遵守了q一规范Q但是实现的l节却可能各有不同,因此解决跨应用程序session׃n的方法也各不相同?br>
首先来看一下Tomcat是如何实现web应用E序之间session的隔ȝQ从 Tomcat讄的cookie路径来看Q它对不同的应用E序讄的cookie路径是不同的Q这样不同的应用E序所用的session id是不同的Q因此即使在同一个浏览器H口里访问不同的应用E序Q发送给服务器的session id也可以是不同的?br>
image
image

Ҏq个Ҏ,我们可以推测Tomcat中session的内存结构大致如下?br>image

W者以前用q的iPlanet也采用的是同L方式Q估计SunONE与iPlanet之间不会有太大的差别。对于这U方式的服务器,解决的思\很简单,实际实行h也不难。要么让所有的应用E序׃n一个session idQ要么让应用E序能够获得其他应用E序的session id?br>
iPlanet中有一U很单的Ҏ来实现共享一个session idQ那是把各个应用程序的cookie路径都设?Q实际上应该?NASAppQ对于应用程序来讲它的作用相当于根)?br>
<session-info>
<path>/NASApp</path>
</session-info>


需要注意的是,操作׃n的session应该遵@一些编E约定,比如在session attribute名字的前面加上应用程序的前缀Q?setAttribute("name", "neo")变成setAttribute("app1.name", "neo")Q以防止命名I间冲突Q导致互相覆盖?br>
在Tomcat中则没有q么方便的选择。在Tomcat版本3上,我们q可以有一些手D|׃nsession。对于版?以上的TomcatQ目前笔者尚未发现简单的办法。只能借助于第三方的力量,比如使用文g、数据库、JMS或者客LcookieQURL参数或者隐藏字D늭手段?br>
我们再看一下Weblogic Server是如何处理session的?br>image
image

从截屏画面上可以看到Weblogic ServerҎ有的应用E序讄的cookie的\径都?Q这是不是意味着在Weblogic Server中默认的可以共享session了呢Q然而一个小实验卛_证明即不同的应用程序用的是同一个sessionQ各个应用程序仍然只能访问自己所讄的那些属性。这说明Weblogic Server中的session的内存结构可能如?br>image

对于q样一U结构,?session机制本n上来解决session׃n的问题应该是不可能的了。除了借助于第三方的力量,比如使用文g、数据库、JMS或者客L cookieQURL参数或者隐藏字D늭手段Q还有一U较为方便的做法Q就是把一个应用程序的session攑ֈServletContext中,q样另外一个应用程序就可以从ServletContext中取得前一个应用程序的引用。示例代码如下,

应用E序A
context.setAttribute("appA", session);


应用E序B
contextA = context.getContext("/appA");
HttpSession sessionA = (HttpSession)contextA.getAttribute("appA");


值得注意的是q种用法不可ULQ因为根据ServletContext的JavaDocQ应用服务器可以处于安全的原因对于context.getContext("/appA");q回I|以上做法在Weblogic Server 8.1中通过?br>
那么Weblogic ServerZ么要把所有的应用E序的cookie路径都设?呢?原来是ؓ了SSOQ凡是共享这个session的应用程序都可以׃n认证的信息。一个简单的实验可以证明这一点,修改首先d的那个应用程序的描述Wweblogic.xmlQ把cookie路径修改?appA 讉K另外一个应用程序会重新要求dQ即使是反过来,先访问cookie路径?的应用程序,再访问修改过路径的这个,虽然不再提示dQ但是登录的用户信息也会丢失。注意做q个实验时认证方式应该用FORMQ因为浏览器和web服务器对basic认证方式有其他的处理方式Q第二次h的认证不是通过 session来实现的。具体请参看[7] secion 14.8 AuthorizationQ你可以修改所附的CZE序来做q些试验?br>
八、ȝ
session机制本nq不复杂Q然而其实现和配|上的灵zL却使得具体情况复杂多变。这也要求我们不能把仅仅某一ơ的l验或者某一个浏览器Q服务器的经验当作普遍适用的经验,而是始终需要具体情况具体分析?br>摘要Q虽然session机制在web应用E序中被采用已经很长旉了,但是仍然有很多h不清楚session机制的本质,以至不能正确的应用这一技术。本文将详细讨论session的工作机制ƈ且对在Java web application中应用session机制时常见的问题作出解答?/div>

chenweicai 2007-06-27 22:36 发表评论
]]>counting 1 bits C implementationshttp://www.tkk7.com/chenweicai/archive/2007/06/27/126647.htmlchenweicaichenweicaiWed, 27 Jun 2007 10:30:00 GMThttp://www.tkk7.com/chenweicai/archive/2007/06/27/126647.htmlhttp://www.tkk7.com/chenweicai/comments/126647.htmlhttp://www.tkk7.com/chenweicai/archive/2007/06/27/126647.html#Feedback0http://www.tkk7.com/chenweicai/comments/commentRss/126647.htmlhttp://www.tkk7.com/chenweicai/services/trackbacks/126647.htmlcounting 1 bits C implementations

(idea) by bis (1.5 mon) (print)   ?   Thu Oct 18 2001 at 4:34:42

Here are C implementations of all the methods for counting 1 bits mentioned in that node. (Go read that first, if you haven't already.) All of the statistical information is purely anecdotal, but for what it's worth, it's based on my testing the code on a Pentium 3 and a Celeron 2, using the cl compiler of Microsoft Visual C++, and on a Sun Ultra 5, using gcc and Sun's own cc. For testing 64-bit code, I used __int64 on the Intel machines, and long long on the Sparc. It's worth noting that while Sun's compiler outputs faster executables than gcc, it doesn't change the relative performance of the different methods.

Table Lookup

Use a pre-built lookup table of all the 1-bit counts for every possibly byte, then index into that for each byte that comprises the word. This is the fastest method (slightly) for 32 bits on both Intel and Sparc, and (even more slightly) the fastest for 64 bits on Sparc, falling to second fastest on 64 bits on Intel. Changing the lookup table from anything but unsigned or int makes it a little slower (what with the extra casting and byte-loading the compiler is forced to add.)
unsigned numbits_lookup_table[256] = {
                0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
                3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
                3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
                4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
                3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
                6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
                4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
                6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
                3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
                4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
                6, 7, 6, 7, 7, 8
                };
                unsigned numbits_lookup(unsigned i)
                {
                unsigned n;
                n = numbits_lookup_table[i & 0xff];
                n += numbits_lookup_table[i>>8  & 0xff];
                n += numbits_lookup_table[i>>16 & 0xff];
                n += numbits_lookup_table[i>>24 & 0xff];
                return n;
                }
                

 

Counters

If you want a full explanation of how this works, read my writeup at counting 1 bits, but suffice it to say that you are essentially partitioning the word into groups, and combining the groups by adding them together in pairs until you are left with only one group, which is the answer. (performance notes in the next section.)
unsigned numbits(unsigned int i)
                {
                unsigned int const MASK1  = 0x55555555;
                unsigned int const MASK2  = 0x33333333;
                unsigned int const MASK4  = 0x0f0f0f0f;
                unsigned int const MASK8  = 0x00ff00ff;
                unsigned int const MASK16 = 0x0000ffff;
                i = (i&MASK1 ) + (i>>1 &MASK1 );
                i = (i&MASK2 ) + (i>>2 &MASK2 );
                i = (i&MASK4 ) + (i>>4 &MASK4 );
                i = (i&MASK8 ) + (i>>8 &MASK8 );
                i = (i&MASK16) + (i>>16&MASK16);
                return i;
                }
                

 

Optimized Counters

call pointed out in counting 1 bits that you could optimize the Counters method further if you pay attention to which bits you care about and which you don't, which allows you to skip applying some of the masks.

 

Some symbols that I'll use to represent what's going on:

  • 0: bits we know are zero from the previous step
  • o: bits we know are zero due to masking
  • -: bits we know are zero due to shifting
  • X: bits that might be 1 and we care about their values
  • x: bits that might be 1 but we don't care about their values

 

So a 0 plus a 0 is still a 0, obviously; the tricky ones are the others, but they're not even so bad. 0 plus X is X, since if the X is a 0 or a 1, added to 0 it will pass through unchanged. However, X plus X is XX, because the sum can range from 0 (0+0), to 10 (1+1). The same holds true with xs, once those show up.

Step 1:

        oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX
                +       -XoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX
                XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                
Step 2:
        ooXXooXXooXXooXXooXXooXXooXXooXX
                +       --XXooXXooXXooXXooXXooXXooXXooXX
                0XXX0XXX0XXX0XXX0XXX0XXX0XXX0XXX
                
Step 3:
        oooo0XXXoooo0XXXoooo0XXXoooo0XXX
                +       ----0XXXoooo0XXXoooo0XXXoooo0XXX
                0000XXXX0000XXXX0000XXXX0000XXXX
                
Step 4:
        oooooooo0000XXXXoooooooo0000XXXX
                +       --------0000XXXXoooooooo0000XXXX
                00000000000XXXXX00000000000XXXXX
                
Step 5:
        oooooooooooooooo00000000000XXXXX
                +       ----------------00000000000XXXXX
                00000000000000000000000000XXXXXX
                
You'll notice that the higher the step, the more known zeros (0) there are. call's suggestion was to change step 5 to this:

Step 5:
        ooooooooooooxxxx00000000000XXXXX
                +       ----------------00000000000XXXXX
                000000000000xxxx0000000000XXXXXX
                (mask)  ooooooooooooooooooooooooooXXXXXX
                
(where "(mask)" means "after adding, apply a mask".)

 

However, you can go back even further and apply the same technique - all the way to step 3, in fact. The best I can think to optimize this changes the last three steps into the following: Step 3:

        0xxx0XXX0xxx0XXX0xxx0XXX0xxx0XXX
                +       ----0XXX0xxx0XXX0xxx0XXX0xxx0XXX
                0xxxXXXX0xxxXXXX0xxxXXXX0xxxXXXX
                (mask)  0000XXXX0000XXXX0000XXXX0000XXXX
                
Step 4:
        0000xxxx0000XXXX0000xxxx0000XXXX
                +       --------0000XXXX0000xxxx0000XXXX
                0000xxxx000XXXXX000xxxxx000XXXXX
                
Step 5:
        0000xxxx000xxxxx000xxxxx000XXXXX
                +       ----------------000xxxxx000XXXXX
                0000xxxx000xxxxx00xxxxxx00XXXXXX
                (mask)  ooooooooooooooooooooooooooXXXXXX
                
Anyway, that's all very lovely, but here's the C to do it:
unsigned numbits(unsigned int i)
                {
                unsigned int const MASK1  = 0x55555555;
                unsigned int const MASK2  = 0x33333333;
                unsigned int const MASK4  = 0x0f0f0f0f;
                unsigned int const MASK6 = 0x0000003f;
                unsigned int const w = (v & MASK1) + ((v >> 1) & MASK1);
                unsigned int const x = (w & MASK2) + ((w >> 2) & MASK2);
                unsigned int const y = (x + (x >> 4) & MASK4);
                unsigned int const z = (y + (y >> 8));
                unsigned int const c = (z + (z >> 16)) & MASK6;
                return c;
                }
                
The performance on this method is marginally worse than the lookup method in the 32 bit cases, slightly better than lookup on 64 bit Intel, and right about the same on 64 bit Sparc. Of note is the fact that loading one of these bitmasks into a register actually takes two instructions on RISC machines, and a longer-than-32-bit instruction on the Intel, because it's impossible to pack an instruction and 32 bits worth of data into a single 32 bit instruction. See the bottom of jamesc's writeup at MIPS for more details on that...

 

Mind-bending "best" method (even more optimized counters)

A slightly-modified version of the code on this page: http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel, which in turn stole the code from the "Software Optimization Guide for AMD AthlonTM 64 and OpteronTM Processors":
unsigned numbits(unsigned int i)
                {
                unsigned int const MASK1 = 0x55555555;
                unsigned int const MASK2 = 0x33333333;
                unsigned int const MASK4 = 0x0f0f0f0f;
                unsigned int const w = v - ((v >> 1) & MASK1);
                unsigned int const x = (w & MASK2) + ((w >> 2) & MASK2);
                unsigned int const y = (x + (x >> 4) & MASK4);
                unsigned int const c = (y * 0x01010101) >> 24;
                return c;
                }
                
This method is identical to the "Optimized Counters" method, with two tricks applied:
  1. To get rid of an AND in the first line: instead of adding adjacent bits, it subtracts the high bit by itself of a pair of the bits from the pair together, because the results are the same. 00 - 0 = 0, 01 - 0 = 01, 10 - 1 = 01, 11 - 1 = 10
  2. To merge the last two lines into one, it uses a multiply and a shift, which adds the four remaining byte-sized "counters" together in one step.

 

Subtract 1 and AND

See counting 1 bits SPOILER for a fuller explanation of this one, but basically the lowest 1-bit gets zeroed out every iteration, so when you run out of 1s to zero, you've iterated to the number of bits in the word. Clever. Unfortunately, not that terribly fast; it's roughly two to three times slower than the lookup and counters methods on both architectures.
unsigned numbits_subtraction(unsigned i)
                {
                unsigned n;
                for(n=0; i; n++)
                i &= i-1;
                return n;
                }
                

 

Straightforwardly Examine Each Bit

The most easily understandable and slowest method: iterate over all the bits in the word; if the current bit is a 1, then increment the counter, otherwise, do nothing. That's actually done here by looking at the least-significant bit on each iteration, then shifting to the right one, and iterating until there are no more 1 bits in the word. There's a little optimization in the #ifndef here: instead of doing if (i & 1) n++;, which uses a branch instruction, just add the actual value of the least-significant bit to the counter ( n += (i & 1); ), as it will be a 1 when you want to add 1, and 0 when you don't. (We're just twiddling bits anyway, so why not?) This actually makes the processor do more adds, but adding is fast, and branching is slow, on modern processors, so it turns out to be about twice as fast. However, even "twice as fast" is still four to five times slower than the lookup method, again, on all architectures.
unsigned numbits(unsigned int i)
                {
                unsigned n;
                for(n=0; i; i >>= 1)
                #ifndef MORE_OPTIMAL
                if (i & 1) n++;
                #else
                n += (i & 1);
                #endif
                return n;
                }
                
Now, why does this all matter? It doesn't, really, but it was sure a good way to waste some time, and maybe someone learned some optimizing tricks from it... (Well, I did, actually - so I hope someone else did as well.)


chenweicai 2007-06-27 18:30 发表评论
]]>
W一个自定义标签的实?/title><link>http://www.tkk7.com/chenweicai/archive/2007/06/26/126405.html</link><dc:creator>chenweicai</dc:creator><author>chenweicai</author><pubDate>Tue, 26 Jun 2007 12:04:00 GMT</pubDate><guid>http://www.tkk7.com/chenweicai/archive/2007/06/26/126405.html</guid><wfw:comment>http://www.tkk7.com/chenweicai/comments/126405.html</wfw:comment><comments>http://www.tkk7.com/chenweicai/archive/2007/06/26/126405.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/chenweicai/comments/commentRss/126405.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/chenweicai/services/trackbacks/126405.html</trackback:ping><description><![CDATA[<p>步一Q定义标{?br><br>步二Q创建标{ֺ描述器TLD diagnostics.tld, 它攑֜WEB-INF目录下的tlds文g夹下Qdiagnostics.tld如下Q?br><br><?xml version="1.0"?><br><taglib><br> <tlibversion>1.0</tlibversion><br> <jspversion>1.1</jspversion><br> <shortname>diag</shortname><br> <tag><br>   <name>getWebServer</name><br>   <tagclass>servlet.GetWebServerTag</tagclass><br>   <bodycontent>empty</bodycontent><br> </tag><br></taglib><br><br>步三Q编写标{֤理器 GetServerTag.java<br><br>package servlet;</p> <p>import java.io.IOException;<br>import java.net.HttpURLConnection;<br>import java.net.URL;<br>import java.net.URLConnection;</p> <p>import javax.servlet.http.HttpServletRequest;<br>import javax.servlet.jsp.JspException;<br>import javax.servlet.jsp.JspWriter;<br>import javax.servlet.jsp.tagext.TagSupport;</p> <p>public class GetWebServerTag extends TagSupport {</p> <p> @Override<br> public int doStartTag() throws JspException {<br>  try{<br>   // get the request object from the page context<br>   HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();<br>   <br>   // Request information form the web server<br>   URL url = new URL("http", request.getServerName(), request.getServerPort(), "/");<br>   URLConnection con = url.openConnection();<br>   ((HttpURLConnection)con).setRequestMethod("OPTIONS");<br>   String webserver = con.getHeaderField("server");<br>   <br>   // write it to the output stream<br>   JspWriter out = pageContext.getOut();<br>   out.print(webserver);<br>  }catch (IOException e)<br>  {<br>   throw new JspException(e.getMessage());<br>  }<br>  <br>  return SKIP_BODY;<br> }<br> <br>}<br><br><br>步四Q?~写WEB.xml文g<br><br>加入Q?br><jsp-config><br><taglib><br><taglib-uri>diagnostics</taglib-uri><br><taglib-location>/WEB-INF/tlds/diagnostics.tld</taglib-location><br></taglib><br></jsp-config><br><br>步五Q编写jsp面Q将标签q入该JSP面<br><br><%@ taglib prefix="<span style="COLOR: red">diag</span>" uri="diagnostics"%><br>    <br><html><br><head><br><title>Basci Example of a Custom Tag</title><br></head><br><body><br><H3>Basci Example of a Custom Tag</H3><br> The web server is <<span style="COLOR: red">diag</span>:getWebServer/><br></body><br></html><br><br><br>OK  , so much so this ,<br><br><br>wish you success<br><br><注: 注意U色的地方要一致哦></p> <img src ="http://www.tkk7.com/chenweicai/aggbug/126405.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/chenweicai/" target="_blank">chenweicai</a> 2007-06-26 20:04 <a href="http://www.tkk7.com/chenweicai/archive/2007/06/26/126405.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jsp 自定义标{?/title><link>http://www.tkk7.com/chenweicai/archive/2007/06/26/126402.html</link><dc:creator>chenweicai</dc:creator><author>chenweicai</author><pubDate>Tue, 26 Jun 2007 11:19:00 GMT</pubDate><guid>http://www.tkk7.com/chenweicai/archive/2007/06/26/126402.html</guid><wfw:comment>http://www.tkk7.com/chenweicai/comments/126402.html</wfw:comment><comments>http://www.tkk7.com/chenweicai/archive/2007/06/26/126402.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/chenweicai/comments/commentRss/126402.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/chenweicai/services/trackbacks/126402.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>本教E目?/strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?1 (? )</nobr></font></td> </tr> </tbody> </table> <font size=+0><font face="Verdana, Arial, Helvetica" size=2>                                                                                        </font></font><font face="Verdana, Arial, Helvetica" size=2> <p>惌?JavaServer Pages QJSPQ?应用E序中添加自定义标签吗?本教E将为您展示如何用这些标{写类g JSP 技术自带操?—??<code><font face=Courier size=1>jsp:useBean</font></code>?code><font face=Courier size=1>jsp:getProperty</font></code> ?<code><font face=Courier size=1>jsp:forward</font></code> —?的自定义操作。介l如何用特定于自已的域的表示逻辑的自定义操作来扩?JSP 语法?</p> <p>?JSP 应用E序中添?<em>自定义标{?/em> 的能力可以您将工作重点攑ֈ以文档ؓ中心的开发方式上。可以 Java 代码不出现在 JSP 中Q从而ɘq些面更容易维护。(我从l验中学刎ͼ?JSP 中攑օq多?Java 代码Ӟ代码l护׃成ؓ可怕的dQ。本教程您可以立卛_发出自定义标{。了解了 JSP 自定义标{ּ发的好处后,您可能会对程序员没有更多C用它而感到意外?</p> <p>在本教程中,我将讨论使用自定义标{基本内容。将介绍如何用自定义标签创徏可重用的表示lgq免在 JSP 加?Java scriptlet?</p> <p>在本教程中,我们: </p> <ul> <li>定义一?JSP 自定义标{体pȝ构? <li>解释单标{? <li>定义嵌套标签? <li>?<code><font face=Courier size=1>BodyContent</font></code> 解释标签? <li>在标{中d属性? <li>在标{中d scriptlet 变量? <li>用自定义标签实现控制程? <li>?Struts 化标{N|Ӏ?</li> </ul> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>我要学习本教E吗Q?/strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?2 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p>如果发现自己?JSP 应用E序中加入了大量 Java scriptletQ那么本教程是为您准备的?阅读本教E后Q就会掌握将 Java 代码?JSP 面中清除出L需要的信息?</p> <p>本教E假定读者熟?Java q_、JavaServer Pages QJSPQ?技术、MVC 模式、Reflection API、Model 2Q最好还?Struts 框架。此外,要从本教E中得到最大的收获Q还需要很好的使用标签库的l验</p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>关于作?/strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?3 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p><a ><u><font color=#0000ff>Rick Hightower</font></u></a> 是一?J2EE 开发h员和NQ他热衷于?J2EE、Ant、Hibernate、Struts、IMB ?ETTK ?Xdoclet?Rick ?<a ><u><font color=#0000ff>Trivera Technologies</font></u></a> 的前?CTOQ这是一家全球培训、指导和咨询公司Q其重点是企业开发。他l常?IBM <em>developerWorks</em> 上发表文章,q编写了 10 多篇 <em>developerWorks</em> 教程Q内容从 EJB 技术到 Web 服务?XDoclet?Rick 不久前与别h共同开办了另一家名?<a ><u><font color=#0000ff>ArcMind</font></u></a> 的公司,它专门研I?agile ҎQ还从事 Struts/JavaServer Faces 开发、咨询和指导?</p> <p>在ؓ eBlox 工作ӞRick ?eBlox 组q在 1.0 版本之前已使用 Struts 为电子商务站ҎZ两个框架和一?ASP Q应用程序服务提供者)。这个框架目前正在ؓ 2000 多个在线商店店面提供支持?</p> <p>Rick 最q完成了一本名?<em>Professional Jakarta Struts</em> 的书。在周游全国?J2EE ?Struts 目提供咨询Q或者在大会上发表关?J2EE 和极端编E?Qextreme programingQ的讲演之余QRick 喜欢在通宵咖啡店喝咖啡Q写一些有?Struts、J2EE 和其他内容的文章Qƈ以第三hU描写他自己?/p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>标签处理E序</strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?1 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p>在创定义标签之前Q需要创Z?<em>标签处理E序</em>。标{֤理程序是一个执行自定义标签操作?Java 对象。在使用自定义标{时Q要导入一?<em>标签?/em> —?即一l标{?标签处理E序寏V通过?Web 部v描述W中声明库导入它Q然后用指o <code><font face=Courier size=1>taglib</font></code> 它导入 JSP c?</p> <p>如果 JSP 容器在{换时遇到了自定义标签Q那么它检?<em>标签库描q符Qtag library descriptorQ?/em> QTLDQ?文g以查询相应的标签处理E序。TLD 文g对于自定义标{֤理程序,像 Web 部v描述W对?servlet 一栗?</p> <p>在运行时QJSP 는成的 servlet 得到对应于这一面所使用的标{标签处理E序的一个实例。生成的 servlet 用传递给它的属性初始化标签处理E序?</p> <p>标签处理E序实现?<em>生存周期</em> Ҏ。生成的 servlet 用这些方法通知标签处理E序应当启动、停止或者重复自定义标签操作。生成的 servlet 调用q些生存周期Ҏ执行标签的功能?/p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>标签的类?/strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?2 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p>可以定义两种cd的标{: </p> <ul> <li><code><font face=Courier size=1>javax.servlet.jsp.tagext.Tag</font></code> <li><code><font face=Courier size=1>javax.servlet.jsp.tagext.BodyTag</font></code> </li> </ul> <p>?<em>正文</em> q行操作 —?卛_在开始和l束标签之间的内容进行操作的 —?标签必须实现 <code><font face=Courier size=1>BodyTag</font></code> 接口。在q个教程中,我们称q些标签?<em>正文标签</em>。我们将不对其正文操作的标签UCؓ <em>单标{?/em>。简单标{֏以实?<code><font face=Courier size=1>Tag</font></code> 接口Q尽不要求它们q样做。要C不对其正文操作的标签仍然 <em>?/em> 正文Q只不过Q它的标{֤理程序不能读取这个正文?/p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>单标{例子</strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?1 (? )</nobr></font></td> </tr> </tbody> </table> <font size=+0><font face="Verdana, Arial, Helvetica" size=2>                                                                                                   <a target=_blank><u><font color=#800080>上一?/font></u></a>      <a target=_blank><u><font color=#800080>下一?/font></u></a></font></font><br><br><font face="Verdana, Arial, Helvetica" size=2></p> <p>Struts 框架带有几个自定义标{ֺQ有?Struts 的更多信息的链接请参?<a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-7-2.html"><u><font color=#0000ff>参考资?/font></u></a> Q。这些库中的一个标{֏以创Z个支持改?URL 的链接ƈ?<code><font face=Courier size=1>jsessionid</font></code> Ҏ写的q接~码?</p> <p>不过有一个问题:如果希望传递一l请求参敎ͼ如查询字W串Q,也许必须为此创徏一?Java scriptlet。真是ؕQ下面的清单 Qsearch_results.japQ?展示了一?JSP ,它被q加入了q样一?scriptlet?</p> <pre><code style="FONT-SIZE: 12px"> <%@ taglib uri="struts-html" prefix="html" %> <jsp:useBean class="java.util.HashMap" id="deleteParams" /> <% deleteParams.put("id", cd.getId()); deleteParams.put("method","delete"); %> <!-- Pass the map named deleteParams to html:link to generate the request parameters--> <html:link action="/deleteCD" name="deleteParams">delete </html:link> </font></td> </code> </pre> <p>search_results.jsp 创徏一?hashmap q向q个 map 传递两个属性。在下面几小节,我们创Z个不?Java 代码完成q项工作的自定义标签。我们的标签定义如下的一?hashmapQ?</p> <pre><code style="FONT-SIZE: 12px"> <map:mapDefine id="deleteParams"> <map:mapEntry id="id" name="cd" property="id"/> <map:mapEntry id="method" value="delete"/> </map:mapDefine> <!-- Pass the map named deleteParams to html:link to generate the request parameters--> <html:link action="/deleteCD" name="deleteParams">delete </html:link> </font></td> </code> </pre> <p>q将使我们可以容易地创徏型 map?</p> <p>q个例子展C几个关键概念,包括使用嵌套标签和定?scriplet 变量。首先我解释这个标{是如何工作的。然后在以后的几节中建立q些概念Qƈ介绍如何~写q个标签的不同Ş式,使它们处理其正文q控制执行流E?</p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>构徏单标{步骤</strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?2 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p>让我们创Z个定义一?<code><font face=Courier size=1>HashMap</font></code> scriptlet 变量的标{。ؓ此,需要实现标{֤理程序接?Qjavax.servlet.jsp.tagext.TagQ。因此,我们要创建的W一个标{ְ是一个简单标{?</p> <p>q个标签实例化一?map。用这个标{开发h员可以指定要实例化的 map 的类?—?<code><font face=Courier size=1>HashMap</font></code>?code><font face=Courier size=1>TreeMap</font></code>?code><font face=Courier size=1>FastHashMap</font></code> 或?<code><font face=Courier size=1>FastTreeMap</font></code>?code><font face=Courier size=1>FastHashMap</font></code> ?<code><font face=Courier size=1>FastTreeMap</font></code> 来自 Jakarta Commons Collection library Q有关链接请参阅 <a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-7-2.html"><u><font color=#0000ff>参考资?/font></u></a>Q。开发h员还可以指定标签所在的范围 —?c请求、会话还是应用程序范围?</p> <p>要构个简单标{,我们需要完成以下步骤: </p> <ol> <li>创徏实现?<code><font face=Courier size=1>Tag</font></code> 接口Q准地说是 javax.servlet.jsp.tagext.TagQ的标签处理E序cR?br><br> <li>创徏一?TLD 文g?br><br> <li>在标{֤理程?Java cM创徏属性?<br><br> <li>?TLD 文g中定义与标签处理E序 Java cM定义的属性对应的属性?<br><br> <li>?TLD 文g中声?scriptlet 变量?br><br> <li>实现 <code><font face=Courier size=1>doStartTag()</font></code> Ҏ。在标签处理E序cMQ根据属性将D|到 scriptlet 变量中?br><br></li> </ol> <p>如果您像我一P可能会提前阅M的结,所以请查看 <a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-8-1.html"><u><font color=#0000ff>附录</font></u></a> 中标{֤理程序类的完整列表以了解q个q程是如何结束的?</p> <p>在下面几节中,我们分?<code><font face=Courier size=1>MapDefineTag</font></code> 的实玎ͼq分析如何到达这一步?/p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>W?1 步:创徏一个实C Tag 接口的标{֤理程?/strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?3 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p>Z~写标签处理E序Q必d?<code><font face=Courier size=1>Tag</font></code> 接口。如前所qͼq个接口用于不操U其标签正文的简单标{֤理程序。就?J2EE API 文档 Q有关链接请参阅 <a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-7-2.html"><u><font color=#0000ff>参考资?/font></u></a>Q所说的Q?code><font face=Courier size=1>Tag</font></code> 接口定义了标{֤理程序和 JSP 实现类之间的基本协议。它定义了在标签开始和l束时调用的生存周期和方法?</p> <p>标签处理E序接口有以下方法: </p> <p> <table border=1> <tbody> <tr> <th width=225>Ҏ</th> <th width=225>作用</th> </tr> <tr> <td width=225><code><font face=Courier size=1>int doStartTag() throws JspException</font></code> </td> <td width=225>处理开始标{?/td> </tr> <tr> <td width=225><code><font face=Courier size=1>int doEndTag() throws JspException</font></code> </td> <td width=225>处理l束标签</td> </tr> <tr> <td width=225><code><font face=Courier size=1>Tag getParent()</font></code>/<code><font face=Courier size=1>void setParent(Tag t)</font></code> </td> <td width=225>获得/讄标签的父标签</td> </tr> <tr> <td width=225><code><font face=Courier size=1>void setPageContext(PageContext pc)</font></code> </td> <td width=225><code><font face=Courier size=1>pageContext</font></code> 属性的 setter Ҏ</td> </tr> <tr> <td width=225><code><font face=Courier size=1>void release()</font></code> </td> <td width=225>释放获得的所有资?/td> </tr> </tbody> </table> </p> <p><strong>TagSupport</strong> </p> <p>现在Q不必直接实?<code><font face=Courier size=1>Tag</font></code> 接口Q相反,?map 定义的(map-definingQ标{ְl承 TagSupport cR这个类以有意义的默认方法实?<code><font face=Courier size=1>Tag</font></code> 接口Q因而开发自定义标签更容?Q有?TagSupport ?API 文档的链接请参阅 <a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-7-2.html"><u><font color=#0000ff>参考资?/font></u></a>Q?例如QTagSupport cd义了 <code><font face=Courier size=1>get</font></code>/<code><font face=Courier size=1>setParent()</font></code> ?<code><font face=Courier size=1>setPageContext()</font></code>Q这与所有标{֤理程序几乎相同?<code><font face=Courier size=1>get</font></code>/<code><font face=Courier size=1>setParent()</font></code> Ҏ允许标签嵌套。TagSupport c还定义了一个可以被子类使用?<code><font face=Courier size=1>pageContext</font></code> 实例变量 Q?code><font face=Courier size=1>protected PageContext pageContext</font></code>Q,q个变量是由 <code><font face=Courier size=1>setPageContext()</font></code> Ҏ讄的?</p> <p>在默认情况下QTagSupport 实现?<code><font face=Courier size=1>doStartTag()</font></code> 以它返?<code><font face=Courier size=1>SKIP_BODY</font></code> 帔RQ表C将不对标签正文q行判断?此外Q在默认情况下,<code><font face=Courier size=1>doEndTag()</font></code> Ҏq回 <code><font face=Courier size=1>EVAL_PAGE</font></code>Q它表示 JSP q行时引擎应当对面的其余部分进行判断?最后,TagSupport 实现?<code><font face=Courier size=1>release()</font></code>Q它讄 <code><font face=Courier size=1>pageContext</font></code> 及其父元素ؓ <code><font face=Courier size=1>null</font></code>?</p> <p>TagSupport c还实现?<code><font face=Courier size=1>IterationTag</font></code> 接口?<code><font face=Courier size=1>doAfterBody()</font></code>Q这样它p?<code><font face=Courier size=1>SKIP_BODY</font></code>?在后面讨行P代的标签时我对此加以更详细的解释(请参?<a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-6-1.html"><u><font color=#0000ff>用自定义标签控制程</font></u></a>Q?</p> <p>好了Q现在让我们通过l承 TagSupport 来实?<code><font face=Courier size=1>Tag</font></code> 接口Q?</p> <pre><code style="FONT-SIZE: 12px"> ... import javax.servlet.jsp.tagext.TagSupport; ... public class MapDefineTag extends TagSupport { ... </code> </pre> <p>我们已经定义了标{֤理程序,现在需要增加从处理E序?TLD 文g中的标签的映。我们将在下一节中对此进行处理。然后,完?<code><font face=Courier size=1>MapDefineTag</font></code> 中剩余的代码?</p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>W?2 步:创徏一?TLD 文g</strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?4 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p>TLD 文g对自定义标签处理E序的作用就?Web 部v描述W对 servlet 的作用?TLD 文g列出了从标签名到标签处理E序的映?q个文g中的大多数数据都是在 JSP {换时使用的?TLD 文g通常保存?Web 应用E序?<code><font face=Courier size=1>WEB-INF</font></code> 目录Qƈ?web.xml 文g中声明。它们一般用 <code><font face=Courier size=1>.tld</font></code> 扩展名结束?/p> <p>TLD 文g有一?<em>DQpreambleQ?/em>Q在q里标识 JSP 技术的版本和用的标签库。这个导a通常看v来像q样Q?</p> <pre><code style="FONT-SIZE: 12px"> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>map</short-name> </code> </pre> <p>让我们更详细地分析一下这些标{:</p> <ul> <li>TLD 文g的根元素?<code><font face=Courier size=1>taglib</font></code>?code><font face=Courier size=1>taglib</font></code> 描述了一?<em>标签?/em> —?即一l标{?标签处理E序寏V?<br><br> <li>因ؓ我们使用的是 JSP 版本 1.2Q所以在q个例子中需?<code><font face=Courier size=1>tlib-version</font></code> ?<code><font face=Courier size=1>short-name</font></code> 元素?br><br> <li><code><font face=Courier size=1>tlib-version</font></code> 元素对应于标{ֺ版本?<br><br> <li><code><font face=Courier size=1>jsp-version</font></code> 对应于标{ֺ所依赖?JSP 技术的版本?br><br> <li><code><font face=Courier size=1>short-name</font></code> 元素定义?IDE 和其他开发工具可以用的标签库的单名?br><br> <li><code><font face=Courier size=1>taglib</font></code> 元素包含许多 <code><font face=Courier size=1>tag</font></code> 元素Q标{ֺ中每一个标{有一?<code><font face=Courier size=1>tag</font></code> 元素?br><br></li> </ul> <p>因ؓ我们刚创Z自己的类Q所以我们将l箋往下进行,?TLD 文g中声明这个类Q如下所C: </p> <pre><code style="FONT-SIZE: 12px"> <taglib> <br>... <br><tag> <br><name>mapDefine</name> <br><tag-class>trivera.tags.map.MapDefineTag</tag-class><br> <body-content>JSP</body-content> <br>... </code> </pre> <p><code><font face=Courier size=1>tag</font></code> 元素用于自定义标签映射到它们的自定义标{֤理程序。上q清单中?<code><font face=Courier size=1>tag</font></code> 元素自定义标签 <code><font face=Courier size=1>mapDefine</font></code> 映射到处理程?<code><font face=Courier size=1>trivera.tags.map.MapDefineTag</font></code>?因此Q不论在 <code><font face=Courier size=1>mapDefine</font></code> 上运行的是什么{换引擎,都会调用 <code><font face=Courier size=1>trivera.tags.map.MapDefineTag</font></code>?/p> <p>已经?TLD 中定义了标签Q接下来要在标签处理E序cM定义q个标签的一些属性了?/p> </font><font size=+0><font face="Verdana, Arial, Helvetica" size=2> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>W?3 步:在标{֤理程?Java cM创徏属?/strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?5 (? )</nobr></font></td> </tr> </tbody> </table>                                                                                                                <a target=_blank set="yes"><u><font color=#800080>上一?/font></u></a>      <a href="http://http://hi.baidu.com/myloveral/blog/item/400e29db5dcd7b67d0164e93.html" target=_blank><u><font color=#0000ff>下一?/font></u></a><br><br><font face="Verdana, Arial, Helvetica" size=2> <p>我们希望?<code><font face=Courier size=1>mapDefine</font></code> 标签指定三个属性,如下所C: </p> <table border=1> <tbody> <tr> <th width=225>属性说?/th> </tr> <tr> <td width=225><code><font face=Courier size=1>id</font></code> </td> <td width=225>?scriptlet 变量的名字?/td> </tr> <tr> <td width=225><code><font face=Courier size=1>scope</font></code> </td> <td width=225>?scriptlet 变量所在的范围?</td> </tr> <tr> <td width=225><code><font face=Courier size=1>type</font></code> </td> <td width=225>?scriptlet 变量的类?Q?code><font face=Courier size=1>HashMap</font></code>?code><font face=Courier size=1>FastHashMap</font></code>?code><font face=Courier size=1>TreeMap</font></code> 或?<code><font face=Courier size=1>FastTreeMap</font></code>Q?如果 <code><font face=Courier size=1>type</font></code> 讄?<code><font face=Courier size=1>hash</font></code>Q那么就会创Z?<code><font face=Courier size=1>HashMap</font></code>。如?<code><font face=Courier size=1>type</font></code> 讄?<code><font face=Courier size=1>fasthash</font></code>Q那么将创徏 <code><font face=Courier size=1>FastHashMap</font></code>?</td> </tr> </tbody> </table> <p>?JSP 中使用q个标签Ӟ它看h像下面q样Q?</p> <pre><code style="FONT-SIZE: 12px"> <map:mapDefine id="editParams" scope="session" type="hash"> <br> ... <br> </map:mapDefine> </code> </pre> <p>q个标签在会话范围内创Z个名?<code><font face=Courier size=1>editParams</font></code> ?<code><font face=Courier size=1>HashMap</font></code>?</p> <p>Z在标{֤理程序中创徏属性,需要定义相应的 JavaBean 属性?因此Q每一个属性在标签处理E序中都有对应的 setter ҎQ如下所C: </p> <pre><code style="FONT-SIZE: 12px"> public class MapDefineTag extends TagSupport { <br>... <br>private String type = FASTTREE; <br>private String id;<br> private String scope; <br><br><br>public void setType(String string) <br>{ type = string; } <br><br>public void setId(String string)<br> { id = string; }<br> public void setScope(String string)<br> { scope = string; } </code> </pre> <p>转换引擎用编码的配置数据或者运行时表达式设|这个标{属性?我们在 <a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-3-6.html"><u><font color=#0000ff>W?4 步:?TLD 文g中定义属?/font></u></a> 中对此做更详l的讨论?/p> <p>?<a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-3-7.html"><u><font color=#0000ff>W?5 步:实现 doStartTag() Ҏ</font></u></a> 中,我们在标签处理E序?<code><font face=Courier size=1>doStartTag()</font></code> Ҏ中用这些属性?/p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>W?4 步:?TLD 文g中定义属?/strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?6 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p>?像上一节中所做的那样Q通过声明 JavaBean 属性定义自定义属性,然后?TLD 文g中声明这些属性?每一?JavaBean 属性都必须与相应的自定义标{ֱ性相匚w??TLD 中定义的属性必d?JavaBean 属性,不过却可以有与标{ֱ性不匚w?JavaBean 属性?</p> <p>下面?<code><font face=Courier size=1>MapDefineTag</font></code> 的属性声明: </p> <pre><code style="FONT-SIZE: 12px"> <tag> <name>mapDefine</name> <tag-class>trivera.tags.map.MapDefineTag</tag-class> <body-content>JSP</body-content> ... <attribute> <name>id</name> <required>true</required> <rtexprvalue>false</rtexprvalue> <description>The id attribute</description> </attribute> <attribute> <name>scope</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description>The scope attribute</description> </attribute> <attribute> <name>type</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description> Specifies the type of map valid values are fasttree, fasthash, hash, tree </description> </attribute> </tag> </code> </pre> <p><code><font face=Courier size=1>name</font></code> 元素指定属性的名字?code><font face=Courier size=1>required</font></code> 元素指定属性是否是必需的(默认值是 <code><font face=Courier size=1>false</font></code>Q?code><font face=Courier size=1>rtexprvalue</font></code> 元素表明属性是编码了转换时的D是允怋用运行时 scriptlet 表达式?</p> <p>CQ?code><font face=Courier size=1>MapDefineTag</font></code> cdMؓ前面描述的每一个属性定义一?JavaBean 属性,我们?<a href="file:///D:/Documents%20and%20Settings/Administrator/%E6%A1%8C%E9%9D%A2/j-customtags/j-customtags/j-customtags-3-5.html"><u><font color=#0000ff>W?3 步:在标{֤理程?Java cM创徏属?/font></u></a> 中完成这个Q务?/p> <p> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td width="90%"><font face="Verdana, Arial, Helvetica" size=4><strong>W?5 步:实现 doStartTag() Ҏ</strong></font></td> <td align=right width=200><font face="Verdana, Arial, Helvetica" size=1><nobr>W?7 (? )</nobr></font></td> </tr> </tbody> </table> <br><br></p> <p>标签开始时调用 <code><font face=Courier size=1>doStartTag()</font></code> Ҏ —?从开发h员的角度看,q是当引擎遇?<code><font face=Courier size=1><map:mapDefine></font></code> 时发生的。如?<code><font face=Courier size=1>doStartTag()</font></code> q回 <code><font face=Courier size=1>SKIP_BODY</font></code>Q那么将不处理标{正文?如果它返回一?<code><font face=Courier size=1>EVAL_BODY_INCLUDE</font></code>Q那么将处理正文?</p> <p><code><font face=Courier size=1>MapDefine</font></code> cȝ <code><font face=Courier size=1>doStartTag()</font></code> Ҏ完成以下工作Q?</p> <ul> <li>Ҏ <code><font face=Courier size=1>type</font></code> 属性确定要创徏?map 的属性? <li>Ҏ <code><font face=Courier size=1>scope</font></code> 属性确定新?map 对象攑֜什么范围内? <li>Ҏ <code><font face=Courier size=1>id</font></code> 属性确定新 map 对象要放入的范围的名字?</li> </ul> <p>让我们更详细地分析这个过E?code><font face=Courier size=1>MapDefine</font></code> cL?<code><font face=Courier size=1>type</font></code> 属性是讄?<code><font face=Courier size=1>FASTTREE</font></code>?code><font face=Courier size=1>HASH</font></code>?code><font face=Courier size=1>TREE</font></code> q是 <code><font face=Courier size=1>FASTHASH</font></code>。然后创建相应的 mapQ如下所C: </p> <pre><code style="FONT-SIZE: 12px"> /* String constants for the different types of maps we support */ public static final String FASTHASH = "FASTHASH"; public static final String FASTTREE = "FASTTREE"; public static final String HASH = "HASH"; public static final String TREE = "TREE"; /** The map we are going to create */ private Map map = null; /** The member variable that holds the type attribute */ private String type = FASTTREE; ... public int doStartTag() throws JspException { /** Based on the type attribute, determines which type of Map to create */ if (type.equalsIgnoreCase(FASTTREE)) { map = new FastTreeMap(); } else if (type.equalsIgnoreCase(HASH)) { map = new HashMap(); } else if (type.equalsIgnoreCase(TREE)) { map = new TreeMap(); } else if (type.equalsIgnoreCase(FASTHASH)) { map = new FastHashMap(); } </code> </pre> <p>然后Q用 <code><font face=Courier size=1>id</font></code> ?<code><font face=Courier size=1>scope</font></code> 属性将 hashmap 以一个给定的名字讄C个给定范围中Q?</p> <pre><code style="FONT-SIZE: 12px"> private String id; private String scope; public int doStartTag() throws JspException { ... if (scope == null){ pageContext.setAttribute(id, map); }else if("page".equalsIgnoreCase(scope)){ pageContext.setAttribute(id, map); }else if("request".equalsIgnoreCase(scope)){ pageContext.getRequest().setAttribute(id, map); }else if("session".equalsIgnoreCase(scope)){ pageContext.getSession().setAttribute(id, map); }else if("application".equalsIgnoreCase(scope)){ pageContext.getServletContext().setAttribute(id, map); } return EVAL_BODY_INCLUDE; } </code> </pre> <p>如果范围属性是 <code><font face=Courier size=1>null</font></code>Q那?map 放入页范围。否则,参数放入通过 <code><font face=Courier size=1>scope</font></code> 属性传递的范围名所对应的范围中?</p> <p>到目前ؓ止,我们已经有一个非常简单的标签Q它有三个属性:<code><font face=Courier size=1>id</font></code>?code><font face=Courier size=1>scope</font></code> ?<code><font face=Courier size=1>type</font></code>?我们用l定的名字将 map 攑ֈ一个范围中。但是,我们q有一件事没做Q就是声?scriptlet 变量?Z做到q一点,需要向 TLD 再添加一,q就是我们在下一节中所要做的事?/p> </font></font></font></font> <img src ="http://www.tkk7.com/chenweicai/aggbug/126402.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/chenweicai/" target="_blank">chenweicai</a> 2007-06-26 19:19 <a href="http://www.tkk7.com/chenweicai/archive/2007/06/26/126402.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>他山之石http://www.tkk7.com/chenweicai/archive/2007/04/28/114442.htmlchenweicaichenweicaiSat, 28 Apr 2007 14:55:00 GMThttp://www.tkk7.com/chenweicai/archive/2007/04/28/114442.htmlhttp://www.tkk7.com/chenweicai/comments/114442.htmlhttp://www.tkk7.com/chenweicai/archive/2007/04/28/114442.html#Feedback0http://www.tkk7.com/chenweicai/comments/commentRss/114442.htmlhttp://www.tkk7.com/chenweicai/services/trackbacks/114442.html最q因为比较闲Q而且有几个师弟来上v扑ַ作,交流后有Ҏ受,所以发了一个脓子.那是W一ơ在QSQN上发_最q几天又想了惻I所以再发一_可能也是最后一_我只谈谈我在上v做了Q年软g开发所了解到的一些东西,本h能力一般,所以我说的也只针对能力一般的人,特别厉害的牛Z需要理会我说的话.
希望能对有些人有一点帮助.
   对于快要毕业的大学生来上h工作Q我觉得最重要的是基础知识一定要好.我推荐看QAQӞ~程思想q本书,很多公司W试的JQ)Q方面的题目q本书.另外QSQͼQIIQԌQIQ_QDQE一定要有所了解Q这个能说明你在大学的时候实习过Q做q一些小目的.HIBERNATEQSQ_QTQIQIQԌQGq些东西我不推荐你去学习Q我觉得你应该学习如何处理异常,学会用JQQ访问数据库Q学会如何释放资源,如何控制数据库事务,学会如何写自定义标签Q这栯够显著的提高你的~程水^Q?br>   工作一q的后我觉得应该回过ȝ看大学的数据l构Q算法,操作pȝQ然后应该对面象对象要有更深ȝ理解Q设计模式也应该慢慢开始涉及到QJQ)Q变~程思想q本书徏议多看几ơ)Q我不徏议工作一q就开始换工作Q因为找工作要花旉Q新工作p适应新的框架和新的业务,q样你就会ؕ费很多时间的Q我q是不徏议你ȝHIBERNATEQSQ_QTQIQIQԌQGq样的东西,虽然你工作中可能要用到它Q对于英语我觉得应该早做准备Q强q自q一些英文方面的书籍Q提高自q口语水^Q另外我q要一点,适当的参加培训是很有必要的,上v有很多的外语培训机构Q主要是培训商务交流Q,效果很不错的Q不q也很贵的,所以去前一定要计划好,不要象大学那样交了钱不去上课或者不认真听课Q那样就最好先不要去.
   工作两年后,如果你算法,数据l构Q设计模式等{有比较q了解的时?br> 我觉得HIBERNATEQSQ_QTQIQIQԌQG的实现方法你应该能够很快理解Q?br> 我还是不推荐你学习这些,我推荐学习IQQ推荐书c精通IQQIQ QԌQAQ写的那本.p他说的这本书不是宣传QJQ,不是写关于IQ世界如何_ֽQ不是ؓ了消灭某个其他对手等{,学习q本书是希望你能构徏出健壮,安全Q可扩展的服务器部vQ他里面很多的概念你可能在工作中C刎ͼ但是不表CZ可以不需要理会,而应该去思考如果碰到这L问题我应该怎样解决Q然后可以去|上找资料解军_Q(q本书是写IQQ.Q的Q但是我q是推荐Q看完后你绝对不会觉得是p旉Q我也觉得没有做q项目也很难理解q本书的Q?br>   我觉得一个程序员要到一定档ơ,p是必ȝQ所以我觉得如果能有一个全英文的工作环境工作一D|间是很应该的Q现在基本上的技术规范全部是英文写的Q很多技术论文也是英文的Q如果英语不行,水^很难提高Q其实对于在上v工作三年的程序员基本上知道自己应该如何发展的Q?/p>

   再说说上PQ)Q程序员的大概工资吧Q一般应届毕业生QO左右Q三q工作经验5Q以上,Q年工作l验QO以上Q这个工资是指很多公司全部能够给出,而且也比较容易找到的Q对于很厉害的h肯定不合适.大公司和外企在我说的基础上乘Q.Q倍.Q其实上h软g开发大专就可以了,只不q要牺牲一部分利Q和需要更高的能力Q本U就一炚w题也没有Q?/p>

   对于从外地来上v扑ַ作的学生Q我做好长期打算Q毕竟找工作是需要开销的,上v的交通费用很高,而且是省不掉的.但是心态一定要摆正Q首先要有决心,工作一定可以找刎ͼ另外不要躁Q其实找工作应该是一个不D学习的q程Q?br>当你面试一家公司,那么W试的题目在你面试完后一定要花时间把你你不会的搞明白Q笔试十家后你会发现其实题目差不多的Q态度一定要谦虚Q待遇可以适当降低
但是不要低于Q.QOQ不q一般你转正都能要求到这个数目的Q只要你好好和老板谈)Q要怿工作可以扑ֈ也要做好长期打算Q就是万一短时间找不到工作的打,不要L退场,Z挺就q去了)Q经上要准备充I而且面试不要担心什么的Q上Y件公司多得很Q你今天面试不过Q三个月后这个公司可能又要你去面试的Q他不会记得你的Q在投简历的时候,单点的两就可以H出你在学校期间做过哪些目Q只要是软g工程师就可以投,最多ؕ费两늺Q不要做太好的简历,是ؕ贚wQ网上投历就应该全部投,最多是不要你去面试Q不会少什么的Q找工作能力是一斚wQ技巧也有的Q只有自己慢慢体会了Q?br>  再说说ؓ什么我不推荐学习HIBERNATEQSQ_QTQIQIQԌQGQ因为我一直就在用q个Q现在突然发现自己好象无法前q了Q所以现在又重新学习基础Q但是问题是我年龄大了,事情多了Q可以供学习的时间不多了Q所以我才极力推荐在工作的前三年一定要把基本功打扎实.现在有很多程序员会用HIBERNATEQSQ_QTQIQIQԌQG来写目Q可是确不会写一个JQQ连接,对JQ)Q的多线E一点不知道QSQRQӞQT不会的也很多Q这个是很不好的Q也是现在国内很多程序员的通病Qؓ什么很多h说程序员刎ͼQ就写不动代码,学不会新东西了,你基那么差还能学会就真的怪了Q?br>   不要把时间放到讨论IQ和SQͼQNQ哪个好哪个差上面,不过我还是們֐QJQ的Q很多h_IQ能实现的QIQԌQG也能实现Q好象有QJQ能实现的但QIQԌQG不能实现Q但是没有完全了解不敢说Q,但是Z么不xQIQԌQG能实现的NQJQ不能实玎ͼ实现ȝ一Ҏ什么关pdQ学习一个东西不是要看到它的优点Q而更应该看到它的~点Q呵呵,不要骂我Q我认ؓQIQ将成ؓ潮流Q把骂我的时间放C解SQA上.而且惛_大的外企Q那么社会招聘百分之八十会问QJQ的Q进d的外企有两个方式Q一个是C会招聘Q但是这个面试特别严|基础不好外语不好的基本上没有戏.Q社会招聘指招聘有工作经验的Q应届毕业生叫校园招聘)另外一个就是通过外包q去Q这栯去要求要低,但是你必Mؕ费几q_{机会直接进你外包出ȝ公司或者蟩巢到和他同一档次的外企.

   很多待遇不重要,重要的是学到东西Q这个是不对的.待遇是你价值的体现Q学东西׃ؓ了更好的待遇Q所以要工资的时候不要觉得不好意思,惌多少q接说出来Q只有生zL保障才能更好的学习,更好的工作.工资高,心情好Q做什么也快呀Q其实应该这么说Q能学到什么不重要Q重要的是工资要高.

   所谓程序员只能刎ͼQ岁的说法是明显不对的,E序员也不是一个蟩板,不要L惛_做系l分析,L理Q而应该扎扎实实的学习Q做E序员有什么不好,从程序员开始,往中E序员,高E序员,职深E序员,专家E序员一直走下去Q?/p>

   再次Q外语很重要Q请把它攑֜W一位置Q最q好象Y件行业也开始好转v来了Q对日的外包多不_Ƨ美的外包也多v来了Q而且外包的性质也发生变化,从最初的~码和测试发展到分析Q设计,~码Q测试全部外包了Q这样和做国内的目区别不大Q所以还是很有发展前景的Q?/p>

   好象q有很多惌的但是说不出来,发现在EQIQ上发脓很费旉Q所以这个也是我最后一ơ发_目马上开启了Q也没有旉来论坛了Q希望想来上发展的和在上v做JQ)Q的E序员全部能扑ֈ满意的工作,生活更开心点Q毕竟做E序q是很辛苦的Q以上只是个点,没有M强加lQ何h的意思.



chenweicai 2007-04-28 22:55 发表评论
]]>
JAVA面试大全http://www.tkk7.com/chenweicai/archive/2007/04/23/112997.htmlchenweicaichenweicaiMon, 23 Apr 2007 09:20:00 GMThttp://www.tkk7.com/chenweicai/archive/2007/04/23/112997.htmlhttp://www.tkk7.com/chenweicai/comments/112997.htmlhttp://www.tkk7.com/chenweicai/archive/2007/04/23/112997.html#Feedback0http://www.tkk7.com/chenweicai/comments/commentRss/112997.htmlhttp://www.tkk7.com/chenweicai/services/trackbacks/112997.html面向对象的特征有哪些斚w 
 
1. 抽象Q抽象就是忽略一个主题中与当前目标无关的那些斚wQ以便更充分地注意与当前目标有关的方面。抽象ƈ不打了解全部问题,而只是选择其中的一部分Q暂时不用部分细节。抽象包括两个方面,一是过E抽象,二是数据抽象?/p>

    l承Q承是一U联l类的层ơ模型,q且允许和鼓q的重用,它提供了一U明表q共性的Ҏ。对象的一个新cd以从现有的类中派生,q个q程UCؓcȝѝ新cȝ承了原始cȝҎ,新类UCؓ原始cȝzc(子类Q,而原始类UCؓ新类的基c(父类Q。派生类可以从它的基c那里承方法和实例变量Qƈ且类可以修改或增加新的方法之更适合Ҏ的需要?/p>

   装Q封装是把过E和数据包围hQ对数据的访问只能通过已定义的界面。面向对象计始于这个基本概念,即现实世界可以被描绘成一pd完全自治、封装的对象Q这些对象通过一个受保护的接口访问其他对象?/p>

   多态性:多态性是指允怸同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语ah灉|、抽象、行为共享、代码共享的优势Q很好的解决了应用程序函数同名问题?/p>

2、String是最基本的数据类型吗?
基本数据cd包括byte、int、char、long、float、double、boolean和short?br>java.lang.StringcLfinalcd的,因此不可以承这个类、不能修改这个类?span style="COLOR: red">Z提高效率节省I间Q我们应该用StringBuffercR?/span>

3、int ?Integer 有什么区?br>Java 提供两种不同的类型:引用cd和原始类型(或内|类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了装cR?br>原始cd装cboolean Boolean  char Character  byte Byte  short Short  int Integer  long Long  float Float  double Double
引用cd和原始类型的行ؓ完全不同Qƈ且它们具有不同的语义。引用类型和原始cdh不同的特征和用法Q它们包括:大小和速度问题Q这U类型以哪种cd的数据结构存储,当引用类型和原始cd用作某个cȝ实例数据时所指定的缺省倹{对象引用实例变量的~省gؓ nullQ而原始类型实例变量的~省g它们的类型有兟?/p>

4、String 和StringBuffer的区?br>JAVAq_提供了两个类QString和StringBufferQ它们可以储存和操作字符Ԍ卛_含多个字W的字符数据。这?span style="COLOR: red">StringcL供了数g可改变的字符?/span>。而这个StringBuffercL供的字符串进行修攏V?span style="COLOR: red">当你知道字符数据要改变的时候你可以用StringBuffer。典型地Q你可以使用StringBuffers来动态构造字W数据?/span>

5、运行时异常与一般异常有何异同?
异常表示E序q行q程中可能出现的非正常状态,q行时异常表C拟机的通常操作中可能遇到的异常Q是一U常见运行错误。java~译器要?span style="COLOR: red">Ҏ必须声明抛出可能发生的非q行时异常,但是q不要求必须声明抛出未被捕获的运行时异常?/span>

6、说出Servlet的生命周期,q说出Servlet和CGI的区别?br>Servlet被服务器实例化后Q容器运行其initҎQ请求到达时q行其serviceҎQserviceҎ自动zNq行与请求对应的doXXXҎQdoGetQdoPostQ等Q当服务器决定将实例销毁的时候调用其destroyҎ?br>与cgi的区别在于servlet处于服务器进E中Q?span style="COLOR: red">它通过多线E方式运行其serviceҎQ一个实例可以服务于多个hQƈ且其实例一般不会销毁,而CGIҎ个请求都产生新的q程Q服务完成后销毁,所以效率上低于servlet?/span>

7、说出ArrayList,Vector, LinkedList的存储性能和特?br>ArrayList和Vector都是使用数组方式存储数据Q此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素Q但是插入元素要涉及数组元素Ud{内存操作,所?span style="COLOR: red">索引数据快而插入数据慢Q?span style="COLOR: red">Vector׃使用了synchronizedҎQ线E安全)Q通常性能上较ArrayList?/span>Q而LinkedList使用双向链表实现存储Q按序号索引数据需要进行前向或后向遍历Q但是插入数据时只需要记录本的前后即可,所以插入速度较快?/p>

8、EJB是基于哪些技术实现的Qƈ说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别?br>    EJB包括Session Bean、Entity Bean、Message Driven BeanQ基?span style="COLOR: red">JNDI、RMI、JAT{技术实现?br>SessionBean在J2EE应用E序中被用来完成一些服务器端的业务操作Q例如访问数据库、调用其他EJBlg?/span>EntityBean被用来代表应用系l中用到的数据?/span>
对于客户机,SessionBean是一U非持久性对象,它实现某些在服务器上q行的业务逻辑?br>对于客户机,EntityBean是一U持久性对象,它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用E序实现的实体?br>Session Bean q可以再l分?Stateful Session Bean ?Stateless Session Bean Q这两种?Session Bean都可以将pȝ逻辑攑֜ method之中执行Q不同的?Stateful Session Bean 可以记录呼叫者的状态,因此通常来说Q一个用者会有一个相对应?Stateful Session Bean 的实体。Stateless Session Bean 虽然也是逻辑lgQ但是他却不负责记录使用者状态,也就是说当用者呼?Stateless Session Bean 的时候,EJB Container q不会找ȝ定的 Stateless Session Bean 的实体来执行q个 method。换a之,很可能数个用者在执行某个 Stateless Session Bean ?methods Ӟ会是同一?Bean ?Instance 在执行。从内存斚w来看Q?Stateful Session Bean ?Stateless Session Bean 比较Q?Stateful Session Bean 会消?J2EE Server 较多的内存,然?Stateful Session Bean 的优势却在于他可以维持用者的状态?/p>

9、Collection ?Collections的区别?Collection是集合类的上U接口,l承与他的接口主要有Set 和List.
Collections是针寚w合类的一个帮助类Q他提供一pd静态方法实现对各种集合的搜索、排序、线E安全化{操作?/span>

10?amp;?amp;&的区别?&是位q算W,表示按位与运,&&是逻辑q算W,表示逻辑与(andQ?/p>


11、HashMap和Hashtable的区别?nbsp; HashMap是Hashtable的轻量实现Q非U程安全
的实玎ͼQ他们都完成了Map接口Q主要区别在于HashMap允许I(nullQ键|keyQ?׃非线E安全,效率上可能高于Hashtable?br>
HashMap允许null作ؓ一个entry的key或者valueQ而Hashtable不允许?br>HashMap把Hashtable的containsҎL了,Ҏcontainsvalue?span style="COLOR: red">containsKey。因为containsҎҎ让h引v误解?Hashtablel承自Dictionaryc,而HashMap是Java1.2引进的Map interface的一个实现?br>最大的不同是,Hashtable的方法是Synchronize?/span>Q而HashMap不是Q在多个U程讉KHashtableӞ不需要自׃ؓ它的Ҏ实现同步Q?span style="COLOR: red">而HashMap 必Mؓ之提供外同步?
Hashtable和HashMap采用的hash/rehash法都大概一P所以性能不会有很大的差异?/p>

12、final, finally, finalize的区别?final 用于声明属性,Ҏ和类Q分别表C属性不可变Q方法不可覆盖,cM可ѝ?/span>finally是异常处理语句结构的一部分Q表CL执行?span style="COLOR: red">finalize是Objectcȝ一个方法,在垃圾收集器执行的时候会调用被回收对象的此方?/span>Q可以覆盖此Ҏ提供垃圾攉时的其他资源回收Q例如关闭文件等?/p>

13、sleep() ?wait() 有什么区? sleep是线E类QThreadQ的ҎQ导致此U程暂停执行指定旉Q?/span>执行机会给其他U程Q但是监控状态依然保持,到时后会自动恢复?span style="COLOR: red">调用sleep不会释放对象?/span>?span style="COLOR: red">wait是ObjectcȝҎQ对此对象调用waitҎD本线E放弃对象锁Q进入等待此对象的等待锁定池Q只有针Ҏ对象发出notifyҎQ或notifyAllQ后本线E才q入对象锁定池准备获得对象锁q入q行状态?/span>

14、Overload和Override的区别。Overloaded的方法是否可以改变返回值的cd?
Ҏ的重写Overriding和重载Overloading是Java多态性的不同表现?span style="COLOR: red">重写Overriding是父cM子类之间多态性的一U表玎ͼ重蝲Overloading是一个类中多态性的一U表?/span>。如果在子类中定义某Ҏ与其父类有相同的名称和参敎ͼ我们说该Ҏ被重?(Overriding)。子cȝ对象使用q个ҎӞ调用子cM的定义,对它而言Q父cM的定义如同被“屏蔽”了?span style="COLOR: red">如果在一个类中定义了多个同名的方法,它们或有不同的参C数或有不同的参数cdQ则UCؓҎ的重?Overloading)。Overloaded的方法是可以改变q回值的cd?/p>

15、error和exception有什么区?
error 表示恢复不是不可能但很困隄情况下的一U严重问题。比如说内存溢出。不可能指望E序能处理这L情况?br>exception 表示一U设计或实现问题。也是_它表C如果程序运行正常,从不会发生的情况?/p>

16、同步和异步有何异同Q在什么情况下分别使用他们QD例说明?br>如果数据在U程间共享。例如正在写的数据以后可能被另一个线E读刎ͼ或者正在读的数据可能已l被另一个线E写q了Q那么这些数据就是共享数据,必须q行同步存取?span style="COLOR: red">当应用程序在对象上调用了一个需要花费很长时间来执行的方法,q且不希望让E序{待Ҏ的返回时Q就应该使用异步~程Q在很多情况下采用异步途径往往更有效率?/p>

17、abstract class和interface有什么区?声明Ҏ的存在而不d现它的类被叫做抽象类Qabstract classQ,它用于要创徏一个体现某些基本行为的c,qؓ该类声明ҎQ但不能在该cM实现该类的情c?span style="COLOR: red">不能创徏abstract cȝ实例。然而可以创Z个变量,其类型是一个抽象类Qƈ让它指向具体子类的一个实例?/span>不能有抽象构造函数或抽象静态方法?span style="COLOR: red">Abstract cȝ子类为它们父cM的所有抽象方法提供实玎ͼ否则它们也是抽象c?/span>。取而代之,在子cM实现该方法。知道其行ؓ的其它类可以在类中实现这些方法。接口(interfaceQ是抽象cȝ变体?span style="COLOR: red">在接口中Q所有方法都是抽象的?span style="COLOR: red">多承性可通过实现q样的接口而获?/span>。接口中的所有方法都是抽象的Q没有一个有E序体?span style="COLOR: red">接口只可以定义static final成员变量。接口的实现与子cȝ|除了该实现类不能从接口定义中l承行ؓ。当cd现特D接口时Q它定义Q即程序体l予Q所有这U接口的Ҏ。然后,它可以在实现了该接口的类的Q何对象上调用接口的方法。由于有抽象c,它允怋用接口名作ؓ引用变量的类型。通常的动态联~将生效。引用可以{换到接口cd或从接口cd转换Qinstanceof q算W可以用来决定某对象的类是否实现了接口?/p>

18、heap和stack有什么区别?span style="COLOR: red">栈是一U线形集?/span>Q其d和删除元素的操作应在同一D完成。栈按照后进先出的方式进行处理?span style="COLOR: red">堆是栈的一个组成元?/span>

19、forward 和redirect的区别forward是服务器h资源Q服务器直接讉K目标地址的URLQ把那个URL的响应内容读取过来,然后把这些内容再发给览器,览器根本不知道服务器发送的内容是从哪儿来的Q所以它的地址栏中q是原来的地址?redirect是服务端根据逻辑,发送一个状态码,告诉览器重新去h那个地址Q一般来说浏览器会用刚才h的所有参数重新请求,所以session,request参数都可以获取?/p>

20、EJB与JAVA BEAN的区别?Java Bean 是可复用的组Ӟ对Java Beanq没有严格的规范Q理ZԌM一个Javac都可以是一个Bean?span style="COLOR: red">但通常情况下,׃Java Bean是被容器所创徏Q如TomcatQ的Q所以Java Bean应具有一个无参的构造器Q另外,通常Java Beanq要实现Serializable接口用于实现Bean的持久性?/span>Java Bean实际上相当于微YCOM模型中的本地q程内COMlgQ它是不能被跨进E访问的。Enterprise Java Bean 相当于DCOMQ即分布式组件。它是基于Java的远E方法调用(RMIQ技术的Q所以EJB可以被远E访问(跨进E、跨计算机)。但EJB必须被布|在诸如Webspere、WebLogicq样的容器中Q?span style="COLOR: red">EJB客户从不直接讉K真正的EJBlgQ而是通过其容器访问。EJB容器是EJBlg的代理,EJBlg由容器所创徏和管理。客户通过容器来访问真正的EJBlg?/span>

21、Static Nested Class ?Inner Class的不同?Static Nested Class是被声明为静态(staticQ的内部c,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部cd例化后才能实例化?/p>

22、JSP中动态INCLUDE与静态INCLUDE的区别?动态INCLUDE用jsp:include动作实现 <jsp:include page="included.jsp" flush="true" />它L会检查所含文件中的变化,适合用于包含动态页面,q且可以带参数。静态INCLUDE用include伪码实现,定不会检查所含文件的变化Q适用于包含静态页?lt;%@ include file="included.htm" %>

23、什么时候用assert?nbsp; assertion(断言)在Y件开发中是一U常用的调试方式Q很多开发语a中都支持q种机制?span style="COLOR: red">在实CQassertion是在程序中的一条语句,它对一个boolean表达式进行检查,一个正程序必M证这个boolean表达式的gؓtrueQ如果该gؓfalseQ说明程序已l处于不正确的状态下Q系l将l出警告或退出。一般来_assertion用于保证E序最基本、关键的正确性。assertion查通常在开发和试时开启。ؓ了提高性能Q在软g发布后,assertion查通常是关闭的?/p>

24、GC是什? Z么要有GC? GC是垃圾收集的意思(Gabage CollectionQ?内存处理是编Eh员容易出现问题的地方Q忘记或者错误的内存回收会导致程序或pȝ的不E_甚至崩溃Q?span style="COLOR: red">Java提供的GC功能可以自动监测对象是否过作用域从而达到自动回收内存的目的QJava语言没有提供释放已分配内存的昄操作Ҏ?

25、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? short s1 = 1; s1 = s1 + 1; Qs1+1q算l果是int型,需要强制{换类型)  short s1 = 1; s1 += 1;Q可以正编译)

26、Math.round(11.5){於多少? Math.round(-11.5){於多少?  Math.round(11.5)==12  Math.round(-11.5)==-11  roundҎq回与参数最接近的长整数Q?span style="COLOR: red">参数?/2后求其floor.

27、String s = new String("xyz");创徏了几个String Object?    两个

28、设?个线E,其中两个U程每次对j增加1Q另外两个线E对j每次减少1。写出程序?br>以下E序使用内部cd现线E,对j增减的时候没有考虑序问题?br>public class ThreadTest1{
   private int j;  
   public static void main(String args[])
      {  
         ThreadTest1 tt=new ThreadTest1();  
         Inc inc=tt.new Inc();
         Dec dec=tt.new Dec();  
         for(int i=0;i<2;i++){ 
                Thread t=new Thread(inc); 
                t.start(); 
                t=new Thread(dec); 
                t.start(); 
          } 
      }  
    private synchronized void inc(){ 
       j++; 
       System.out.println(Thread.currentThread().getName()+"-inc:"+j); 
    }

   private synchronized void dec(){
       j--;
       System.out.println(Thread.currentThread().getName()+"-dec:"+j); 
   }

class Inc implements Runnable{  
      public void run(){  
            for(int i=0;i<100;i++){  
                  inc(); 
             } 
      } 
 }
class Dec implements Runnable{
     public void run(){  
         for(int i=0;i<100;i++){
             dec(); 
          } 
     } 
  }

}

29、Java有没有goto?  java中的保留字,现在没有在java中用?/p>

30、启动一个线E是用run()q是start()?启动一个线E是调用start()ҎQɾU程所代表的虚拟处理机处于可运行状态,q意味着它可以由JVM调度q执行?span style="COLOR: red">qƈ不意味着U程׃立即q行。run()Ҏ可以产生必须退出的标志来停止一个线E?/p>

31、EJB包括QSessionBean,EntityBeanQ说Z们的生命周期Q及如何理事务的?
SessionBeanQ?span style="COLOR: red">Stateless Session Bean 的生命周期是由容器决定的Q当客户机发求要建立一个Bean的实例时QEJB容器不一定要创徏一个新的Bean的实例供客户用,而是随便找一个现有的实例提供l客h。当客户机第一ơ调用一个Stateful Session Bean Ӟ容器必须立即在服务器中创Z个新的Bean实例Qƈ兌到客h上,以后此客h调用Stateful Session Bean 的方法时容器会把调用分派C此客h相关联的Bean实例。EntityBeanQEntity Beans能存zȝ对较长的旉Qƈ且状态是持箋的?span style="COLOR: red">只要数据库中的数据存在,Entity beans׃直存z?/span>。而不是按照应用程序或者服务进E来说的?span style="COLOR: red">即EJB容器崩溃了,Entity beans也是存活?/span>。Entity Beans生命周期能够被容器或?Beans自己理。EJB通过以下技术管理实务:对象理l织QOMGQ的对象实务服务QOTSQ?/span>QSun Microsystems?span style="COLOR: red">Transaction ServiceQJTSQ?/span>?span style="COLOR: red">Java Transaction APIQJTAQ?/span>Q开发组QX/OpenQ的XA接口?/p>

32、应用服务器有那些?
BEA WebLogic ServerQIBM WebSphere Application ServerQOracle9i Application ServerQjBossQTomcat

33、给我一个你最常见到的runtime exception?br>ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException

34、接口是否可l承接口? 抽象cL否可实现(implements)接口? 抽象cL否可l承实体c?concrete class)?
接口可以l承接口。抽象类可以实现(implements)接口Q抽象类是否可承实体类Q但前提是实体类必须有明的构造函数?/p>

35、List, Set, Map是否l承自Collection接口?  ListQSet是,Map不是

36、说出数据连接池的工作机制是什?
J2EE服务器启动时会徏立一定数量的池连?/span>Qƈ一直维持不于此数目的池连接。客LE序需要连接时Q池驱动E序会返回一个未使用的池q接q将其表Cؓ忙。如果当前没有空闲连接,池驱动程序就新徏一定数量的q接Q新接的数量有配|参数决定。当使用的池q接调用完成后,池驱动程序将此连接表CؓI闲Q其他调用就可以使用q个q接?/p>

37、abstract的method是否可同时是static,是否可同时是nativeQ是否可同时是synchronized?  都不?/p>

38、数l有没有length()q个Ҏ? String有没有length()q个ҎQ数l没有length()q个ҎQ有length的属性。String有有length()q个Ҏ?/p>

39、Set里的元素是不能重复的Q那么用什么方法来区分重复与否? 是用==q是equals()? 它们有何区别?
Set里的元素是不能重复的Q那么用iterator()Ҏ来区分重复与否。equals()是判M个Set是否相等。equals()?=Ҏ军_引用值是否指向同一对象equals()在类中被覆盖Qؓ的是当两个分ȝ对象的内容和cd盔R的话Q返回真倹{?/p>

40、构造器Constructor是否可被override?构造器Constructor不能被承,因此不能重写OverridingQ但可以被重载Overloading?/span>

41、是否可以承Stringc?StringcLfinalcL不可以ѝ?/p>

42、swtich是否能作用在byte上,是否能作用在long上,是否能作用在String?switchQexpr1Q中Q?span style="COLOR: red">expr1是一个整数表辑ּ。因此传递给 switch ?case 语句的参数应该是 int?short?char 或?byte。long,string 都不能作用于swtich?/span>

43、try {}里有一个return语句Q那么紧跟在q个try后的finally {}里的code会不会被执行Q什么时候被执行Q在return前还是后?会执行,在return前执?/span>?/p>

44、编E题: 用最有效率的Ҏ出2乘以8{於? 2 << 3

45、两个对象值相?x.equals(y) == true)Q但却可有不同的hash codeQ这句话对不?不对Q有相同的hash code?/p>

46、当一个对象被当作参数传递到一个方法后Q此Ҏ可改变这个对象的属性,q可q回变化后的l果Q那么这里到底是g递还是引用传? 是g递?span style="COLOR: red">Java ~程语言只有g递参?/span>。当一个对象实例作Z个参数被传递到Ҏ中时Q参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变Q但对象的引用是永远不会改变的?/p>

47、当一个线E进入一个对象的一个synchronizedҎ后,其它U程是否可进入此对象的其它方?
不能Q一个对象的一个synchronizedҎ只能׃个线E访问?/p>

48、编E题: 写一个Singleton出来?br>Singleton模式主要作用是保证在Java应用E序中,一个类Class只有一个实例存在。一般Singleton模式通常有几U种形式:W一UŞ? 定义一个类Q它的构造函Cؓprivate的,它有一个static的private的该cd量,在类初始化时实例话,通过一个public的getInstanceҎ获取对它的引?l而调用其中的Ҏ。public class Singleton {private Singleton(){} private static Singleton instance = new Singleton();  public static Singleton getInstance() {  return instance;   }  }  W二UŞ? public class Singleton {  private static Singleton instance = null;  public static synchronized Singleton getInstance() { if (instance==null) instanceQnew Singleton();
return instance;   } }   其他形式:  定义一个类Q它的构造函Cؓprivate的,所有方法ؓstatic的。一般认为第一UŞ式要更加安全?

49、Java的接口和C++的虚cȝ相同和不同处?br>׃Java不支持多l承Q而有可能某个cL对象要用分别在几个cL对象里面的方法或属性,现有的单l承机制׃能满求。与l承相比Q接口有更高的灵zL,因ؓ接口中没有Q何实C码。当一个类实现了接口以后,该类要实现接口里面所有的Ҏ和属性,q且接口里面的属性在默认状态下面都是public static,所有方法默认情况下是public.一个类可以实现多个接口?/p>

50、Java中的异常处理机制的简单原理和应用?br>当JAVAE序q反了JAVA的语义规则时QJAVA虚拟机就会将发生的错误表CZؓ一个异常。违反语义规则包?U情c一U是JAVAcd内置的语义检查。例如数l下标越?会引发IndexOutOfBoundsException;讉Knull的对象时会引发NullPointerException。另一U情况就是JAVA允许E序员扩展这U语义检查,E序员可以创q异常Qƈ自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子cR?/p>

51、垃圑֛收的优点和原理。ƈ考虑2U回收机制?br>Java语言中一个显著的特点是引入了垃圑֛收机Ӟ使c++E序员最头疼的内存管理的问题q刃而解Q它使得JavaE序员在~写E序的时候不再需要考虑内存理。由于有个垃圑֛收机ӞJava中的对象不再?#8220;作用?#8221;的概念,只有对象的引用才?#8220;作用?#8221;。垃圑֛收可以有效的防止内存泄露Q有效的使用可以使用的内存?span style="COLOR: red">垃圾回收器通常是作Z个单独的低别的U程q行Q不可预知的情况下对内存堆中已经M的或者长旉没有使用的对象进行清楚和回收Q程序员不能实时的调用垃圑֛收器Ҏ个对象或所有对象进行垃圑֛收。回收机制有分代复制垃圾回收和标记垃圑֛Ӟ增量垃圾回收

52、请说出你所知道的线E同步的Ҏ?br>wait():使一个线E处于等待状态,q且释放所持有的对象的lock。sleep():使一个正在运行的U程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。notify():唤醒一个处于等待状态的U程Q注意的是在调用此方法的时候,q不能确切的唤醒某一个等待状态的U程Q而是由JVM定唤醒哪个U程Q而且不是按优先。Allnotity():唤醒所有处入等待状态的U程Q注意ƈ不是l所有唤醒线E一个对象的锁,而是让它们竞争?/p>

53、你所知道的集合类都有哪些Q主要方法?最常用的集合类?List ?Map?List 的具体实现包?ArrayList ?VectorQ它们是可变大小的列表,比较适合构徏、存储和操作Mcd对象的元素列表?List 适用于按数值烦引访问元素的情Ş?Map 提供了一个更通用的元素存储方法?Map 集合cȝ于存储元素对Q称?#8220;?#8221;?#8220;?#8221;Q,其中每个键映到一个倹{?/p>

54、描qC下JVM加蝲class文g的原理机?JVM中类的装载是由ClassLoader和它的子cL实现?Java ClassLoader 是一个重要的Javaq行时系l组件。它负责在运行时查找和装入类文g的类?/p>

55、char型变量中能不能存贮一个中文汉?Z?
能够定义成ؓ一个中文的Q因为java中以unicode~码Q一个char?6个字节,所以放一个中文是没问题的

56、多U程有几U实现方?都是什?同步有几U实现方?都是什?
多线E有两种实现ҎQ分别是l承ThreadcM实现Runnable接口 ,同步的实现方面有两种Q分别是synchronized,wait与notify

57、JSP的内|对象及Ҏ?br>request表示HttpServletRequest对象。它包含了有x览器h的信息,q且提供了几个用于获取cookie, header, 和session数据的有用的Ҏ,response表示HttpServletResponse对象Qƈ提供了几个用于设|送回 览器的响应的方法(如cookies,头信息等Q?
out对象是javax.jsp.JspWriter的一个实例,q提供了几个Ҏ使你能用于向览器回送输出结果?pageContext表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各U范围的名字I间、servlet相关的对象的APIQƈ且包装了通用的servlet相关功能的方法?nbsp; session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信?nbsp; applicaton 表示一个javax.servle.ServletContext对象。这有助于查找有关servlet引擎和servlet环境的信?nbsp; config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数?nbsp; page表示从该面产生的一个servlet实例

58、线E的基本概念、线E的基本状态以及状态之间的关系U程指在E序执行q程中,能够执行E序代码的一个执行单位,每个E序臛_都有一个线E,也就是程序本w。Java中的U程有四U状态分别是Q运行、就l、挂赗结束?

59、JSP的常用指?lt;%@page language=”java” contenType=”text/html;charset=gb2312” session=”true” buffer=”64kb” autoFlush=”true” isThreadSafe=”true” info=”text” errorPage=”error.jsp” isErrorPage=”true” isELIgnored=”true” pageEncoding=”gb2312” import=”java.sql.*”%>isErrorPage(是否能用Exception对象)QisELIgnored(是否忽略表达? <%@include file=”filename”%><%@taglib prefix=”c”uri=”http://……”%>

60、什么情况下调用doGet()和doPost()QJsp面中的form标签里的method属性ؓget时调用doGet()Qؓpost时调用doPost()?/p>

61、servlet的生命周期web容器加蝲servletQ生命周期开始。通过调用servlet的init()Ҏq行servlet的初始化。通过调用service()Ҏ实现Q根据请求的不同调用不同的do***()Ҏ。结束服务,web容器调用servlet的destroy()Ҏ?/p>

62、如何现实servlet的单U程模式  <%@ page isThreadSafe=”false”%>

63、页面间对象传递的Ҏ  requestQsessionQapplicationQcookie{?/p>

64、JSP和Servlet有哪些相同点和不同点Q他们之间的联系是什么?
JSP是Servlet技术的扩展Q本质上是Servlet的简易方式,更强调应用的外表表达。JSP~译后是"cservlet"。Servlet和JSP最主要的不同点在于QServlet的应用逻辑是在Java文g中,q且完全从表C层中的HTML里分d来。而JSP的情冉|Java和HTML可以l合成一个扩展名?jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑?/p>

65、四U会话跟t技?cookie,url重写,session,隐藏?/p>

65,jsp的四U范?br>page否是代表与一个页面相关的对象和属性。一个页面由一个编译好?Java servlet c(可以带有M?include 指oQ但是没?include 动作Q表C。这既包?servlet 又包括被~译?servlet ?JSP 面
request是是代表?Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨多个页面,涉及多个 Web lgQ由?forward 指o?include 动作的关p)
session是是代表与用于某?Web 客户机的一个用户体验相关的对象和属性。一?Web 会话可以也经怼跨越多个客户?br>application是是代表与整?Web 应用E序相关的对象和属性。这实质上是跨越整个 Web 应用E序Q包括多个页面、请求和会话的一个全局作用?/p>

66、Request对象的主要方法:
setAttribute(String name,Object)Q设|名字ؓname的request的参数?br>getAttribute(String name)Q返回由name指定的属性?br>getAttributeNames()Q返回request对象所有属性的名字集合Q结果是一个枚丄实例
getCookies()Q返回客L的所有Cookie对象Q结果是一个Cookie数组
getCharacterEncoding()Q返回请求中的字W编码方?br>getContentLength()Q返回请求的Body的长?br>getHeader(String name)Q获得HTTP协议定义的文件头信息
getHeaders(String name)Q返回指定名字的request Header的所有|l果是一个枚丄实例
getHeaderNames()Q返回所以request Header的名字,l果是一个枚丄实例
getInputStream()Q返回请求的输入,用于获得h中的数据
getMethod()Q获得客L向服务器端传送数据的Ҏ
getParameter(String name)Q获得客L传送给服务器端的有name指定的参数?br>getParameterNames()Q获得客L传送给服务器端的所有参数的名字Q结果是一个枚丄实例
getParameterValues(String name)Q获得有name指定的参数的所有?br>getProtocol()Q获取客L向服务器端传送数据所依据的协议名U?br>getQueryString()Q获得查询字W串
getRequestURI()Q获取发求字W串的客L地址
getRemoteAddr()Q获取客L的IP地址
getRemoteHost()Q获取客L的名?br>getSession([Boolean create])Q返回和h相关Session
getServerName()Q获取服务器的名?br>getServletPath()Q获取客L所h的脚本文件的路径
getServerPort()Q获取服务器的端口号
removeAttribute(String name)Q删除请求中的一个属?/p>

67、J2EE是技术还是^台还是框ӞJ2EE本n是一个标准,一个ؓ企业分布式应用的开发提供的标准q_?br>J2EE也是一个框Ӟ包括JDBC、JNDI、RMI、JMS、EJB、JTA{技术?/p>

68、我们在web应用开发过E中l常遇到输出某种~码的字W,如iso8859-1{,如何输出一个某U编码的字符Ԍ
  Public String translate (String str) {  String tempStr = "";  try { tempStr = new String(str.getBytes("ISO-8859-1"), "GBK"); tempStr = tempStr.trim(); } catch (Exception e) {  System.err.println(e.getMessage());  } return tempStr;  }

69、简q逻辑操作(&,|,^)与条件操?&&,||)的区别。区别主要答两点Qa.条g操作只能操作布尔型的,而逻辑操作不仅可以操作布尔?而且可以操作数值型b.逻辑操作不会产生短\

70、XML文档定义有几UŞ式?它们之间有何本质区别Q解析XML文档有哪几种方式Q?
a: 两种形式 dtd  schemaQb: 本质区别:schema本n是xml的,可以被XML解析器解?q也是从DTD上发展schema的根本目?Qc:有DOM,SAX,STAX{?nbsp; DOM:处理大型文g时其性能下降的非常厉実뀂这个问题是由DOM的树l构所造成的,q种l构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随?nbsp; SAX:不现于DOM,SAX是事仉动型的XML解析方式。它序dXML文gQ不需要一ơ全部装载整个文件。当遇到像文件开_文档l束Q或者标{ּ头与标签l束Ӟ它会触发一个事Ӟ用户通过在其回调事g中写入处理代码来处理XML文gQ适合对XML的顺序访?STAX:Streaming API for XML (StAX)

71、简qsynchronized和java.util.concurrent.locks.Lock的异?Q?br>主要相同点:Lock能完成synchronized所实现的所有功能主要不同点QLock有比synchronized更精的U程语义和更好的性能。synchronized会自动释NQ而Lock一定要求程序员手工释放Qƈ且必dfinally从句中释放?/p>

72、EJB的角色和三个对象
一个完整的ZEJB的分布式计算l构由六个角色组成,q六个角色可以由不同的开发商提供Q每个角色所作的工作必须遵@Sun公司提供的EJB规范Q以保证彼此之间的兼Ҏ。这六个角色分别是EJBlg开发者(Enterprise Bean ProviderQ?、应用组合者(Application AssemblerQ、部|者(DeployerQ、EJB 服务器提供者(EJB Server ProviderQ、EJB 容器提供者(EJB Container ProviderQ、系l管理员QSystem AdministratorQ三个对象是RemoteQLocalQ接口、HomeQLocalHomeQ接口,Beanc?/p>

73、EJB容器提供的服务主要提供声明周期管理、代码生、持l性管理、安全、事务管理、锁和ƈ发行理{服务?/p>

74、EJB规范规定EJB中禁止的操作有哪些? 1.不能操作U程和线EAPI(U程API指非U程对象的方法如notify,wait{?Q?.不能操作awtQ?.不能实现服务器功能,4.不能寚w态属生存取,5.不能使用IO操作直接存取文gpȝQ?.不能加蝲本地?Q?.不能this作ؓ变量和返回,8.不能循环调用?/p>

75、remote接口和home接口主要作用remote接口定义了业务方法,用于EJB客户端调用业务方法。home接口是EJB工厂用于创徏和移除查找EJB实例

76、bean 实例的生命周期对于Stateless Session Bean、Entity Bean、Message Driven Bean一般存在缓冲池理Q而对于Entity Bean和Statefull Session Bean存在Cache理Q通常包含创徏实例Q设|上下文、创建EJB ObjectQcreateQ、业务方法调用、remove{过E,对于存在~冲池管理的BeanQ在create之后实例q不从内存清除,而是采用~冲池调度机制不断重用实例,而对于存在Cache理的Bean则通过ȀzdLzL制保持Bean的状态ƈ限制内存中实例数量?/p>

77、EJB的激zL?以Stateful Session Bean ZQ其Cache大小军_了内存中可以同时存在的Bean实例的数量,ҎMRU或NRU法Q实例在ȀzdLzȝ态之间迁U,ȀzL制是当客L调用某个EJB实例业务ҎӞ如果对应EJB Object发现自己没有l定对应的Bean实例则从其去ȀzBean存储中(通过序列化机制存储实例)回复Q激z)此实例。状态变q前会调用对应的ejbActive和ejbPassivateҎ?/p>

78、EJB的几U类型会话(SessionQBean Q实体(EntityQBean 消息驱动的(Message DrivenQBean  Q会话Bean又可分ؓ有状态(StatefulQ和无状态(StatelessQ两U;实体Bean可分为Bean理的持l性(BMPQ和容器理的持l性(CMPQ两U?/p>

79、客服端调用EJB对象的几个基本步骤设|JNDI服务工厂以及JNDI服务地址pȝ属性,查找Home接口Q从Home接口调用CreateҎ创徏Remote接口Q通过Remote接口调用其业务方法?/p>

80、如何给weblogic指定大小的内? 在启动Weblogic的脚本中Q位于所在Domian对应服务器目录下的startServerNameQ,增加set MEM_ARGS=-Xms32m -Xmx200mQ可以调整最内存ؓ32MQ最?00M

81、如何设定的weblogic的热启动模式(开发模?与品发布模?可以在管理控制台中修改对应服务器的启动模式ؓ开发或产品模式之一。或者修Ҏ务的启动文g或者commenv文gQ增加set PRODUCTION_MODE=true?/p>

82、如何启动时不需输入用户名与密码?修改服务启动文gQ增?WLS_USER和WLS_PWV也可以在boot.properties文g中增加加密过的用户名和密?

83、在weblogic理制台中对一个应用域(或者说是一个网?Domain)q行jms及ejb或连接池{相关信息进行配|后,实际保存在什么文件中?保存在此Domain的config.xml文g中,它是服务器的核心配置文g?/p>

84、说说weblogic中一个Domain的缺省目录结?比如要将一个简单的helloWorld.jsp攑օ何目录下,然的在浏览器上就可打入http://L:端口?/helloword.jsp可以看到运行结果了? 又比如这其中用到了一个自己写的javaBean该如何办?
Domain目录\服务器目录\applicationsQ将应用目录攑֜此目录下可以作为应用访问,如果是Web应用Q应用目录需要满Web应用目录要求Qjsp文g可以直接攑֜应用目录中,Javabean需要放在应用目录的WEB-INF目录的classes目录中,讄服务器的~省应用可以实现在览器上无需输入应用名?/p>

85、在weblogic中发布ejb需涉及到哪些配|文件不同类型的EJB涉及的配|文件不同,都涉及到的配|文件包括ejb-jar.xml,weblogic-ejb-jar.xmlCMP实体Bean一般还需要weblogic-cmp-rdbms-jar.xml

86、如何在weblogic中进行ssl配置与客L的认证配|或说说j2ee(标准)q行ssl的配|缺省安装中使用DemoIdentity.jks和DemoTrust.jks  KeyStore实现SSLQ需要配|服务器使用Enable SSLQ配|其端口Q在产品模式下需要从CA获取U有密钥和数字证书,创徏identity和trust keystoreQ装载获得的密钥和数字证书。可以配|此SSLq接是单向还是双向的?/p>

87、如何查看在weblogic中已l发布的EJB?可以使用理控制収ͼ在它的Deployment中可以查看所有已发布的EJB

88、CORBA是什?用途是什? CORBA 标准是公共对象请求代理结?Common Object Request Broker Architecture)Q由对象理l织 (Object Management GroupQ羃写ؓ OMG)标准化。它的组成是接口定义语言(IDL), 语言l定(binding:也译~?和允许应用程序间互操作的协议?其目的ؓQ用不同的程序设计语a书写在不同的q程中运行,Z同的操作pȝ开发?/p>

89、说说你所熟悉或听说过的j2ee中的几种常用模式?及对设计模式的一些看?br>  Session Facade PatternQ用SessionBean讉KEntityBeanQMessage Facade PatternQ实现异步调用;EJB Command PatternQ用Command JavaBeans取代SessionBeanQ实现轻量讉KQData Transfer Object FactoryQ通过DTO Factory化EntityBean数据提供Ҏ;Generic Attribute AccessQ通过AttibuteAccess接口化EntityBean数据提供Ҏ;Business InterfaceQ通过q程Q本圎ͼ接口和Beancd现相同接口规范业务逻辑一致性;QJQ架构的设计好坏直接媄响系l的性能、可扩展性、可l护性、组件可重用性及开发效率。项目越复杂Q项目队伍越庞大则越能体现良好设计的重要性?/p>

90、说说在weblogic中开发消息Bean时的persistent与non-persisten的差别persistent方式的MDB可以保证消息传递的可靠?也就是如果EJB容器出现问题而JMS服务器依然会消息在此MDB可用的时候发送过来,而nonQpersistent方式的消息将被丢弃?/p>

91、Servlet执行时一般实现哪几个ҎQpublic void init(ServletConfig config)Qpublic ServletConfig getServletConfig()Qpublic String getServletInfo()Qpublic void service(ServletRequest request,ServletResponse response)Qpublic void destroy()

92、常用的设计模式Q说明工厂模式?Java中的23U设计模式:FactoryQ工厂模式)QBuilderQ徏造模式)Q?Factory MethodQ工厂方法模式)QPrototypeQ原始模型模式)QSingletonQ单例模式)Q?FacadeQ门面模式)QAdapterQ适配器模式)Q?BridgeQ桥梁模式)Q?CompositeQ合成模式)QDecoratorQ装饰模式)Q?FlyweightQn元模式)Q?ProxyQ代理模式)QCommandQ命令模式)Q?InterpreterQ解释器模式Q, VisitorQ访问者模式)QIteratorQP代子模式Q, MediatorQ调停者模式)Q?MementoQ备忘录模式Q,ObserverQ观察者模式)QStateQ状态模式)QStrategyQ策略模式)QTemplate MethodQ模板方法模式)Q?Chain Of ResponsibleityQ责任链模式Q。工厂模式:工厂模式是一U经常被使用到的模式Q根据工厂模式实现的cd以根据提供的数据生成一l类中某一个类的实例,通常q一l类有一个公q抽象父类q且实现了相同的ҎQ但是这些方法针对不同的数据q行了不同的操作。首先需要定义一个基c,该类的子c通过不同的方法实C基类中的Ҏ。然后需要定义一个工厂类Q工厂类可以Ҏ条g生成不同的子cd例。当得到子类的实例后Q开发h员可以调用基cM的方法而不必考虑到底q回的是哪一个子cȝ实例?/p>

93、EJB需直接实现它的业务接口或Home接口吗,Lq理由。远E接口和Home接口不需要直接实玎ͼ他们的实C码是由服务器产生的,E序q行中对应实现类会作为对应接口类型的实例被用?/p>

94、排序都有哪几种ҎQ请列D。用JAVA实现一个快速排序。排序的Ҏ有:插入排序Q直接插入排序、希排序)Q交换排序(冒排序、快速排序)Q选择排序Q直接选择排序、堆排序Q,归ƈ排序Q分配排序(排序、基数排序)
快速排序的伪代码? /使用快速排序方法对a[ 0 :n- 1 ]排序Q从a[ 0 :n- 1 ]中选择一个元素作为m i d d l eQ该元素为支点,
把余下的元素分割ZDleft 和r i g h tQ得l e f t中的元素都小于等于支点,而right 中的元素都大于等于支点,递归C用快速排序方法对left q行排序Q递归C用快速排序方法对right q行排序Q所得结果ؓl e f t + m i d d l e + r i g h t?/p>

95、请对以下在J2EE中常用的名词q行解释(或简单描q?web容器Q给处于其中的应用程序组ӞJSPQSERVLETQ提供一个环境,使JSP,SERVLET直接更容器中的环境变量接口交互,不必x其它pȝ问题。主要有WEB服务器来实现。例如:TOMCAT,WEBLOGIC,WEBSPHERE{。该容器提供的接口严格遵守J2EE规范中的WEB APPLICATION 标准。我们把遵守以上标准的WEB服务器就叫做J2EE中的WEB容器。EJB容器QEnterprise java bean 容器。更h行业领域特色。他提供l运行在其中的组件EJB各种理功能。只要满J2EE规范的EJB攑օ该容器,马上׃被容器进行高效率的管理。ƈ且可以通过现成的接口来获得pȝU别的服务。例如邮件服务、事务管理。JNDIQ(Java Naming & Directory InterfaceQJAVA命名目录服务。主要提供的功能是:提供一个目录系l,让其它各地的应用E序在其上面留下自己的烦引,从而满_速查扑֒定位分布式应用程序的功能。JMSQ(Java Message ServiceQJAVA消息服务。主要实现各个应用程序之间的通讯。包括点对点和广播。JTAQ(Java Transaction APIQJAVA事务服务。提供各U分布式事务服务。应用程序只需调用其提供的接口卛_。JAFQ(Java Action FrameWorkQJAVA安全认证框架。提供一些安全控制方面的框架。让开发者通过各种部v和自定义实现自己的个性安全控制策略。RMI/IIOP:QRemote Method Invocation /internet对象h中介协议Q他们主要用于通过q程调用服务。例如,q程有一台计机上运行一个程序,它提供股分析服务,我们可以在本地计机上实现对其直接调用。当然这是要通过一定的规范才能在异构的pȝ之间q行通信。RMI是JAVAҎ的?/p>

96、JAVA语言如何q行异常处理Q关键字Qthrows,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
Java通过面向对象的方法进行异常处理,把各U不同的异常q行分类Qƈ提供了良好的接口。在Java中,每个异常都是一个对象,它是ThrowablecL其它子类的实例。当一个方法出现异常后便抛Z个异常对象,该对象中包含有异怿息,调用q个对象的方法可以捕获到q个异常q进行处理。Java的异常处理是通过5个关键词来实现的Qtry、catch、throw、throws和finally。一般情况下是用try来执行一D늨序,如果出现异常Q系l会抛出QthrowsQ一个异常,q时候你可以通过它的cd来捕捉(catchQ它Q或最后(finallyQ由~省处理器来处理。用try来指定一块预防所?#8220;异常”的程序。紧跟在tryE序后面Q应包含一个catch子句来指定你惌捕捉?#8220;异常”的类型。throw语句用来明确地抛Z?#8220;异常”。throws用来标明一个成员函数可能抛出的各种“异常”。Finally为确保一D代码不发生什?#8220;异常”都被执行一D代码。可以在一个成员函数调用的外面写一个try语句Q在q个成员函数内部写另一个try语句保护其他代码。每当遇C个try语句Q?#8220;异常”的框架就攑ֈ堆栈上面Q直到所有的try语句都完成。如果下一U的try语句没有ҎU?#8220;异常”q行处理Q堆栈就会展开Q直到遇到有处理q种“异常”的try语句?/p>

97、一?#8220;.java”源文件中是否可以包括多个c(不是内部c)Q有什么限Ӟ可以。必d有一个类名与文g名相同?/p>

98、MVC的各个部分都有那些技术来实现?如何实现? MVC是ModelQViewQController的简写?Model" 代表的是应用的业务逻辑Q通过JavaBeanQEJBlg实现Q, "View" 是应用的表示面(由JSP面产生Q,"Controller" 是提供应用的处理q程控制Q一般是一个ServletQ,通过q种设计模型把应用逻辑Q处理过E和昄逻辑分成不同的组件实现。这些组件可以进行交互和重用?/p>

99、java中有几种Ҏ可以实现一个线E?用什么关键字修饰同步Ҏ? stop()和suspend()ҎZ不推荐用?有两U实现方法,分别是承ThreadcM实现Runnable接口用synchronized关键字修饰同步方法反对用stop()Q是因ؓ它不安全。它会解除由U程获取的所有锁定,而且如果对象处于一U不q诏状态,那么其他U程能在那种状态下查和修改它们。结果很难检查出真正的问题所在。suspend()ҎҎ发生死锁。调用suspend()的时候,目标U程会停下来Q但却仍然持有在q之前获得的锁定。此Ӟ其他MU程都不能访问锁定的资源Q除非被“挂v”的线E恢复运行。对MU程来说Q如果它们想恢复目标U程Q同时又试图使用M一个锁定的资源Q就会造成死锁。所以不应该使用suspend()Q而应在自qThreadcM|入一个标志,指出U程应该zdq是挂v。若标志指出U程应该挂vQ便用wait()命其q入{待状态。若标志指出U程应当恢复Q则用一个notify()重新启动U程?/p>

100、java中有几种cd的流QJDK为每U类型的提供了一些抽象类以供l承Q请说出他们分别是哪些类Q?br>字节,字符。字节流l承于InputStream \ OutputStreamQ字W流l承于InputStreamReader \ OutputStreamWriter。在java.io包中q有许多其他的流Q主要是Z提高性能和用方ѝ?/p>

101、java中会存在内存泄漏吗,L单描q。会。如Qint i,i2;  return (i-i2);   //when i够大的正?i2够大的负数。结果会造成溢位Q导致错误?/p>

102、java中实现多态的机制是什么?Ҏ的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父cM子类之间多态性的一U表玎ͼ重蝲Overloading是一个类中多态性的一U表现?/p>

103、垃圑֛收器的基本原理是什么?垃圾回收器可以马上回收内存吗Q有什么办法主动通知虚拟行垃圑֛Ӟ对于GC来说Q当E序员创建对象时QGC开始监控这个对象的地址、大以及用情c通常QGC采用有向囄方式记录和管理堆(heap)中的所有对象。通过q种方式定哪些对象?可达?Q哪些对象是"不可辄"。当GC定一些对象ؓ"不可?ӞGC有责Q回收q些内存I间。可以。程序员可以手动执行System.gc()Q通知GCq行Q但是Java语言规范q不保证GC一定会执行?/p>

104、静态变量和实例变量的区别?static i = 10; //帔RQ?class A a;  a.i =10;//可变

105、什么是java序列化,如何实现java序列化?
序列化就是一U用来处理对象流的机Ӟ所谓对象流也就是将对象的内容进行流化。可以对化后的对象q行d操作Q也可将化后的对象传输于网l之间。序列化是ؓ了解军_对对象流q行d操作时所引发的问题。序列化的实玎ͼ需要被序列化的cd现Serializable接口Q该接口没有需要实现的ҎQimplements Serializable只是Z标注该对象是可被序列化的Q然后用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象?对象Q接着Q用ObjectOutputStream对象的writeObject(Object obj)Ҏ可以将参数为obj的对象写?即保存其状?Q要恢复的话则用输入?/p>

106、是否可以从一个staticҎ内部发出寚wstaticҎ的调用?不可?如果其中包含对象的method()Q不能保证对象初始化.

107、写clone()ҎӞ通常都有一行代码,是什么?Clone 有缺省行为,super.clone();他负责生正大的I间Qƈ逐位复制?/p>

108、在JAVA中,如何跛_当前的多重嵌套@环?用break; return Ҏ?/p>

109、List、Map、Set三个接口Q存取元素时Q各有什么特点?List 以特定次序来持有元素Q可有重复元素。Set 无法拥有重复元素,内部排序。Map 保存key-value|value可多倹{?/p>

110、J2EE是什么?J2EE是Sun公司提出的多?multi-diered),分布?distributed),Zlg(component-base)的企业应用模型(enterpriese application model).在这L一个应用系l中Q可按照功能划分Z同的lgQ这些组件又可在不同计算ZQƈ且处于相应的层次(tier)中。所属层ơ包括客户层(clietn tier)lg,web层和lg,Business层和lg,企业信息pȝ(EIS)层?/p>

111、UML斚w 标准建模语言UML。用例图,静态图(包括cd、对象图和包?,行ؓ?交互?序?合作?,实现图?/p>

112、说Z些常用的c,包,接口Q请各D5个常用的c:BufferedReader  BufferedWriter  FileReader  FileWirter  String  IntegerQ常用的包:java.lang  java.awt  java.io  java.util  java.sqlQ常用的接口QRemote  List  Map  Document  NodeList

113、开发中都用C那些设计模式?用在什么场? 每个模式都描qC一个在我们的环境中不断出现的问题,然后描述了该问题的解x案的核心。通过q种方式Q你可以无数ơ地使用那些已有的解x案,无需在重复相同的工作。主要用CMVC的设计模式。用来开发JSP/Servlet或者J2EE的相兛_用。简单工厂模式等?/p>

114、jsp有哪些动?作用分别是什? JSP共有以下6U基本动?jsp:includeQ在面被请求的时候引入一个文件?jsp:useBeanQ寻找或者实例化一个JavaBean?jsp:setPropertyQ设|JavaBean的属性?jsp:getPropertyQ输出某个JavaBean的属性?jsp:forwardQ把h转到一个新的页面?jsp:pluginQ根据浏览器cd为Java插g生成OBJECT或EMBED标记?/p>

115、Anonymous Inner Class (匿名内部c? 是否可以extends(l承)其它c,是否可以implements(实现)interface(接口)? 可以l承其他cL完成其他接口Q在swing~程中常用此方式?/p>

116、应用服务器与WEB SERVER的区别?应用服务器:Weblogic、Tomcat、JbossQ?WEB SERVERQIIS?Apache

117、BS与CS的联pM区别。C/S是Client/Server的羃写。服务器通常采用高性能的PC、工作站或小型机Qƈ采用大型数据库系l,如Oracle、Sybase、Informix?SQL Server。客L需要安装专用的客户端Y件。B/QxBrower/Server的羃写,客户Z只要安装一个浏览器QBrowserQ,如Netscape Navigator或Internet ExplorerQ服务器安装Oracle、Sybase、Informix?SQL Server{数据库。在q种l构下,用户界面完全通过WWW览器实玎ͼ一部分事务逻辑在前端实玎ͼ但是主要事务逻辑在服务器端实现。浏览器通过Qeb Server 同数据库q行数据交互。C/S ?B/S 区别Q?Q.g环境不同: C/S 一般徏立在专用的网l上, 范围里的网l环? 局域网之间再通过专门服务器提供连接和数据交换服务Q B/S 建立在广域网之上? 不必是专门的|络g环境,例与电话上网, U用讑֤. 信息自己理. 有比C/S更强的适应范围, 一般只要有操作pȝ和浏览器p Q.对安全要求不?QC/S 一般面向相对固定的用户? 对信息安全的控制能力很强. 一般高度机密的信息pȝ采用C/S l构适宜. 可以通过B/S发布部分可公开信息.B/S 建立在广域网之上, 对安全的控制能力相对? 可能面向不可知的用户。3Q对E序架构不同 Q C/S E序可以更加注重程, 可以Ҏ限多层次校验, 对系l运行速度可以较少考虑. B/S 对安全以及访问速度的多重的考虑, 建立在需要更加优化的基础之上. 比C/S有更高的要求 B/Sl构的程序架构是发展的趋? 从MS?Netpd的BizTalk 2000 Exchange 2000{? 全面支持|络的构件搭建的pȝ. SUN 和IBM推的JavaBean 构g技术等,?B/S更加成熟. Q.软g重用不同Q?C/S E序可以不可避免的整体性考虑, 构g的重用性不如在B/S要求下的构g的重用性好. B/S 对的多重l构,要求构g相对独立的功? 能够相对较好的重?入买来的餐桌可以再利用,而不是做在墙上的矛_桌子 。5Q系l维护不?nbsp; QC/S E序׃整体? 必须整体考察, 处理出现的问题以及系l升U? 升? 可能是再做一个全新的pȝQ B/S 构gl成,斚w构g个别的更?实现pȝ的无~升U? pȝl护开销减到最?用户从网上自׃载安装就可以实现升. Q.处理问题不同 QC/S E序可以处理用户面固? q且在相同区? 安全要求高需? 与操作系l相? 应该都是相同的系l,B/S 建立在广域网? 面向不同的用L, 分散地域, q是C/S无法作到? 与操作系l^台关pL? Q.用户接口不同Q?C/S 多是建立的Windowq_?表现Ҏ有限,对程序员普遍要求较高QB/S 建立在浏览器? 有更加丰富和生动的表现方式与用户交流. q且大部分难度减?减低开发成?
Q.信息不?Q C/S E序一般是典型的中央集权的机械式处? 交互性相对低QB/S 信息向可变? B-B B-C B-G{信息、流向的变化, 更像交易中心?br>



chenweicai 2007-04-23 17:20 发表评论
]]>
java 虚拟?/title><link>http://www.tkk7.com/chenweicai/archive/2007/04/23/112944.html</link><dc:creator>chenweicai</dc:creator><author>chenweicai</author><pubDate>Mon, 23 Apr 2007 06:18:00 GMT</pubDate><guid>http://www.tkk7.com/chenweicai/archive/2007/04/23/112944.html</guid><wfw:comment>http://www.tkk7.com/chenweicai/comments/112944.html</wfw:comment><comments>http://www.tkk7.com/chenweicai/archive/2007/04/23/112944.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/chenweicai/comments/commentRss/112944.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/chenweicai/services/trackbacks/112944.html</trackback:ping><description><![CDATA[<p><strong>一、什么是Java虚拟?/strong><br>     当你谈到Java虚拟机时Q你可能是指Q?br>     1、抽象的Java虚拟?br>     2、一个具体的Java虚拟机实?br>     3、一个运行的Java虚拟机实?br><strong>二、Java虚拟机的生命周期</strong><br>     一个运行中的Java虚拟机有着一个清晰的dQ执行JavaE序。程序开始执行时他才q行Q程序结束时他就停止?span style="COLOR: red">你在同一台机器上q行三个E序Q就会有三个q行中的Java虚拟?/span>?br>     Java虚拟机L开始于一个main()ҎQ这个方法必L公有、返回void、直接受一个字W串数组。在E序执行Ӟ<span style="COLOR: red">你必ȝJava虚拟机指明这个包含main()Ҏ的类?/span>?br>     Main()Ҏ是程序的LQ他被执行的U程初始化ؓE序的初始线E。程序中其他的线E都׃来启动。Java中的U程分ؓ两种Q守护线E?QdaemonQ和普通线E(non-daemonQ?span style="COLOR: red">守护U程是Java虚拟׃用的U程Q比如负责垃圾收集的U程是一个守护线E?/span>。当Ӟ你也可以把自qE序讄为守护线E。包含Main()Ҏ的初始线E不是守护线E?br>     只要Java虚拟Zq有普通的U程在执行,Java虚拟机就不会停止。如果有_的权限,你可以调用exit()Ҏl止E序?br><strong>三、Java虚拟机的体系l构</strong><br>     在Java虚拟机的规范中定义了一pd的子pȝ、内存区域、数据类型和使用指南。这些组件构成了Java虚拟机的内部l构Q他们不仅仅为Java虚拟机的实现提供了清晰的内部l构Q更是严D定了Java虚拟机实现的外部行ؓ?nbsp;<br>     每一个Java虚拟机都׃?span style="COLOR: red">cd载器子系l(class loader subsystemQ,</span>负责加蝲E序中的cdQ类和接口)Qƈ赋予唯一的名字。每一个Java虚拟机都有一个执行引擎(execution engineQ负责执行被加蝲cM包含的指令?br>     E序的执行需要一定的内存I间Q如字节码、被加蝲cȝ其他额外信息、程序中的对象、方法的参数、返回倹{本地变量、处理的中间变量{等。Java虚拟机将q些信息l统保存?span style="COLOR: red">数据区(data areasQ?/span>中。虽然每个Java虚拟机的实现中都包含数据区,但是Java虚拟范对数据区的规定却非常的抽象。许多结构上的细节部分都留给?Java虚拟机实现者自己发挥。不同Java虚拟机实C的内存结构千差万别。一部分实现可能占用很多内存Q而其他以下可能只占用很少的内存;一些实现可能会使用虚拟内存Q而其他的则不使用。这U比较精炼的Java虚拟机内存规U,可以使得Java虚拟机可以在q泛的^C被实现?br>     数据Z的一部分是整个程序共有,其他部分被单独的U程控制。每一个Java虚拟机都包含<span style="COLOR: red">Ҏ区(method areaQ?/span>?span style="COLOR: red">堆(heapQ,</span>他们都被整个E序׃n。Java虚拟机加载ƈ解析一个类以后Q将从类文g中解析出来的信息保存与方法区中。程序执行时创徏?对象都保存在堆中?nbsp;<br>     当一个线E被创徏Ӟ会被分配只属于他自己的PC寄存?#8220;pc register”Q程序计数器Q和Java堆栈QJava stackQ。当U程不掉用本地方法时QPC寄存器中保存U程执行的下一条指令。Java堆栈保存了一个线E调用方法时的状态,包括本地变量、调用方法的 参数、返回倹{处理的中间变量。调用本地方法时的状态保存在本地Ҏ堆栈中(native method stacksQ,可能再寄存器或者其他非q_独立的内存中?br>     Java堆栈有堆栈块Qstack frames (or frames)Q组成。堆栈块包含JavaҎ调用的状态。当一个线E调用一个方法时QJava虚拟Z一个新的块压到Java堆栈中,当这个方法运行结束时QJava虚拟Z对应的块弹出ƈ抛弃?br>     Java虚拟Z使用寄存器保存计的中间l果Q而是用Java堆栈在存放中间结果。这是的Java虚拟机的指o更紧凑,也更Ҏ在一个没有寄存器的设备上实现Java虚拟机?nbsp;<br>     图中的Java堆栈中向下增长的QPC寄存器中U程三ؓ灰色Q是因ؓ它正在执行本地方法,他的下一条执行指令不保存在PC寄存器中?br><strong>四、数据类型(Data TypesQ?/strong><br>     所有Java虚拟Z使用的数据都有确定的数据cdQ数据类型和操作都在Java虚拟范中严格定义。Java中的数据cd分ؓ<span style="COLOR: red">原始数据cd Qprimitive typesQ?/span>?span style="COLOR: red">引用数据cdQreference typeQ?/span>引用cd依赖于实际的对象Q但不是对象本n。原始数据类型不依赖于Q何东西,他们是本n表示的数据?br>所有JavaE序语言中的原始 数据cdQ都是Java虚拟机的原始数据cdQ除了布型QbooleanQ。当~译器将Java源代码编译ؓ自己码时Q用整型(intQ或者字节型 QbyteQ去表示布尔型。在Java虚拟Z使用整数0表示布尔型的falseQ用非零整数表C布型的trueQ布数l被表示为字节数l,虽然?们可能会以字节数l或者字节块Qbit fieldsQ保存在堆中?br>     除了布尔型,其他Java语言中的原始cd都是Java虚拟Z的数据类型。在Java中数据类型被分ؓQ整形的byteQshortQintQlongQchar和Q点型的floatQdouble。Java语言中的数据cd在Q何主Z都有同样的范围?nbsp;<br>     在Java虚拟Zq存在一个Java语言中不能用的原始数据cdq回值类型(returnValueQ。这U类型被用来实现JavaE序中的“finally clauses”Q具体的参见18章的“Finally Clauses”?br>     引用cd可能被创ZؓQ?span style="COLOR: red">cȝ型(class typeQ,接口cdQinterface typeQ,数组cdQarray type</span><span style="COLOR: red">Q?/span>。他们都引用被动态创建的对象。当引用cd引用nullӞ说明没有引用M对象?br>     Java虚拟范只定义了每一U数据类型表C的范围Q没有定义在存储时每U类型占用的I间。他们如何存储由Java虚拟机的实现者自己决定?/p> <blockquote dir=ltr> <div>TypeRange<br>byte8-bit signed two's complement integer (-27 to 27 - 1, inclusive)<br>short16-bit signed two's complement integer (-215 to 215 - 1, inclusive)<br>int32-bit signed two's complement integer (-231 to 231 - 1, inclusive)<br>long64-bit signed two's complement integer (-263 to 263 - 1, inclusive)<br>char16-bit unsigned Unicode character (0 to 216 - 1, inclusive)<br>float32-bit IEEE 754 single-precision float<br>double64-bit IEEE 754 double-precision float<br>returnValueaddress of an opcode within the same method<br>referencereference to an object on the heap, or null</div> </blockquote> <div><strong>五、字节长?/strong><br>     Java虚拟Z最的数据单元式字QwordQ,其大由Java虚拟机的实现者定义。但是一个字的大必够容UbyteQshortQintQ?charQfloatQreturnValueQreferenceQ两个字必须_容纳longQdouble。所以虚拟机的实现者至提供的字不能小 ?1bits的字Q但是最好选择特定q_上最有效率的字长?br>     在运行时QJavaE序不能军_所q行机器的字ѝ字长也不会影响E序的行为,他只是在Java虚拟Z的一U表现方式?br><strong>六、类加蝲器子pȝ</strong><br>     Java虚拟Z的类加蝲器分ZU:<span style="COLOR: red">原始cd载器Qprimordial class loaderQ?/span>?span style="COLOR: red">cd载器对象Qclass loader objectsQ?/span>。原始类加蝲器是Java虚拟机实现的一部分Q类加蝲器对象是q行中的E序的一部分。不同类加蝲器加载的c被不同的命名空间所分割?br>     cd载器调用了许多Java虚拟Z其他的部分和java.lang包中的很多类。比如,cd载对象就是java.lang.ClassLoader子类 的实例,ClassLoadercM的方法可以访问虚拟机中的cd载机Ӟ每一个被Java虚拟机加载的c都会被表示Z?java.lang.Classcȝ实例。像其他对象一Pcd载器对象和Class对象都保存在堆中Q被加蝲的信息被保存在方法区中?br>     1、加载、连接、初始化QLoading, Linking and InitializationQ?br>cd载子pȝ不仅仅负责定位ƈ加蝲cLӞ他按照以下严格的步骤作了很多其他的事情:Q具体的信息参见W七章的“cȝ生命周期”Q?br>          1Q、加载:Lq导入指定类型(cd接口Q的二进制信?br>          2Q、连接:q行验证、准备和解析<br>               ①验证:保导入cd的正?br>               ②准备:为类型分配内存ƈ初始化ؓ默认?br>               ③解析:字W引用解析ؓ直接饮用<br>          3Q、初始化Q调用Java代码Q初始化cd量ؓ合适的?br>     2、原始类加蝲器(The Primordial Class LoaderQ?br>     每个Java虚拟机都必须实现一个原始类加蝲器,他能够加载那些遵守类文g格式q且被信ȝcR但是,Java虚拟机的规范q没有定义如何加载类Q这?Java虚拟机实现者自己决定。对于给定类型名的类型,原始莱加载器必须扑ֈ那个cd名加“.class”的文件ƈ加蝲入虚拟机中?br>     3、类加蝲器对?br>     虽然cd载器对象是JavaE序的一部分Q但是ClassLoadercM的三个方法可以访问Java虚拟Z的类加蝲子系l?br>          1Q、protected final Class defineClass(…)Q用这个方法可以出入一个字节数l,定义一个新的类型?br>          2Q、protected Class findSystemClass(String name)Q加载指定的c,如果已经加蝲Q就直接q回?br>          3Q、protected final void resolveClass(Class c)QdefineClass()Ҏ只是加蝲一个类Q这个方法负责后l的动态连接和初始化?br>     具体的信息,参见W八?#8220;q接模型”Q?The Linking ModelQ?br>     4、命名空?br>     当多个类加蝲器加载了同一个类ӞZ保证他们名字的唯一性,需要在cd前加上加载该cȝcd载器的标识。具体的信息Q?br><strong>七、方法区QThe Method AreaQ?br></strong>     在Java虚拟ZQ被加蝲cd的信息都保存在方法区中。这写信息在内存中的l织形式p拟机的实现者定义,比如Q虚拟机工作在一?#8220;little- endian”的处理器上,他就可以信息保存ؓ“little-endian”格式的,虽然在JavacL件中他们是以“big-endian”格式?存的。设计者可以用最适合q地机器的表C格式来存储数据Q以保证E序能够以最快的速度执行。但是,在一个只有很内存的讑֤上,虚拟机的实现者就不会占用 很大的内存?br>     E序中的所有线E共享一个方法区Q所以访问方法区信息的方法必LU程安全的。如果你有两个线E都d载一个叫Lava的类Q那只能׃个线E被容许d载这个类Q另一个必ȝ待?br>     在程序运行时Q方法区的大是可变的,E序在运行时可以扩展。有些Java虚拟机的实现也可以通过参数也订制方法区的初始大,最值和最大倹{?br>     ҎZ可以被垃圾收集。因为程序中的内q加蝲器动态加载,所有类可能变成没有被引用(unreferencedQ的状态。当cd成这U状态时Q他可 能被垃圾攉掉。没有加载的cd括两U状态,一U是真正的没有加载,另一个种?#8220;unreferenced”的状态?br>     1、类型信息(Type InformationQ?br>          每一个被加蝲的类型,在Java虚拟Z都会在方法区中保存如下信息:<br>          1Q、类型的全名QThe fully qualified name of the typeQ?br>          2Q、类型的父类型的全名Q除非没有父cdQ或者弗雷Ş式java.lang.ObjectQ(The fully qualified name of the typeís direct superclassQ?br>          3Q、给cd是一个类q是接口Qclass or an interfaceQ(Whether or not the type is a class Q?br>          4Q、类型的修饰W(publicQprivateQprotectedQstaticQfinalQvolatileQtransient{)QThe typeís modifiersQ?br>          5Q、所有父接口全名的列表(An ordered list of the fully qualified names of any direct superinterfacesQ?br>          cd全名保存的数据结构由虚拟机实现者定义。除此之外,Java虚拟要ؓ每个cd保存如下信息Q?br>          1Q、类型的帔R池(The constant pool for the typeQ?br>          2Q、类型字D늚信息QField informationQ?br>          3Q、类型方法的信息QMethod informationQ?br>          4Q、所有的静态类变量Q非帔RQ信息(All class (static) variables declared in the type, except constantsQ?br>          5Q、一个指向类加蝲器的引用QA reference to class ClassLoaderQ?br>          6Q、一个指向Classcȝ引用QA reference to class ClassQ?/div> <p><br>          1Q、类型的帔R池(The constant pool for the typeQ?br>          帔R池中保存中所有类型是用的有序的常量集合,包含直接帔RQliteralsQ如字符丌Ӏ整数、QҎ的常量,和对cd、字Dc方法的W号引用。常量池 中每一个保存的帔R都有一个烦引,像数组中的字段一栗因为常量池中保存中所有类型用到的类型、字Dc方法的字符引用Q所以它也是动态连接的主要?象?nbsp;         2Q、类型字D늚信息QField informationQ?br>          字段名、字D늱型、字D늚修饰W(publicQprivateQprotectedQstaticQfinalQvolatileQtransient{)、字D在cM定义的顺序?br>          3Q、类型方法的信息QMethod informationQ?br>          Ҏ名、方法的q回值类型(或者是voidQ、方法参数的个数、类型和他们的顺序、字D늚修饰W(publicQprivateQprotectedQstaticQfinalQvolatileQtransient{)、方法在cM定义的顺?br>          如果不是抽象和本地本法还需要保?br>          Ҏ的字节码、方法的操作数堆栈的大小和本地变量区的大(E候有详细信息Q、异常列?br>          4Q、类Q静态)变量QClass VariablesQ?br>          cd量被所有类的实例共享,即不通过cȝ实例也可以访问。这些变量绑定在cMQ而不是类的实例上Q,所以他们是cȝ逻辑数据的一部分。在Java虚拟Z用这个类之前需要ؓcd量(non-finalQ分配内?br>          帔RQfinalQ的处理方式于这U类变量Qnon-finalQ不一栗每一个类型在用到一个常量的时候,都会复制一份到自己的常量池中。常量也像类?量一样保存在ҎZQ只不过他保存在帔R池中。(可能是,cd量被所有实例共享,而常量池是每个实例独有的Q。Non-finalcd量保存ؓ定义他的 cd数据Qdata for the type that declares themQ的一部分Q而final帔R保存Z用他的类型数据(data for any type that uses themQ的一部分?nbsp;  <br>          5Q、指向类加蝲器的引用QA reference to class ClassLoaderQ?br>          每一个被Java虚拟机加载的cdQ虚拟机必须保存q个cd是否由原始类加蝲器或者类加蝲器加载。那些被cd载器加蝲的类型必M存一个指向类加蝲器的?用。当cd载器动态连接时Q会使用q条信息。当一个类引用另一个类Ӟ虚拟机必M存那个被引用的类型是被同一个类加蝲器加载的Q这也是虚拟机维护不同命 名空间的q程?br>          6Q、指向Classcȝ引用QA reference to class ClassQ?br>          Java虚拟Zؓ每一个加载的cd创徏一个java.lang.Classcȝ实例。你也可以通过ClasscȝҎQ?br>public static Class forName(String className)来查找或者加载一个类Qƈ取得相应的Classcȝ实例。通过q个Classcȝ实例Q我们可以访问Java虚拟机方法区中的信息。具体参照ClasscȝJavaDoc?br>     2、方法列表(Method TablesQ?br>     Z更有效的讉K所有保存在ҎZ的数据,q些数据的存储结构必ȝq仔l的设计。所有方法区中,除了保存了上边的那些原始信息外,q有一个ؓ了加快存 取速度而设计的数据l构Q比如方法列表。每一个被加蝲的非抽象c,Java虚拟机都会ؓ他们产生一个方法列表,q个列表中保存了q个cd能调用的所有实?Ҏ的引用,报错那些父类中调用的Ҏ?/p> <p><strong>八、堆<br></strong>     当JavaE序创徏一个类的实例或者数l时Q都在堆中ؓ新的对象分配内存。虚拟机中只有一个堆Q所有的U程都共享他?br>     1、垃圾收集(Garbage CollectionQ?br>     垃圾攉是释放没有被引用的对象的主要Ҏ。它也可能会Z减少堆的片Q而移动对象。在Java虚拟机的规范中没有严格定义垃圾收集,只是定义一个Java虚拟机的实现必须通过某种方式理自己的堆?nbsp;  2、对象存储结构(Object RepresentationQ?br>     Java虚拟机的规范中没有定义对象怎样在堆中存储。每一个对象主要存储的是他的类和父cM定义的对象变量。对于给定的对象的引用,虚拟机必d耨很快的 定位到这个对象的数据。另为,必须提供一U通过对象的引用方法对象数据的ҎQ比如方法区中的对象的引用,所以一个对象保存的数据中往往含有一个某UŞ?指向Ҏ区的指针?br>     一个可能的堆的设计是将堆分Z个部分:引用池和对象池。一个对象的引用是指向引用池的本地指针。每一个引用池中的条目都包含两个部分:指向对象池中?象数据的指针和方法区中对象类数据的指针。这U设计能够方便Java虚拟机堆片的整理。当虚拟机在对象池中Ud一个对象的时候,只需要修改对应引用池?的指针地址。但是每ơ访问对象的数据都需要处理两ơ指针?nbsp; 另一U堆的设计是Q一个对象的引用是一个指向一堆数据和指向相应对象的偏UL针。这U设计方便了对象的访问,可是对象的移动要变的异常复杂?nbsp;  当程序试囑ְ一个对象{换ؓ另一U类型时Q虚拟机需要判断这U{换是否是q个对象的类型,或者是他的父类型。当E序适用instanceof语句的时候也 会做cM的事情。当E序调用一个对象的ҎӞ虚拟机需要进行动态绑定,他必d断调用哪一个类型的Ҏ。这也需要做上面的判断?br>     无论虚拟机实现者用哪一U设计,他都可能为每一个对象保存一个类似方法列表的信息。因Z可以提升对象Ҏ调用的速度Q对提升虚拟机的性能非常重要Q但 是虚拟机的规范中比没有要求必d现类似的数据l构?nbsp;      每一个Java虚拟Z的对象必d联一个用于同步多U程的lock(mutex)。同一时刻Q只能有一个对象拥有这个对象的锁。当一个拥有这个这个对?的锁Q他可以多ơ申误个锁Q但是也必须释放相应ơ数的锁才能真正释放q个对象锁。很多对象在整个生命周期中都不会被锁Q所以这个信息只有在需要时才需 要添加。很多Java虚拟机的实现都没有在对象的数据中包含“锁定数据”Q只是在需要时才生成相应的数据。除了实现对象的锁定Q每一个对象还逻辑兌C ?#8220;wait set”的实现。锁定帮l线E独立处理共享的数据Q不需要妨其他的U程?#8220;wait set”帮组U程协作完成同一个目标?#8220;wait set”往往通过Objectcȝwait()和notify()Ҏ来实现?nbsp;<br>     垃圾攉也需要堆中的对象是否被关联的信息。Java虚拟范中指出垃圾攉一个运行一个对象的finalizerҎ一ơ,但是容许 finalizerҎ重新引用q个对象Q当q个对象再次不被引用Ӟ׃需要再ơ调用finalizeҎ。所以虚拟机也需要保存finalizeҎ 是否q行q的信息。更多信息参见第九章?#8220;垃圾攉”<br>     3、数l的保存QArray RepresentationQ?br>在Java 中,数组是一U完全意义上的对象,他和对象一样保存在堆中、有一个指向Classcd例的引用。所有同一l度和类型的数组拥有同样的ClassQ数l的?度不做考虑。对应Class的名字表CZؓl度和类型。比如一个整型数据的Class?#8220;[I”Q字节型三维数组Class名ؓ“[[[B”Q两l对象数?Class名ؓ“[[Ljava.lang.Object”?br>多维数组被表CZؓ数组的数l?nbsp;, 数组必须在堆中保存数l的长度Q数l的数据和一些对象数l类型数据的引用。通过一个数l引用的Q虚拟机应该能够取得一个数l的长度Q通过索引能够讉K特定 的数据,能够调用Object定义的方法。Object是所有数据类的直接父cR?/p> <img src ="http://www.tkk7.com/chenweicai/aggbug/112944.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/chenweicai/" target="_blank">chenweicai</a> 2007-04-23 14:18 <a href="http://www.tkk7.com/chenweicai/archive/2007/04/23/112944.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://meixiudashi.com" target="_blank">ҰƵѹۿ</a>| <a href="http://zzzttt669.com" target="_blank">վƵA˫</a>| <a href="http://saohu533.com" target="_blank">99ֻоƷ6</a>| <a href="http://jomashopcn.com" target="_blank">99ѹۿƵ</a>| <a href="http://118762.com" target="_blank">jyzzjyzz鶹</a>| <a href="http://6wss.com" target="_blank">زѿ</a>| <a href="http://www44xixi.com" target="_blank">ҰƵѹۿ</a>| <a href="http://shguojing.com" target="_blank">Ļк޴Ƭ</a>| <a href="http://hbtelong.com" target="_blank">޴ɫƵ</a>| <a href="http://www09191z.com" target="_blank">޸Ƶվ</a>| <a href="http://saohu533.com" target="_blank">av˾Ʒ</a>| <a href="http://67f6.com" target="_blank">Ļaѿ </a>| <a href="http://zjjtejia.com" target="_blank">3dѶ߹ۿ</a>| <a href="http://35633487.com" target="_blank">ŷaѹۿ</a>| <a href="http://liulian88.com" target="_blank">һһƬһëƬ</a>| <a href="http://426366.com" target="_blank">avַ</a>| <a href="http://cshjjc.com" target="_blank">Ļþ</a>| <a href="http://987566.com" target="_blank">޾Ʒ͵Ƶѹۿ</a>| <a href="http://jsjumei.com" target="_blank">99þĻƷ</a>| <a href="http://455zx.com" target="_blank">պȫƵۿѹۿ</a>| <a href="http://074g8.com" target="_blank">ĻձƬ</a>| <a href="http://6f2igoa4.com" target="_blank">ҹƷ</a>| <a href="http://bjfljg.com" target="_blank">ҹþAAAAAëƬѿ</a>| <a href="http://yutuzb.com" target="_blank">AVƬ</a>| <a href="http://91sebo.com" target="_blank">ëƬѹۿƵ</a>| <a href="http://tuopumao.com" target="_blank">þɫһ</a>| <a href="http://2222jjjj.com" target="_blank">޹ۺϾƷ</a>| <a href="http://51porn3.com" target="_blank">վ߹ۿ</a>| <a href="http://xjdz8.com" target="_blank">˳ɾƷƵ</a>| <a href="http://chiyizi.com" target="_blank">ѹ˸߹ۿ鶹 </a>| <a href="http://pjappuiehjdkhsjkssd2.com" target="_blank">Ļþ</a>| <a href="http://hnlchb.com" target="_blank">þþžѸƵ</a>| <a href="http://6h6y.com" target="_blank">߹ۿhƬ</a>| <a href="http://zhongxueping888.com" target="_blank">Av߲</a>| <a href="http://www-887234.com" target="_blank">ŷ߲</a>| <a href="http://w7759.com" target="_blank">ʪôýˬƵ</a>| <a href="http://xx16xx.com" target="_blank">ӰԺֻ߹ۿ </a>| <a href="http://gtja1668.com" target="_blank">޹˾Ʒþ</a>| <a href="http://2c06xyz.com" target="_blank">Ʒ߹ۿѲ</a>| <a href="http://dqmovie.com" target="_blank">ĻȫƵ</a>| <a href="http://by6215.com" target="_blank">޹Ƭ߹ۿ </a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>