精华内容
下载资源
问答
  • 工作季来了,互联网大潮也将至。近来陆续有不少师弟师妹校友求分享各种资料和经验,想来手头上...前面已经有找工作笔试面试那些事儿(15)---互联网公司面试的零零种种和多家经验、找工作笔试面试那些事儿(14)---轻松

    作者:寒小阳
    时间:2013年9月。
    出处:http://blog.csdn.net/han_xiaoyang/article/details/11683589
    声明:版权所有,转载请注明出处,谢谢。

            

           找工作季来了,互联网大潮也将至。近来陆续有不少师弟师妹校友求分享各种资料和经验,想来手头上确实还有一些资源,也包括当初博主的师兄师姐们以及某些无私的大牛们分享的资料,笔经面经以及感想。于是翻出来看看,倒是也勾起了不少博主当初找工作时候的记忆和感想,于是一并整理整理,发上来吧。前面已经有找工作笔试面试那些事儿(15)---互联网公司面试的零零种种和多家经验找工作笔试面试那些事儿(14)---轻松一下,谈谈面试注意的点谈谈找工作过程中的那些环节、注意点和经验三篇文章了,这里再上一篇长文吧。其实博主打心底里也不大赞赏这类快餐似的知识补充突击准备,也觉得技术这个东西应该踏踏实实,一步步积累,积累的量到了,技术到位了,自然就找到好工作了;但是也理解第一份工作的意义,大家都想要一个好的平台,好的起点,可观一些的收入(博主当年找工作的时候也是这么一种心理)。这里暂且先不议好坏,该分享的还是分享上来吧,大牛们一笑而过就好,其他的同学们若看过文章后感觉能对自己有那么一些些的帮助,那也挺好的。

             某师兄留下过一篇比较诚恳的找工作感想,博主回忆了一下自己的经历,想来很多东西也比较类似。于是在其基础上,增删修改了一部分内容,整理成一篇文章发上来了。

    找工作前: 

            1)多动手解决实际问题。

            实验室的任务也好,自己感兴趣的事情、项目(现在有很多非常不错的开源项目,能参与进去对自己的提高也会很大)也好,多多主动折腾。

             来自别人的知识很容易遗忘,来自自己的知识是最扎实的。 没事上各大高校的OJ刷一下acm题对现场写代码很有帮助。这个听起来很泛,但是感觉性价比还是很高的。也可以读读“如何用两年时间面试一个人”这篇文章和一些相关的延伸(博主在本文后面附上了),看面试官都想要怎样的人。        

            2)确定自己的方向。

            首先要找到自己的核心竞争力,这个竞争力是多元的,有人算法厉害,有人懂设计模式工程能力超NB,有人做页面效果很炫丽……不妨问问自己,最擅长的是哪个,最喜欢做的是哪个。假如能够找到两个方面,你能在周围的人里面都做到前10%,那找到一个同时需要这两方面能力的工作,你的竞争力就是10%*10% = top 1%了(先抛开这两个东西是不是独立的吧呵呵)。可以把自己的特长和兴趣组合到一起的工作,对于我来说就是dream work。        

            3) 写简历。

            简历上的东西多而杂是一把双刃剑。刘未鹏(如何用两年时间面试一个人作者)也说,简历上写兴趣广泛的他都不想要,这不是优点。有些人为了凸显各个方面都有尝试,写了很多方向的内容。这导致了要预期面试官问一些扩展的问题,因此准备简历的时候也要花更大的精力进行整理,补上自己的盲点以防万一被问到。虽然如此,大多厉害点的面试官都能探到我的底,也建议我在某个方向做深做细。扯远了,但这样也有好处,有些地方就喜欢要这样的人,觉得这样的人有潜力,有主动性。所以大家还是分职位去准备简历吧。 

            4) 投简历。

             确定方向以后,就去投。但不要一直海投(在另外一篇文章谈谈找工作过程中的那些环节、注意点和经验也提到了),面试跑来跑去挤公交车地铁的感觉让人真的想投海,还不如省下点时间好好看书或者和同学讨论讨论问题。

            当然,也不能全投特别好的公司,不然前前期积累不够或者一时没有状态,很容易就挂掉。初期可以先投一些公司练练手,预先感受一下面试的感觉,调整出一个比较好的状态。

            不过要额外考虑的是,互联网每年的形势都不一样,去年如此今年不一定就这样。例如某年搜狗和美团突然给力了(指的待遇哈),很多人当时根本就没有考虑要投,叹息不已;而曾一度吵得热得不行的人民搜索,却又弱了。

            5) 可以到各个渠道去找工作信息,不要只是局限于招聘网站。

            例如现在好些技术牛人都会在微博上发招聘信息,感觉自己有希望的话,主动投一下。在牛人身边学习还是会快很多,无论是工作方式、习惯、视野等等,都不是一个普通团队可以企及的。另外,提供一个渠道让别人找到你。平时多干点事情,求职时通过各种媒介主动宣传一下自己。有些论坛也是非常不错的,帝都的话,IT互联网这块,水木和byr论坛还是很不错的。 
      

    找工作时面试前: 

             1) 看书补充基础知识。

             程序员面试宝典什么的过一遍总是好的。如果是C/C++的话,这里再脸皮厚着推荐一下我之前写过的找工作笔试面试那些事儿系列,或者你可以直接看林博士的《高质量C++/C编程指南》。

             2)算法多积累和思考。

            好吧,虽然博主不喜欢,但是这里又要提到那几本快餐式填补算法的书了。是的,《编程之美》《剑指offer》《代码之美》《编程珠玑》还是要好好过一遍的,尤其前两本,要仔细把代码都写一遍。说起来好玩的是,博主和同学当年面试时,发现不会的题有70%以上都在前两本书上有原题或者母题……有一次面试某公司的时候,吃惊地发现,某道当时想破头也没想出来的题,确实在某美上有原题,而自恃完整看过一遍的我居然完全没有印象了。。。

             3 )找些好战友。

            真的,找工作你不是一个人在战斗,事实上,团队努力可以让每一个人都有更好的结果共享消息,交流面经等等废话我就不说了。在求职的过程中,往往两个人的盲点互补一下,效果会比一个人默默看书好;讨论问题很容易得到正确的结果;假如你们一起参加笔试了,他过了,你没过,你霸面也起码能知道点消息。再阴暗点说,笔试也可以相互关照一下吧(好吧,这个求轻喷)。 

            4 )不要轻易松懈。

             用某师兄的话说,前中期他找工作都比较顺利,也感觉各家的面试大概都那样了,所以给自己的压力就减轻了,偶尔还打打游戏什么的。导致后期的面试无论是想算法还是写代码的状态,都不怎么好了。事实上很多好的offer都在后头,想起来还是很可惜,大家不要重蹈覆辙。觉得自己要懈怠下来的时候,要好好想想第一份工作的意义——按自己的能力,可以如此奢侈地不那么努力吗? 
      

    笔试时: 

             没什么好说的了,基本的门槛,不是要求太高的话,通常都能过。不会的也不要放弃,用意志坚持住,越用心做,机会就越大一分。师兄自己就说当时完美的图形学部分一点不会,但是坚持自己推理,硬是答了半份……

             程序题时间充裕的话,最好先打个草稿吧。这样卷面能整洁一些,不然鬼画符一样,即使程序是对的,改卷的工程师也不乐意给满分。
      

    面试时: 

            1)要自信!!

             气场足是成功的开始。自己都不相信自己,在自己这关上就弱掉了,还指望别人欣赏你, 很难是吧。

            2)遇到挫折时心态要放好。

            笔试和面试随机性都挺大的。笔试可以通过团队作战减少不稳定的因素,面试就不一样了,面试官不一样的情况下,很可能两个求职者的命运也截然不同,不管两个人的水平和最后的结果是否相对匹配。当然实力压倒一切,但人总会有一些盲点,我想强调的是,保持一个积极的心态去面试比较重要。 

             3)面完好好做总结。

            这点太太重要了。找工作的时候,有些同学的习惯很好,每去一次面试回来都会写一个总结,过了会写长一些,反之会短一些,但是一定要总结,特别是不会的题目,第一时间搞清楚记下来。

            根据生日攻击的理论,假如总的面试题目有365道,那随机抽23道,就有50%的概率出现重复。不想被再次恶心到的话,就搞明白好了。能面试的算法题目大概来来去去也就这么几道。

             4)代码写好后要有review的习惯。

            释放内存,边界条件,循环退出条件等等。最次也要拿一个case出来,把程序走一遍,走通了再让面试官看。只要活好,没人会嫌你做得慢。 

             5)鼓起勇气霸笔霸面。

             霸笔情况太多了,博主和同学当时都经常收不到通知,反正觉得公司靠谱的就去霸。除了微软这种明文禁止的没去,100%成功率。霸面就比较讲技巧和RP——一是要表示出诚意和和蔼的态度,二是要把自己的亮点展示出来,剩下的就是看RP了。  

             6)随身携带中英文简历。

             有时HR可能会忘了让你带简历,你真不带的话,万一……,在面试官那里,印象会比较吃亏。    

            7)充分准备好英文相关内容,最好能找个有共同需求的同学一起联系。

             博主自恃英语口语还算OK,但第一次自我介绍的时候真的是挫得一塌糊涂,准备过后效果就完全不一样了。全英文面试基本就不能临急抱佛脚了,但最差也要mark几个关键技术的关键字,什么polymorphism啊,object-oriented programming啊,千万要会。 
      

    选择: 

             1)选行业,选公司真的没有一概的定论。

            各取所需,有人就爱技术昼夜编程,有人喜欢安稳的节奏,有人有伟大的事业追求……没有高低之分。只有适合不适合一说。师兄提到,他寻找的准则有三个,可以参考一下: 

            a 可以做我喜欢做的事情。

              假如不认同自己的工作,每天去工作就是完成任务了。那会是很不爽的。当然每份工作都会有脏活累活,看看比例是不是能够接受吧。当然也有人很厉害,总可以从自己无聊的工作中找到有意思的部分,我真希望我能培养出这种能力。

            b 周围有比我厉害的人。

            有了好同事,才能快速进步。再刨深一些就是要跟对老大,我定义好老大有三个条件:1、有眼光和阅历。2、对你欣赏,肯花时间给你建议,给你机会。3、不轻易跳槽。跟了好老大,行业平台等其实于我看都是浮云。       

           c work life balance. 

           这个倒是看自己的情况了,我除了编程以外运动音乐什么的都很爱好,所以目前还是选择了留一点时间,做做自己喜欢的事情,结识新的朋友,参加些有趣的活动等等。毕竟我们找好的工作是为了给自己和家人更好的生活,不要忘了找工作的初衷。当然有人会反驳,安逸的环境成长慢啊,这样的工作没有意义,或者这些事情是要分阶段考虑的等等。但还是要考虑身体和家人。当前的想法是这些,也有可能是我还没遇到让我奋不顾身的事业吧,仅供参考。  

           d 户口神马的,恩,在帝都的话,还是得考虑一下的

          2)公司信息获取。

            这时就是八仙过海了,上论坛问,找在公司里工作的师兄师姐问,或者加招聘群等等都可以。这个时候人脉的作用也体现出来了,平时多给师兄师姐打打下手什么的吧,吃亏就是占便宜。 

          3)纠结的时候,问问自己的第一直觉。

           例如有人问搜狗和百度,我觉得差不多的话就follow自己的第一感觉吧。纠结主要是因为两种原因:1 信息量太少,无法决策; 2 两者之间真的没有什么差别。 把握足够主干信息以后,一些细微的差别,可能就不用太较真了。


    附:怎样花两年时间去面试一个人 by  刘未鹏

    Joel Spolsky曾经感叹:招聘难,难于上青天(此处笔者稍加演绎:))。他有两个辛辣但不乏洞察力的断言:真正的牛人也许一辈子就投大概4次简历,这些家伙一毕业就被好公司抢走了,并且他们的雇主会给他们不赖的待遇,所以他们也不想挪窝。(刚刚去世的Dennis Ritchie就是这样一个人)而“人才”市场上能找到的大多都不是什么人才。招到这帮人轻则费钱重则把你公司搞挂。

    (当我把这篇文章给邹欣老师review的时候,他说了另外两点:1. 最好的人也许不投简历,就决定去哪里了。所以要在他们做决定前找到他们。2. 比较差的会投很多次简历,找不到工作的时间越多,投的简历越多,给整个pool 带来很多噪音,top10%的简历也许根本不算全部人的top10%。)

    诚然,也许没有哪个行业像IT行业这样,无形资产占据公司的绝大多数资产。拒坊间传言比尔·盖茨就曾经说过类似这样的话:只要允许我带走100个人我可以再造一个微软。这话没搜到原版出处,但是从一个侧面反映了IT公司当中智力资产所占的比例之重。

    所以一个自然的推论就是,招聘也许是一个公司决策当中最最重要的一个环节。Joel Spolsky把他在这方面的观察,体会和洞见集结成了一本小册子《Smart and Gets Things Done》,开篇就挑战“产品是公司成败的关键”这个传统观念,他认为创造最适合工程师生活的环境,留下最优秀的人才才是最先最重要的一步,接下来好的产品是水到渠成的事情。国内iapp4me.com创始人郝培强正是这个理念,所以他在微博上说

    我们是小公司,工资开的不高,也不招太多的人,但是电脑都是iMac27,iMac21,Macbook pro15,基本上比很多大公司都好多了。软件没盗版,刚才photoshop的正版我也收了。中午管饭,公司备伞。哈哈。节日假正常放,从不加班,早晨11点上班,下午6点下班。我是有资格说某些大公司的员工苦逼的。

    事实上,米国找个人尚且难成这样,搞得Joel还费心费力写本书语重心长地劝企业们要善待好工程师,国内找个人更是难上加难,国内高质量问答社区知乎创始人周源就曾经在知乎上分享他呕心沥血的招人历程,看完真是让人慨叹这年头找个靠谱的人多不容易(这条知乎问答还有很多精彩的跟帖):

    其实从 08 年到现在,我一直想这事能不能有点窍门,或者是实用的方法,结论是几乎没有。我用过的大家都用的方法:

    • 在水木上发贴子(有点效果)
    • 在蓝色理想上发贴子(无效)
    • 在技术邮件组里发贴子(无效)
    • 买 51job/智联 最便宜的服务(有点效果)
    • 给所有可以想到的人打电话,请他们推荐(无效)
    • 给所有和你讨论过创业,喝过点小酒的人打电话(无效)
    • 约前同事私下谈(有效)

    我用过的大家可能没有用的方法:

    • 上 twitter,看 XXX 的 follower,一个一个看,看他们的 twitter,博客,Google Reader 分享,想办法搞到邮件,联系,半夜电话骚扰。
    • 上豆瓣,前端后端挑几本重量级的书,去找想看,看过,正在看这本书的人,一个一个看,看他们的活动,博客,Google Reader 分享,想办法搞到邮件,联系,半夜电话骚扰。
    • 找同事,问他们都看什么技术博客,想办法搞到邮件,联系,半夜电话骚扰。

    正是这样的不容易,才有不少公司走内部培养的办法,这里的逻辑是:一上来就招到靠谱的人太难了,但找一块靠谱的璞玉然后雕琢雕琢相对就简单很多。这倒是个办法,但这样做的人难免就陷入了纠结:培养好了,人跑了怎么办。这也不能怪招聘的公司,的确是人之常情。其实解决的办法也很简单,培养的时候进行适当引导,让员工发挥自己的主动学习能力,这样不但人得到更多成长,公司也不会觉得投入太多患得患失。所谓师傅领进门修行在个人。

    但是,这仍然还是没有解决根本的问题,就是招聘真的很困难。应聘者固然觉得自己是在“海投”,大海捞针一般。而招聘者何尝不也是这种大海捞针的感觉。这就好比两个人谈恋爱,都想和对方好上,但是偏偏就聊不到一块去。

    招聘真的很困难。以至于招聘者每年需要绞尽脑汁出新笔试题,以免往年的笔试题早就被人背熟了。出题很费脑子,要出的不太简单也不太难,能够滤掉绝大多数滥竽充数的但又要保证不因题目不公平而滤掉真正有能力的,要考虑审题人的时间成本就只能大多数用选择题,而选择题又是可以猜答案的(极少有人会在选了答案之后还敢在空白的地方写为什么选某答案的原因的)。更悲催的是,有些题目出的连公司的员工们自己都会做错(真的是员工们做错了吗?还是题目本身就出错了?)

    笔试完了之后如果还没有被鄙视就要进入面试环节,姑且不说笔试题的种种弊端,就说面试环节,短短几个小时的面试(大多数公司也许连几个小时的面试时间都没有),既需要全面考察基本知识,又要考察编程素养,还要考察(也许最重要的)性格心态。再然后还有一项根本没法考察但却占据程序员相当一部分工作时间的:debug能力。面试官不但得找准问题,不因对方一题答对而妄下结论,也不因一题打错而就扼杀机会,还要以管窥豹,从一朵花看到整个世界,从面试人的举止言谈,分析问题的方式,甚至写程序的笔迹来观察这个人的性格,做事的方式和心态,简直是要面试官具备心理分析师的水准才行。

    这厢要招人的雇主苦不堪言,那边找工作的人也是一团乱麻。绝大多数应届生直到毕业也不清楚他们想要去的公司到底需要什么样的能力,或者说,他们到底需要具备什么样的能力才能在应聘季节拥有自己的选择权。中国虽然本科教育环境差,但是同样有很多的人在本科希望整点东西出来,他们有一腔的激情和抱负,有强大的动力,但就是不知道自己需要掌握哪些技能才能满足雇主的要求,求告无门,整年整年苦闷的像没头苍蝇一样乱撞(我就收到过很多次这样的来信,他们往往很想学点东西,但又不知道哪些重要哪些不重要,到底该学到什么程度,不知道导致不确定,不确定导致决策瘫痪,干脆嘛也不动,荒废时间)。

    什么叫熟练?什么又叫精通?那么扎实呢?两年的YY经验又意味着什么?能这么简单的量化吗?同样是两年的“实践”有的人能真的学到点东西,有的人也许近似一无所得。那么实习呢?很多人都一定要在简历上弄个实习经验,这个又能说明多少问题呢?大作业呢?得奖呢?有一次我面试一位同学,据简历说编译原理课的大作业得了一等奖,可我一问什么是递归下降,就傻眼了。

    这个现实的结果就是,现在绝大多数应届简历而言,也许最具信息量的部分不是“精通XXX,熟悉YYY,掌握ZZZ”,不是“在UUU实习过”,也不是这个项目那个作业,反倒是越来越被认为不重要的一项:毕业学校毕业学校本不应该是最具信息量的,它之所以最具信息量只是源于一个悲剧的事实:简历上其他条目实在信息量太少了。所以靠谱的面试者往往学会了无视简历上华而不实的内容,只相信面试的时候亲眼所见,扫两眼简历也就罢了,最后还得自己捋起袖子慢慢面。而应聘者也许也知道招聘的也不会细细纠简历上的条目,所以什么词也都敢往上捅,反正先过了HR筛简历这关再说。从经济学角度来讲,应聘者的这种策略是正确的,没有代价(因为目前似乎没有公司会去给已经申请过的人做一个诚信数据库),但至少有可能会带来巨大的收益。应聘成了博彩。而博彩式的应聘给招聘公司带来了巨大的筛选压力。简历成了摆设。

    那么招聘这个关系里面的第三者——学校——所处的位置呢?学校更关心的是毕业率和就业率,这似乎是件好事,有这个为目标,那么老师们似乎应该努力让自己的学生多学点东西。可惜就业的质量似乎不是最重要的指标,此其一。其二老师本身大多数没有丰富的业界经验,根本不知道企业整整需要的人才是什么样的,可能花了精力,但却培养不出雇主真正需要的人。另一方面,老师所起的作用很多时候甚至是一个负面的作用,例如布置大作业表面上看上去是培养学生的能力,我们姑且不说抄袭,假设每个人都做了,那么大作业本身能够衡量多少东西呢?能否衡量代码质量,能否衡量团队协作能力?能否衡量交流能力?考虑到大作业用到的东西往往都是书里面现成的,大作业甚至不能衡量学习能力。而学习能力简直算是这个行业最重要的能力没有之一了

    所以,简而言之,如果把人才培养/招聘这件事情本身类比做一个项目,那么这整个项目迄今为止就是一个巨大的失败。为什么这么说呢:

    • 和需求严重脱节:作为人才需求方的雇主的需求到底是什么?绝大多数应聘者都没搞清。更严重的是,这却一点都不是应聘者的错。因为雇主是stakeholder,是雇主自己的责任得去说清楚需求是什么。结果应聘者实现的不是雇主想要的,雇主想要的应聘者没有实现。
    • 应聘者雇来培训自己的人根本不管事:学生交了学费,就相当于雇老师来培训自己,可培训者根本也不了解(或不关心)他的客户们的需求。这里,学生是需求方,老师则是实现方。弄清需求的职责在后者,可后者也弄不清。
    • 学生自己也弄不清:学生自己既是需求方(需要特定技能),也是实现方。可他们自己也弄不清需求到底是什么。

    以上三点还不是最严重的,最严重的在下面:

    • 明白需求是什么的也不知道怎么实现:怎么去培养现代IT企业真正需要的人才?特别地,实战能力怎么培养?代码素养怎么培养?协作沟通能力怎么培养?学习能力怎么培养?就算这些都知道怎么培养,又怎么给在象牙塔里头,离催命之日还遥遥无期的学生提供足够的动力呢?而学生自己就算知道该学哪些技能,又怎么知道具体怎么着手?什么是最有效率的学习方法?又如何让自己保持学习的热情?

    以上这些问题,就是当下人才培养/招聘的惨淡现状。简而言之,在雇主和学生之间,横梗着一条巨大的鸿沟,两头都很着急,两头都有动力,但就是没有方法,君住长江头妾住长江尾。像微软谷歌这样的,干脆和高校合作,直接插手本科或硕士的教育,从而保证到时有足够强的候选,某种程度上,这的确是根本解决之道,可一来这代价太大了,非一般企业承受得起,二来这影响面也太小了。

    这一切,也许将在未来的5年发生根本的变化。

    《Switch: How to Change Things When Change Is Hard》(中译《瞬变》)里面指出,表面上看来非常困难的改变,也许是因为根本就没有抓住要害。在书中作者通过大量案例分析和心理学研究,雄辩地指出以下几点促成改变的关键之处:

    • 触动内心的大象:要改变的人必须要有情感层面的动力。有一些特定的方法能够比另一些方法更能对人的情感产生触动。
    • 给出清晰、明确的目标:目标一定不能含糊,模棱两口的目标让人无所适从,导致决策瘫痪。例如最近我们组在招实习生,我在微博上发了一条招聘信息,其中提到“扎实”的系统底层知识,有同学就写信来问,怎么叫“扎实”。我傻眼了。比尔·盖茨就以目标清晰明确著称,不仅在战略制定上,“每个人桌面上都有一台PC”,而且居然还体现在招聘上——“如果你读完了TAOCP,那么就给我投简历吧”。多么清晰,明确的目标啊——虽然高了点,也许这就是比尔·盖茨至今还没被应聘邮件淹没的原因:)
    • 给前进的道路扫清障碍:人是懒惰的,只要有借口就会不想往前。如果既有明确的目标,同时道路又直直指向目标,一览无余,只等你开始往前走,那么便没有借口,一往无前。

    那么让我们对照上面看看,可以做什么?

    首先,内心的大象不需要触动,中国有足够多的人足够早就开始焦虑就业的事情,只是不知道往哪使劲,这部分人如果把劲头用到正确的事情上面也许足以满足现在的IT企业人才饥渴了。至于其他人,好吧,也许身边的人开始动起来他们也会被触动。

    然后是清晰、明确的目标。这一点上目前雇主们的做法可谓好坏参半,好的一点是大家都强调要有实践经验,要有团队协作精神,坏的一点就在基础知识和技能的要求方面,可谓再含糊不过了:“精通XX语言”,“扎实的XX功底”,“熟悉XX技术”,甚至看上去最具量化感的描述“X年YY经验”其实都根本说明不了多少东西,在信息量方面还不如我家门口菜市场上一家卖酥油饼的店门口挂的横幅——“三天不硬、至少六层!”。

    很多朋友也许注意到一个现象,现在企业对招聘者简历的要求也在变得越来越灵活变通,例如ThoughtWorks在招聘的时候就希望招聘者能给出自己的博客地址,博客对IT行业的意义也许胜过其他所有行业,一个积累多年的技术博客比任何简历都更能说明问题。台湾的郭安定也说“为什么写技术博客对新人如此重要”。可惜这个做法也有一个弊端:并不是所有技术牛人都写博客,有人就是只干不说型的,而就算写博客,乃至动手写过一阵子的,写一个常年的博客,也远比你想象的更为困难,因为很多时候,写(说)得靠谱比做得靠谱更难。所以这个过滤器很多时候用不上。

    但是这的确表明了一个思考的方向,就是寻找更具鉴别力的过滤器,Stackoverflow Careers 2.0之所以强大,是因为Joel Spolsky和Jeff Atwood这两位常年混社区的资深博主创造性地将一个人在社区的活动历史浓缩成为一系列的量化数值,由于这个历史很长期,所以鉴别力非常高。但它同样也有问题,就是对于应聘者来讲相当花费时间,而且并不是花时间(在Stackoverflow上回答问题)就一定能花到点子上。

    到底什么特征才是既通用,又能够有效地鉴别高低应聘者的特征呢?这个特征必须不像博客那样难以实现,同时又必须有足够的区分度

    有的地方在要求填写简历的时候必须填上平时都访问哪些技术网站。恩,很不错的尝试,可区分度仍然还是不够,因为上网站上查东西毕竟只占现阶段大多数应届生的少数信息来源,特别是当我们看重得更多的是应届应聘者的系统性的知识基础的时候,网上的东西虽然丰富,但属于提高班,也更为琐碎,什么是更系统的知识来源呢?答案其实大家都知道——

    书。

    我一向认为,很多时候,是否好好看完一本好书,对一个人的提升往往能达到质的区别。就算不好好看完一本好书,马马虎虎看完,只要书是真的好书,也肯定会有很大的提高。我在面试的时候就经常询问对方看过哪些技术书籍,经常上哪些网站,订哪些博客。这里头尤其数书籍这一项的区分度最高。此外,好书和坏书的差别,从本质上,就是学习效率和大方向的差别。一本烂书可以浪费你半年的时间,但一本好书却可以为你带来真正扎实的基础和开阔的视野。人们常常用“内功”来形容扎实的基础,认为学好了内功以后学什么都快,其实一点没错,好的“内功”书不仅讲清楚深刻的原理,而且指明技术的本质,刻画领域的地图。好的书抓住不变量,让人能够触类旁通。好的书不仅介绍知识,而且阐释原则,介绍那些万变不离其宗的东西。读烂书浪费时间,但读好书却节省时间

    象牙塔内的学生受到视野的限制,往往择书不慎,事倍功半,烂书不仅浪费时间,还会打击人的积极性,让人对知识心生恐惧,认为很难掌握,殊不知只是作者没有讲好(或者没有翻译好)。因此,为招聘头疼的公司完全可以给出“应聘俺们公司前必读的十本书”,也不一定要每个公司都不一样,在某个技术子领域有影响力的人,或者创始人们,可以来定义具有代表性的书单。

    我们姑且把这个计划叫做“书单计划”,容易看到“书单计划”具备以下几个卓越的优点:

    1. 清晰、明确。完全可度量。
    2. 防伪:读没读过,随便一问便知。而正因为应聘者也知道这事不像实习经验可以忽悠,所以也不敢乱往简历上捅词。
    3. 不在乎是否“泄题”:书单完全公开的,无所谓,本来就是要你去读的。想背题?背书吧。真能背下来说明认真看了。
    4. 管你用心不用心读,只要读了,读完了,就有区别。真正的好书,你想不被吸引都难。据我观察很多人就是不知道该去读什么书。
    5. 不存在“怎么做”的障碍:所有人都知道怎么读书——一页一页读。
    6. 不需要招聘者投入精力:书单在此,就这么简单,您看着办。
    7. 评估的负担很大程度转移到了应聘者的身上:是不是认真看完了,有没有心得体会,您自己掂量。没看完别来找我们。

    “书单计划”能很大程度上起到强鉴别器的作用,看了就是看了,必然能学到东西,没看就是没看。知道和不知道,区别是本质的其实很多企业内部培训,根本上其实还不就是叫员工去看之前没看过的书或者资料嘛。最后,除了鉴别作用之外,它还是一个清晰促进的目标,是完全不花精力的培养

    当然,“书单计划”的背后是另一个悲剧的现实,如果不是因为这个现实,这个计划也完全没有必要,那就是,中国IT大学教育当中要求要学的书,和企业真正需要你去读的书相比,不是完全不够用,就是写的不够好,或者更悲剧的就是根本用不上,所以在这个大背景下出来的牛人都是自己淘书自己学的。微软高级开发测试工程师,《Windows用户态程序高效排错》作者熊力就在微博上说过:“我当年毕业的时候总结了一个公式:第一份工作的月薪=大学四年买过的技术书籍价格的总和。”

    但是光有“书单计划”还不够,因为书籍只能管基础知识这一块,一些更难以量化衡量的实战“能力”又怎么办呢?至少目前为止,除了“练”之外好像还没有特别好的办法。可是在象牙塔里面做的项目,或大作业,真的能起到练的作用吗?前面说了,学生会知道自己最终要交差的不是雇主,而是老师,于是就以老师能够评判的标准来默认要求自己了,老师能够评判编码素养?代码风格?文档?设计?协作?甚至连著名的Joel 12条的第一条“是否用源代码管理系统”都没法通过。所以大多数时候,大作业能起到的作用近乎0。

    但是如果这一切是由雇主来评判的,这个“作业”是由雇主来给出的,就完全不一样了。一想到作业是要作为简历的一部分的,能不紧张嘛。能不好好做嘛。能不学到点东西嘛?

    可是这事儿能实现吗?雇主能给学生出大作业吗?也许一两个关系好的高校可以,可是中国那么多学生呢?

    为什么不能呢?如果像书单那样,列出各个技术领域“推荐在学校期间尝试的项目”,至于动不动手做,那是学生自己的问题。做的,自然能够得到锻炼,面试的时候自然能得到更大的优势。

    可问题是,面试的人又怎么来评估呢?这不又回到了没法有效评估的怪圈了吗?答案很简单,但这个答案,直到最近几年,才真正成为现实——

    GitHub

    GitHub诞生于08年春天,第一年便产生了4万6千个公共项目,大约一年半之后用户就已经达到10万用户之巨。而到今年九月份,GitHub已经迎来了百万级用户。Host超过两百万个项目。

    增长的太快了!就像Twitter一样。这样疯了一般的增长只能说明一个事实——人们等待这个产品太久了

    Social Coding

    真实的项目,真实的流程,真实的人名,一切代码review, check-in, test, build, document, 甚至讨论,计划,brianstorming,流程,一切的一切,都是项目历史的一部分,都可以像棋局那样复盘。有经验的面试者只要稍稍扫两眼一个人的GitHub历史,挑出几个check-in历史看一看,便完全能够迅速判断这个人是否满足他的要求。不再需要费劲心机地去想题目,去观察,去揣测,去花费大量的时间的同时还只能采样到几个极为有限的点。

    不像象牙塔里面大作业,这里有源代码管理系统,自动化build,有check-in,有review,有分工,有合作,最重要的是——这是一个集市,一个超出象牙塔的集市,牛人相互吸引,你可以在互联网上找到和自己拥有共同兴趣的一帮人,真正做起一点事情,而不是交差,不需要受限于几十个人的一个小班级。Here Comes Everybody

    为什么我这么有信心?因为这事儿已经发生了。这个想法也完全不是我原创的

    正如很多事情一样,现在在国内发生的事情,往往是美国那头的历史。今年7月中旬,纽约一家公司的工程师老大发了一篇博客文章:Github is Your New Resume。指出一个惊人但再合理不过的事实:越来越多的IT公司在招聘的时候要求应聘者给出GitHub账号。甚至已经有人为GitHub写了根据GitHub上的历史自动生成简历的工具

    仔细想想,这是必然的趋势,没有比这个再合理的事情了,既然StackOverflow的历史能够作为简历,GitHub的历史不本该就是更好的简历吗:你想要具有实战经验,懂check-in懂review懂test和代码质量的重要性,懂交流和沟通的重要性,你本就应该在一个真实的项目当中去锻炼这些东西,而这些在目前已经完全可以办到。正如邹欣老师所说,你的工作就是最好的面试

    这件事情放在早几年,是完全没法做到的,因为我们那时候还没有GitHub。正如没有Twitter,没有微博之前,很多事情都不会成为可能一样,你有千钧之力,缺乏一个合适的支点,也没法撬动一整个社群。无组织中的组织,具有强大的杠杆效应。

    这个事情里面,我唯一提出的东西就是:在目前国内这个现状下,苦闷的招聘者应该主动行动,给出一些建议项目,正如前面提到的书单计划一样,招聘者需要给出的只是引导和清晰明确的目标,剩下的事情,应聘者自然会去完成,这些项目可以是实验项目,也可以是完全能做出点卖钱的东西的项目(如果好好做的话),唯一的不可或缺的前提是,项目不能太小,单人就能完成的项目不理想,一两个月就能完成的项目不理想,最好足够大到能够锻炼到方方面面,偏大一点倒是无所谓的,因为一个尚未完成的项目完全可以作为简历。当然,可以想见的是,真到了那个时候,学生们肯定又是不会满足于仅去做那些已经有许多人做过的项目了所以这里企业们一开始所建议的项目只是一个《Nudge》,是滚雪球之前需要的一点初始动能。后面的事情,他们自己会完成。

    “GitHub计划”同样有一些明显的、甚至不可替代的优点:

    1. 清晰、明确,完全可度量。
    2. 防伪:同样不担心“泄题”。你伪造不了GitHub历史,伪造不了check-in历史,review comments,文档,交流记录…
    3. 它不但是招聘,也是不花精力的培养。善哉善哉。
    4. 评估的责任很大程度上交给了应聘者自己。

    从你的GitHub旅程开始,你就已经一脚踏进了真正的企业,而企业的面试也已经开始。

    书单+GitHub,就相当于一个两年左右的面试。

    没有什么面试比持续两年的面试更具有信息量。

    书单,加上项目,已经基本上覆盖了所需的全部技能。最妙的是,有太多的人在焦急的等待着他们未来的雇主给出明确的信号,他们想投入精力,去学习和实践,去成为企业需要的人,但是他们就是不知道往什么方向走,所谓有动力没方向。所以,雇主给出了清晰明确的要求,相信对于很多人来说反倒是一个解脱:“终于知道该干什么了”。《编程之美》为什么常居畅销榜?因为它透露了雇主眼中的需求,明确、清晰的需求,可以实现,并且知道怎么去实现的需求。

    你提前两年就开始面试和培养未来的候选者,而且还不需要你花出一分精力,而且人家还很乐意,没有比这更完美的面试了。

    想一想,以后那些没见过世面的公司看见你拿出GitHub账号给他看,该是多么惊讶同时又觉得多么合理。

    而这一切,只是因为两个小小的改变:

    1. 由需求方(雇主)给出了清晰、明确的目标。
    2. GitHub这样的平台。

    那么,学校/老师在这个事情当中的位置呢?说实话我不知道。没有哪个行业像IT行业这样特殊:没有什么东西不能够(应该)在互联网上学到的。自组织的力量完全大过传统的教育方式。而且,既然雇主都当了领路人了,我不知道还有中间开发商什么事儿。(注:这里说的是软件开发,并非计算机科学研究,后者另当别论

    那么,这个改变会发生吗?多久会发生呢?当然,它在国外已经发生了,所以问这个问题多少有点无趣。但我还是预计很快就会在国内发生,毕竟,不是已经有人要求出示博客,和经常浏览的网站了吗?也许5年左右(4年本科和6年硕士的中间值?))就会深刻改变整个人才培养/招聘的格局。当然,我并不是预言家,所以不要把我的时间估计当真,我能肯定的是,这种方式是必然的大势所趋。

    刚才我就收到一位同学邀请我上知乎回答一个问题“找工作的首要原则是什么?”,当然,这个问题的答案是:“弄清雇主的需求到底是什么”。


    列一下我所认为的,你面试微软前必须要读的十本书:

    1. Code: The Hidden Language of Computer Hardware and Software (《编码的奥秘》)
    2. Computer System: A Programmer’s Perspective (《深入理解计算机系统》) / Windows via C/C++ (《Windows核心编程》 / 《程序员的自我修养》
    3. Code Complete 2(《代码大全》)/ The Pragmatic Programmer (《程序员修炼之道》,我也把这本书称为《代码小全》)
    4. Programming Pearls (《编程珠玑》) / Algorithms / Algorithm Design / 《编程之美》
    5. The C Programming Language
    6. The C++ Programming Language / Programming: Principles and Practice Using C++ / Accelerated C++
    7. The Structure and Interpretation of Computer Programs (《计算机程序的构造和解释》)
    8. Clean Code / Implementation Patterns
    9. Design Patterns (《设计模式》) / Agile Software Development, Principles, Patterns, and Practices
    10. Refactoring (《重构》)

    (注:1. 以上同一条目下用“/”隔开的表示任选,当然你也可以都读了,相信我,时间是足够的。2. 读这些书并不意味着逐字逐句从第一页读到最后一页——当然你也可以这么做。怎么是聪明高效的读法,可以参考我之前写的关于如何阅读和查找/鉴别书籍/资料的博文

    注意:以上是我个人认为你面试微软开发职位前必须要读的10本书,它不代表我的雇主的观点。它也只是一个初步的书单,肯定会受到我个人经验和眼界的限制。欢迎大家提意见。

    此外,IT不同子领域的必读书单可能千差万别,所以在发布之前我把这篇文章发给了一些朋友,他们给出了自己的书单(你是不是能看到一些有趣的共同点呢):

    云风(中国游戏编程先行者,前网易游戏部门资深程序员,简悦创始人):

    如果面试,我会挑以下的我自己读过的书,让人选择他也读过的部分,再了解他对这些书的理解。这些书其实本质上就是两类,对所面对的东西(程序语言也好,操作系统也好,底层设施也好)本身的理解程度。以及另一类:对设计思想和原则的理解:

    1. C++编程思想
    2. Effective C++
    3. 深度探索C++对象模型
    4. C++语言的设计和演化
    5. C专家编程
    6. C陷阱与缺陷
    7. C语言接口与实现
    8. Lua程序设计
    9. Linkers and Loaders
    10. COM本质论
    11. Windows核心编程
    12. 深入解析Windows操作系统
    13. 程序员修炼之道
    14. 代码大全
    15. UNIX编程艺术
    16. 设计模式
    17. 代码优化:有效使用内存
    18. 深入理解计算机系统
    19. 深入理解LINUX内核
    20. TCP/IP 详解

    冯大辉(丁香园CTO,贝塔咖啡创始人):

    1. 软件随想录
    2. 黑客与画家
    3. 重来
    4. UNIX编程艺术
    5. 编程人生

    洪强宁(豆瓣技术总监):

    StackOverflow上有一个程序员必读书单帖子,这里仅列出top10,更多参考这里

    1. Code Complete 2
    2. The Mythical Man-Month (《人月神话》)
    3. Code: The Hidden Language of Computer Hardware and Software (《编码的奥秘》)
    4. TAOCP (不解释)
    5. The Pragmatic Programmer (《程序员修炼之道》)
    6. Design Patterns (《设计模式》)
    7. The Structure and Interpretation of Computer Programs (《计算机程序的构造和解释》)
    8. Refactoring (《重构》)
    9. The C Programming Language
    10. Introduction to Algorithms (《算法导论》)

    郑昀(窝窝团研发副总裁):

    1. 工程师入门:
      1. Code Complete 2
      2. 程序员修炼之道
      3. 深入理解计算机系统
    2. 工程师升级:
      1. 设计模式
      2. 重构——改善既有代码的设计
    3. 工程师转型:
      1. 快速软件开发——有效控制与完成进度计划
      2. 人月神话
      3. IT项目管理那些事儿
      4. 软件随想录
      5. 最后期限
      6. 走出软件作坊
      7. 你的灯亮着吗?——发现问题的真正所在

    张峥(微软亚洲研究院副院长):

    1. Algorithms (by Sanjoy Dasgupta, Christos Papadimitriou and Umesh Vazirani)
    2. Data Structure and Algorithms
    3. The C Programming Language
    4. The Design of the UNIX Operating System
    5. Compilers (龙书)
    6. Computer Architecture: A Quantitative Approach
    7. Flow
    8. Outliers (why hard work and luck are both important)

    邹欣(MSRA创新工程中心首席研发经理):

    关于创新的书籍(http://book.douban.com/doulist/1253169/):

    1. The Myths of Innovation
    2. The Innovator’s Dilemma
    3. The Innovator’s Solution
    4. Crossing the Chasm
    5. Inside Intuit
    6. 盛田昭夫
    7. 杰克·韦尔奇自传
    8. 梦断代码
    9. Innovation
    10. 浪潮之巅

    关于“精通”的一篇博客《技能的反面:魔方和模仿》:

    http://www.cnblogs.com/xinz/archive/2011/08/07/2129751.html

    在我教的《现代软件工程》课上,除了教科书,每个学生要看另一本相关的书籍并写读书分析。这个博客有一些同学的读书报告: 
    http://www.cnblogs.com/OMG-Team/archive/2011/10/25/2223247.html


    展开全文
  • 主 题: 发布本人整理的面试问题大全,为准备找工作的同行们尽一份力!希望大家多补充或回答! 作 者: top1000 (天天向上) 等 级: 信 誉 值: 98 所属社区: .NET技术 C# 问题点数: 0 回复次数: ...

    主  题:  发布本人整理的面试问题大全,为准备找工作的同行们尽一份力!希望大家多补充或回答! 
    作  者:  top1000 (天天向上) 
    等  级:   
    信 誉 值:  98 
    所属社区:  .NET技术 C# 
    问题点数:  0 
    回复次数:  184 
    发表时间:  2005-9-14 21:13:57 
      
     
      

    1. C#中 property 与 attribute的区别,他们各有什么用处,

    <script type="text/javascript"> google_ad_client = "pub-6924533005275861"; google_ad_slot = "0030867594"; google_ad_width = 300; google_ad_height = 250; </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
    这种机制的好处在哪里?
    2. 讲一讲你理解的web service,在dot net framework中,怎么很好的结合xml?(讲概念就行了)
    3. C#, Java 和 c++的特点,有什么相同的地方,不同的地方,C#分别从c++和java中吸取了他们那些优点?
    4. C#可否对内存进行直接的操作?(这可是个难点哦?要注意!)
    5. 用Visual C++ 6.0编写的代码(unmanaged code),如何在CLR下和其他dot net component结合?
    6. 以前作过的一些项目?介绍一下自己的编程经验。(这是蒙混不过去的,基本一问就知道是真是假)
    7. 你对公司有什么期望?你的薪水期望值?为什么学计算机?以前的工作经验(这非常重要)?

     

    Q3: 维护数据库的完整性、一致性、你喜欢用触发器还是自写业务逻辑?为什么
    Q4:ADO。NET相对于ADO等主要有什么改进?
    Q5:ASP。NET与ASP相比,主要有哪些进步?
    Q6:C#中的委托是什么?事件是不是一种委托?
    Q7:描述一下C#中索引器的实现过程,是否只能根据数字进行索引?
    Q8:C#中要使一个类支持FOREACH遍历,实现过程怎样?
    Q10:写一个HTML页面,实现以下功能,左键点击页面时显示“您好”,右键点击时显示“禁止右键”。并在2分钟后自动关闭页面。
    Q11:你对XMLHTTP、WEBSERVICE 了解吗?简单描述其特点、作用
    Q12:接口和抽象类有什么区别?你选择使用接口和抽象类的依据是什么?
    Q13:自定义控件和一般用户控件的异同?如果要用这两者之一,你会选择哪种?为什么
    Q14:大概描述一下ASP。NET服务器控件的生命周期
    Q15:UML
    Q16:面向对象的概念,主要特点
    Q17:类划分的依据。类粒度问题
    Q18:事物管理问题

    第一,谈谈final, finally, finalize的区别。
    第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
    第三,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统)。
    第四,&和&&的区别。
    第五,HashMap和Hashtable的区别。
    第六,Collection 和 Collections的区别。
    第七,什么时候用assert。
    第八,GC是什么? 为什么要有GC?
    第九,String s = new String("xyz");创建了几个String Object?
    第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
    第十一,short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
    第十二,sleep() 和 wait() 有什么区别?
    第十三,Java有没有goto?
    第十四,数组有没有length()这个方法? String有没有length()这个方法?
    第十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
    第十六,Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
    第十七,给我一个你最常见到的runtime exception。
    第十八,error和exception有什么区别?
    第十九,List, Set, Map是否继承自Collection接口?
    第二十,abstract class和interface有什么区别?
    第二十一,abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
    第二十二,接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
    第二十三,启动一个线程是用run()还是start()?
    第二十四,构造器Constructor是否可被override?
    第二十五,是否可以继承String类?
    第二十六,当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
    第二十七,try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
    第二十八,编程题: 用最有效率的方法算出2乘以8等於几?
    第二十九,两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
    第三十,当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
    第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
    第三十二,编程题: 写一个Singleton出来。


     
      top1000(天天向上) ( ) 信誉:98  2005-9-14 21:14:28  得分: 0 
     
     
      

    数据库方面:

    1.存储过程和函数的区别
    2.事务是什么?
    3.游标的作用?如何知道游标已经到了最后?
    4.触发器分为事前触发和事后触发,这两种触发有和区别。语句级触发和行级触发有何区别。

    1。用C#实现以下功能
       a 产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
       b 对上面生成的数组排序,需要支持升序、降序两种顺序
    2。请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。
    3。请说明.net中的错误处理机制,并举例
    4。请说出强名的含义
    5。请列出c#中几种循环的方法,并指出他们的不同
    6。请指出.net中所有类型的基类
    7。请指出GAC的含义
    8。SQL SREVER中,向一个表中插入了新数据,如何快捷的得到自增量字段的当前值

    您在什么情况下会用到虚方法?它与接口有什么不同?
    Q:Override与重载有什么区别?
    Q:值类型与引用类型有什么区别?
    Q:怎样理解静态变量?
    Q:向服务器发送请求有几种方式?
    Q:DataReader与Dataset有什么区别?
    Q:如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理?
    Q:用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层?
    Q:软件开发过程一般有几个阶段?每个阶段的作用?
    Q:微软推出了一系列的Application Block,请举出您所知道的Application Block并说明其作用?
    Q:请列举一些您用到过的设计模式以及在什么情况下使用该模式?
    Q:您对WebService的体会?
    Q:您对编程的兴趣如何?工作中遇到不懂的问题是怎样去解决的?您一般怎样去提高自己的编程水平?
    Q:您离职的原因是什么?
    Q:通过超链接怎样传递中文参数?
    Q:请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
    Q:请编程实现一个冒泡排序算法?

    1、override与重载的区别
    2、.net的错误处理机制是什么
    3、C#中接口和类的异同
    4、DataReader和DataSet的异同

    1.有哪几种方法可以实现一个类存取另外一个类的成员函数及属性,并请举列来加以说明和分析.
    2.如果需记录类的实例个数,该如何实现,请写一个简单的类于以证明.
    3.A类是B类的基类,并且都有自己的构造,析构函数,请举例证明B类从实例化到消亡过程中构造,析构函数的执行过程.
    4.需要实现对一个字符串的处理,首先将该字符串首尾的空格去掉,如果字符串中间还有连续空格的话,仅保留一个空格,即允许字符串中间有多个空格,但连续的空格数不可超过一个.

    一.填空题
    1.c#中的三元运算符是__?:___?
    2.当整数a赋值给一个object对象时,整数a将会被__装箱(封装)___?
    3.类成员有_____种可访问形式?  this.;new Class().Method;
    4.public static const int A=1;这段代码有错误么?是什么?  const不能用static修饰
    5.float f=-123.567F;
      int i=(int)f;
    i的值现在是_____?   123 
    6.利用operator声明且仅声明了“==”,有什么错误么? 
    7.委托声明的关键字是______? delagete
    8.用sealed修饰的类有什么特点?密封,不能继承
    9.在Asp.net中所有的自定义用户控件都必须继承自________?Control
    10.在.Net中所有可序列化的类都被标记为_____? 
    11.在.Net托管代码中我们不用担心内存漏洞,这是因为有了______?gc
    12.下面的代码中有什么错误吗?_______
         using System;
         class A
         {
              public virtual void F(){
                  Console.WriteLine("A.F");
               }
          }
          abstract class B:A
           {
               public abstract override void F(); // new public abstract void F(); 
           }

    13.当类T只声明了私有实例构造函数时,则在T的程序文本外部,___可以___(可以 or 不可以)从T派生出新的类,不可以____(可以 or 不可以)直接创建T的任何实例。
    14.下面这段代码有错误么?
        switch (i){
        case():
            CaseZero();
            break;
        case 1:
            CaseOne();
            break;
        case 2:
            dufault;  //wrong
            CaseTwo();
            break;
       }
    15.在.Net中,类System.Web.UI.Page 可以被继承么?可以

    二.简答题
    1.在c#中using和new这两个关键字有什么意义,请写出你所知道的意义?using 指令 和语句 new 创建实例 new 隐藏基类中方法
    4.谈谈类和结构的区别?类是引用类型、结构是值类型
    5.一个长度为10000的字符串,通过随机从a-z中抽取10000个字符组成。请用c#语言编写主要程序来实现。
    6.对于这样的一个枚举类型:
          enum Color:byte{
              Red,
              Green,
              Blue,
              Orange
           }
         string[] ss=Enum.GetNames(typeof(Color));
         byte[]   bb=Enum.GetValues(typeof(Color));
    试写一段程序显示出枚举类型中定义的所有符号名称以及它们对应的数值。
    7.您了解设计模式么?请列出您所知道的设计模式的名称。 //
    8.请在SQL Server中设计表来保存一个树状结构的组织结构图(假设结构图中只有名称这一项内容需要保存),如果我想查询某一职位下的所有职位,用一个存储过程来实现,你有什么思路?
    9.什么叫做SQL注入,如何防止?请举例说明。
    10.下面这段代码输出什么?为什么?
         int i=5;
         int j=5;
         if (Object.ReferenceEquals(i,j))
              Console.WriteLine("Equal");
         else
              Console.WriteLine("Not Equal");
    //不相等,因为比较的是对象

    1.写一个实现对一段字符串翻转的方法,附加一些条件,如其中包括“,”、“.”,对其设计测试用 例 。
    2.对一支纸杯设计测试用例(可以是广义的杯,不一定是某一支特定功能的杯)
    开发语言概念题
    3.什么是反射?
    4.用Singleton如何写设计模式
    5.C#中的垃圾回收机制是怎样的?
    6.什么是Application Pool?
    7.链表和数组的区别,各有什么优缺点.
    8.Remoting在客户端服务器怎么实现 ?
    9.什么是友元函数?
    10.用标准C如何实现多态?
    11.什么是虚函数?
    12.什么是抽象函数?
    13.什么是内存泄漏,怎样最简单的方法判断被存泄漏 ?

    英语题
    14.用英文介绍一下使用C#/C++做的项目,主要功能
    15.如果要与美国开电话会议,会如何与美国的工程师沟通
    16.如果老板认为你的技术落后,你会怎么回答

    数据库知识题
    17.使用什么工具来调用存储过程
    18.SQL Server的两种索引是何形式?索引的作用?索引的优缺点?
    19.触发器的作用

    其它知识题及问题
    20.什么是Web Service?
    21.什么是XML?
    22.Socket怎么实现?


     
     
    Top 
     top1000(天天向上) ( ) 信誉:98  2005-9-14 21:14:57  得分: 0 
     
     
      
    本人msn:hnuc@hotmail.com,欢迎大家多交流!

     
     
    Top 
     IceChan(IceChan) ( ) 信誉:100  2005-9-14 21:20:25  得分: 0 
     
     
      
    好贴,顶一下

     
     
    Top 
     wang921718(从aquatic到computer) ( ) 信誉:100  2005-9-14 21:37:08  得分: 0 
     
     
      
    顶啊,好好!

     
     
    Top 
     yanam(神啊帮帮我吧) ( ) 信誉:100  2005-9-14 22:55:28  得分: 0 
     
     
      
    好难啊,看来找工作难了

     
     
    Top 
     sunsjorlin(ALonelyMan) ( ) 信誉:100  2005-9-15 0:16:30  得分: 0 
     
     
      
    顶下


     
     
    Top 
     top1000(天天向上) ( ) 信誉:98  2005-9-15 12:23:08  得分: 0 
     
     
      
    别沉下去了!

     
     
    Top 
     ljrcl() ( ) 信誉:100  2005-9-15 12:27:47  得分: 0 
     
     
      


     
     
    Top 
     j_lei407(一笑(急需充电……)) ( ) 信誉:100  2005-9-15 12:38:34  得分: 0 
     
     
      
    mark

     
     
    Top 
     guenli() ( ) 信誉:100  2005-9-15 12:40:54  得分: 0 
     
     
      
    帮顶一下!

     
     
    Top 
     shrinerain(圣影雨) ( ) 信誉:100  2005-9-15 12:41:14  得分: 0 
     
     
      
    收藏

     
     
    Top 
     top1000(天天向上) ( ) 信誉:98  2005-9-15 12:50:08  得分: 0 
     
     
      
    大家也别老是顶,也可以多多补充或对有把握的问题回答!

     
     
    Top 
     song_2000(今天心情很不错) ( ) 信誉:99  2005-9-15 12:56:04  得分: 0 
     
     
      
    学习.

     
     
    Top 
     zerory(吸水的海绵) ( ) 信誉:100  2005-9-15 13:02:08  得分: 0 
     
     
      
    恩 需要答案中

     
     
    Top 
     kkk_visual(不学无术) ( ) 信誉:100  2005-9-15 13:14:21  得分: 0 
     
     
      
    谢谢,正需要中。。

     
     
    Top 
     ljhkim6(龙成啊少) ( ) 信誉:100  2005-9-15 13:22:29  得分: 0 
     
     
      
    不错的题目

     
     
    Top 
     happer6012() ( ) 信誉:100  2005-9-15 13:56:13  得分: 0 
     
     
      
    mark

     
     
    Top 
     top1000(天天向上) ( ) 信誉:98  2005-9-15 15:43:13  得分: 0 
     
     
      
    呵呵,明天开始,慢慢解答上面的问题,欢迎大家积极参加!

     
     
    Top 
     fengjianwei1982(小熊) ( ) 信誉:100  2005-9-15 15:46:53  得分: 0 
     
     
      
    mark

     
     
    Top 
     quanyi(长生天) ( ) 信誉:100  2005-9-16 14:50:20  得分: 0 
     
     
      
    mark

     
     
    Top 
     Queen_L(Queen) ( ) 信誉:100  2005-9-16 15:06:54  得分: 0 
     
     
      
    谢了!

     
     
    Top 
     emp(Thinking) ( ) 信誉:100  2005-9-16 15:10:54  得分: 0 
     
     
      
    mark

     
     
    Top 
     metababy(花纯春) ( ) 信誉:100  2005-9-16 15:19:02  得分: 0 
     
     
      
    微软解决方案

     
     
    Top 
     shrinerain(圣影雨) ( ) 信誉:100  2005-9-16 16:11:13  得分: 0 
     
     
      
    请大家指出我的错误

    1. C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?
    一个是属性,用于存取类的字段,一个是特性,用来标识类,方法等的附加性质

    2. 讲一讲你理解的web service,在dot net framework中,怎么很好的结合xml?(讲概念就行了)
    不会,正在学习中

    3. C#, Java 和 c++的特点,有什么相同的地方,不同的地方,C#分别从c++和java中吸取了他们那些优点?
    相同点:都是C系的,都是面向对象
    不同点:Java,C#都是建立在虚拟机机制上,而C++不是

    4. C#可否对内存进行直接的操作?(这可是个难点哦?要注意!)
    可以

    5. 用Visual C++ 6.0编写的代码(unmanaged code),如何在CLR下和其他dot net component结合?
    编译Dll,[DLLImport]

    6. 以前作过的一些项目?介绍一下自己的编程经验。(这是蒙混不过去的,基本一问就知道是真是假)
    7. 你对公司有什么期望?你的薪水期望值?为什么学计算机?以前的工作经验(这非常重要)?

    Q3: 维护数据库的完整性、一致性、你喜欢用触发器还是自写业务逻辑?为什么
    触发器,性能好,事务性

    Q4:ADO。NET相对于ADO等主要有什么改进?
    新增dataset等,不需要随时保持连接,性能提高

    Q5:ASP。NET与ASP相比,主要有哪些进步?
    asp解释形,aspx编译型,性能提高,有利于保护源码

    Q6:C#中的委托是什么?事件是不是一种委托?
    委托是一种安全的函数指针,事件是一种消息机制

    Q7:描述一下C#中索引器的实现过程,是否只能根据数字进行索引?
    不会

    Q8:C#中要使一个类支持FOREACH遍历,实现过程怎样?
    实现一个接口

    Q10:写一个HTML页面,实现以下功能,左键点击页面时显示“您好”,右键点击时显示“禁止右键”。并在2分钟后自动关闭页面。
    JS代码

    Q11:你对XMLHTTP、WEBSERVICE 了解吗?简单描述其特点、作用
    xmlhttp可以主动获取远端web代码,类似HttpWebRequest

    Q12:接口和抽象类有什么区别?你选择使用接口和抽象类的依据是什么?
    接口用于规范,抽象类用于共性。

    Q15:UML
    统一建模语言

    Q16:面向对象的概念,主要特点
    封装,基层,多态

     

    数据库方面:

    1.存储过程和函数的区别
    存储过程是编译好的存储在数据库的操作,函数不用说了。。。

    2.事务是什么?
    具有原子性特点

    3.游标的作用?如何知道游标已经到了最后?
    指示当前记录的位置,检查NULL

    4.触发器分为事前触发和事后触发,这两种触发有和区别。语句级触发和行级触发有何区别。
    一个是操作前,一个是操作后

    1。用C#实现以下功能
    a 产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
            int[] intArr=new int[100];
    ArrayList myList=new ArrayList();
           Random rnd=new Random();
    while(myList.Count<100)
    {
     int num=rnd.Next(1,101);
     if(!myList.Contains(num))
     myList.Add(num);
    }
    for(int i=0;i<100;i++)
        intArr[i]=(int)myList[i];

    b 对上面生成的数组排序,需要支持升序、降序两种顺序
    ArrayList本身就能排序

    2。请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。
    session(viewstate) 简单,但易丢失
    application        全局
    cookie             简单,但可能不支持,可能被伪造
    input ttype="hidden"     简单,可能被伪造
    url参数                  简单,显示于地址栏,长度有限
    数据库                   稳定,安全,但性能相对弱


    3。请说明.net中的错误处理机制,并举例
    try catch final

    4。请说出强名的含义
    具有自己的key,可以在GAC为公用

    5。请列出c#中几种循环的方法,并指出他们的不同
    for wile foreach

    6。请指出.net中所有类型的基类
    object

    7。请指出GAC的含义
    全局程序集缓存

    8。SQL SREVER中,向一个表中插入了新数据,如何快捷的得到自增量字段的当前值
    select @@id... 什么的,忘了

    您在什么情况下会用到虚方法?它与接口有什么不同?
    前面已说

    Q:Override与重载有什么区别?
    一个是重写父类函数,一个是同一个函数的几种形式

    Q:值类型与引用类型有什么区别?
    值和指针的区别

    Q:怎样理解静态变量?
    所有实例公用一个的变量

    Q:向服务器发送请求有几种方式?
    get post

    Q:DataReader与Dataset有什么区别?
    一个是只能向前的只读游标,一个是内存中的表

    Q:如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理?
    input type=""
    url
    数据库

    Q:用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层?
    三层,表现,逻辑,数据, 安全性,维护性

    Q:软件开发过程一般有几个阶段?每个阶段的作用?
    需求分析,架构设计,代码编写,QA,部署

    Q:请列举一些您用到过的设计模式以及在什么情况下使用该模式?
    著名的singleton


    Q:您对编程的兴趣如何?工作中遇到不懂的问题是怎样去解决的?您一般怎样去提高自己的编程水平?
    Q:您离职的原因是什么?
    Q:通过超链接怎样传递中文参数?
    URLEncode URLDecode

    Q:请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
    foreach

    1.有哪几种方法可以实现一个类存取另外一个类的成员函数及属性,并请举列来加以说明和分析.
    同一个名称控件直接,或者反射

    2.如果需记录类的实例个数,该如何实现,请写一个简单的类于以证明.
    const static int classNum=0;
    classNum++;

    3.A类是B类的基类,并且都有自己的构造,析构函数,请举例证明B类从实例化到消亡过程中构造,析构函数的执行过程.
    构造先父后子,析够反之

    4.需要实现对一个字符串的处理,首先将该字符串首尾的空格去掉,如果字符串中间还有连续空格的话,仅保留一个空格,即允许字符串中间有多个空格,但连续的空格数不可超过一个.
    string inputStr=" xx   xx  ";
    inputStr=Regex.Replace(inputStr.Trim()," *"," ");

    二.简答题
    1.在c#中using和new这两个关键字有什么意义,请写出你所知道的意义?using 指令 和语句 new 创建实例 new 隐藏基类中方法
    using 引入名称空间或者使用非托管资源
    new 新建实例或者隐藏父类方法

    4.谈谈类和结构的区别?
    类是引用类型、结构是值类型

    5.一个长度为10000的字符串,通过随机从a-z中抽取10000个字符组成。请用c#语言编写主要程序来实现。
    和前面那个差不多,一样

    6.对于这样的一个枚举类型:
    enum Color:byte{
    Red,
    Green,
    Blue,
    Orange
    }
    string[] ss=Enum.GetNames(typeof(Color));
    byte[] bb=Enum.GetValues(typeof(Color));
    试写一段程序显示出枚举类型中定义的所有符号名称以及它们对应的数值。
    foreach

    9.什么叫做SQL注入,如何防止?请举例说明。
    利用sql关键字对网站进行攻击。过滤关键字'等

    10.下面这段代码输出什么?为什么?
    int i=5;
    int j=5;
    if (Object.ReferenceEquals(i,j))
    Console.WriteLine("Equal");
    else
    Console.WriteLine("Not Equal");
    //不相等,因为比较的是对象

    1.写一个实现对一段字符串翻转的方法,附加一些条件,如其中包括“,”、“.”,对其设计测试用例 。
    inputStr=inputStr.ToCharArray().Reverse().ToString();

    2.对一支纸杯设计测试用例(可以是广义的杯,不一定是某一支特定功能的杯)
    太宽了。。。

    开发语言概念题
    3.什么是反射?
    动态获取程序集信息

    4.用Singleton如何写设计模式
    static属性里面new ,构造函数private

    5.C#中的垃圾回收机制是怎样的?
    三个generation,当每个generation内存满了的时候检查引用,无引用就回收内存

    6.什么是Application Pool?
    Web应用,类似Thread Pool,提高并发性能

    7.链表和数组的区别,各有什么优缺点.
    一个可以动态增长,一个固定(VB中可以Redim),性能数组教好

    8.Remoting在客户端服务器怎么实现 ?
    9.什么是友元函数?
    friendly声明,可以访问protect级别方法

    11.什么是虚函数?
    可以被重写

    12.什么是抽象函数?
    必须被重写

    13.什么是内存泄漏,怎样最简单的方法判断被存泄漏 ?
    C++,C中忘了释放内存,内存不会再次分配

    数据库知识题
    17.使用什么工具来调用存储过程
    任何一种语言

    18.SQL Server的两种索引是何形式?索引的作用?索引的优缺点?
    cluster和非cluster,加速查找,占用额外控件,维护索引耗费时间

    19.触发器的作用
    保证数据库操作变更能接到通知

    其它知识题及问题
    20.什么是Web Service?
    使应用程序在整个网上可以被调用

    21.什么是XML?
    可扩展标记语言,可以做配置文件,可以传输数据,可以存储数据

    22.Socket怎么实现?
    这个不知道怎么说了。。。


     
     
    Top 
     top1000(天天向上) ( ) 信誉:98  2005-9-16 16:52:24  得分: 0 
     
     
      
    呵呵,看了楼上的回答,我今天几不回答了,大家先研究下你的答案吧!

     
     
    Top 
     wsjdx(猫) ( ) 信誉:100  2005-9-16 16:57:11  得分: 0 
     
     
      
    正需要呢

     
     
    Top 
     ChenLiuqing(没有心的鸟^_^(★★★★★)) ( ) 信誉:100  2005-9-16 17:04:05  得分: 0 
     
     
      
    学习

     
     
    Top 
     yzh0523(水手) ( ) 信誉:95  2005-9-16 17:52:29  得分: 0 
     
     
      
    收藏

     
     
    Top 
     ybzsu(弑君者) ( ) 信誉:98  2005-9-16 18:00:55  得分: 0 
     
     
      
    ArrayList ar=new ArrayList();
    int [] list=new int[100];
    for(int i=1;i<=100;i++)ar.Add(i);
    Random rm=new Random();
    for(int i=0;i<100;i++)
    {
    int index=rm.Next(99-i);
    list[i]=(int)ar[index];
    ar.RemoveAt(index);
    }

     

     
     
    Top 
     sunheartlee(心晴) ( ) 信誉:100  2005-9-16 18:12:07  得分: 0 
     
     
      
    不错,谢谢了,
    收藏!!

     
     
    Top 
     top1000(天天向上) ( ) 信誉:98  2005-9-16 18:22:53  得分: 0 
     
     
      
    楼上的回答的很强了,大家都可以试着回答下!

     
     
    Top 
     yjlbukn(聪哥) ( ) 信誉:100  2005-9-16 18:27:49  得分: 0 
     
     
      
    Q3: 维护数据库的完整性、一致性、你喜欢用触发器还是自写业务逻辑?为什么

    使用数据库关系:这样可以尽可能的规范编码、对比较大型的开发来说也容易维护数据的一致性和完整性,也让数据库的性能尽可能的发挥出来。

    实在是不能使用数据库的关系的时候才使用触发器,这让数据逻辑简单,但这时候要注意记录文档,不然,触发器多了,维护难度会相当大。
     
    最后是自己编写逻辑:这样会造成数据的一致性,完整性的维护逻辑相当大,也十分分散,没有良好的文档记录习惯的话,一旦任务出现交接,其他人很难继续你未完成的工作,甚至于过一段时间以后,自己要完全理请逻辑都是一个麻烦的事!因为这些逻辑相当于隐藏起来了的。

     
     
    Top 
     yjlbukn(聪哥) ( ) 信誉:100  2005-9-16 18:35:40  得分: 0 
     
     
      
    22.Socket怎么实现?

    这个问题是猪才会用来做测试题,

    不同的语言有不同的方式,有不同的包,有不同的通讯方式!

    就java和c#来说:他们都有net包/名称空间
    直接使用类就是了,还要什么实现不实现的?
    是c的话还有则说的:
    比如端口需要监听,数据需要串行和反串行化等等。
    这个不是一个问题了,是一个工程!

     
     
    Top 
     ynmc(一天多一点) ( ) 信誉:100  2005-9-16 18:37:58  得分: 0 
     
     
      
    藏了.

     
     
    Top 
     yjlbukn(聪哥) ( ) 信誉:100  2005-9-16 18:38:15  得分: 0 
     
     
      
    11.什么是虚函数?
    没有实现的,可由子类继承并重写的函数。
    12.什么是抽象函数?
    规定其非虚子类必须实现的函数。


     
     
    Top 
     mathsword(梦在流浪) ( ) 信誉:100  2005-9-16 18:55:59  得分: 0 
     
     
      
    有空慢慢做

     
     
    Top 
     yufenfeila(雨纷飞啦) ( ) 信誉:100  2005-9-16 20:44:50  得分: 0 
     
     
      
    mark

     
     
    Top 
     jianli0108(激光) ( ) 信誉:98  2005-9-16 23:02:06  得分: 0 
     
     
      
    好贴子!收藏了

     
     
    Top 
     lgr0727(特立独行的猪) ( ) 信誉:96  2005-9-17 11:47:38  得分: 0 
     
     
      
    收藏

     
     
    Top 
     salmon230() ( ) 信誉:100  2005-9-17 12:06:07  得分: 0 
     
     
      
    学习

     
     
    Top 
     chendd_911() ( ) 信誉:100  2005-9-17 12:24:51  得分: 0 
     
     
      
    好贴,学习,收藏!

     
     
    Top 
     wangwanru(蓝月亮) ( ) 信誉:100  2005-9-17 14:00:49  得分: 0 
     
     
      
    好,收藏!UP!

     
     
    Top 
     ndhjx(你的好记性) ( ) 信誉:98  2005-9-17 15:31:43  得分: 0 
     
     
      
    这么帅的帖子!


     
     
    Top 
     zhaoliang_chen(龙行天下) ( ) 信誉:100  2005-9-17 15:36:06  得分: 0 
     
     
      
    事件是委托

     
     
    Top 
     top1000(天天向上) ( ) 信誉:98  2005-9-17 19:21:20  得分: 0 
     
     
      
    呵呵,今天去华为面试了,全是些算法题,而且考的太细致了。人又多,实在没意思,等了会就走了!
    现在还记得最后两道:
    1。有个字符串,下个函数删除从i开始后j个字符。
    2。写个方法判断什么是对称数。比如121,34543,6678766。

     

     
     
    Top 
     wangfuchong(怫悰) ( ) 信誉:100  2005-9-17 19:36:30  得分: 0 
     
     
      
    看看

     
     
    Top 
     wingnal(清淡天和) ( ) 信誉:100  2005-9-17 19:50:20  得分: 0 
     
     
      
    up

     
     
    Top 
     top1000(天天向上) ( ) 信誉:98  2005-9-18 15:52:08  得分: 0 
     
     
      
    补充中:

    1.面向对象的思想主要包括什么?
    面向对象三大特征:继承,封套,多态.面相对象的思想也不是一句两句就能说清楚..主要思想就是减少代码重复,增大代码复用率..

    2.什么是ASP.net中的用户控件
    问这样的问题,一般是迷惑你.因为新手还是分不清楚用户控件和服务器控件(也称自定义控件)..用户控件一般用在内容多为静态,或者少许会改变的情况下..用的比较大..类似ASP中的include..但是功能要强大的多..

    3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?
    这个需要当前描述了..东西太多..打字要打死了..找个比较简单的说说吧!
    CTS:公共类型系统.主要是为了语言之间的进行标准化处理.
    CLS:公共语言规范.主要是确保代码可以在任何语言中访问的最小标准集体
    CLR:公共语言运行时.主要是管理代码..处理,加载代码,以及所有服务的代码

    4.列举一下你所了解的XML技术及其应用
    xml用于配置,用于保存静态数据类型.接触XML最多的是web Services..和config

    5.值类型和引用类型的区别?写出C#的样例代码。
    值类型是在内存中保存,引用类型是在内存中保存一副本.你在内存中可以有多个某种引用对象..但是值类型始终只有一个.
    最常见的值类型就是static,struct;
    例如:
    static int aa = 1;//值类型
    如果多个用户改变aa的值则,aa的值会以最后一个修改的记录为准.其他人的修改则会被冲掉.
    引用类型,最能说明问题的就是实例化..你new出来的对象单独分配一个独立的内存..所以值不会互相冲突/
    具体的区别参考我的文章:http://lixianhuei.cnblogs.com/archive/2005/08/31/227274.html

    6.ADO.net中常用的对象有哪些?分别描述一下。
    Connection 数据库连接对象
    Command 数据库命令
    DataReader 数据读取器
    DataSet 数据集

    7.如何理解委托?
    委托的概念,最好的说明就是事件.因为事件使用的就是委托.例如:this.Load += new System.EventHandler(this.Page_Load);这个就是使用了一个委托.
    具体的用法请参考.我以前的帖子,设计猫鼠联动..

    8.C#中的接口和类有什么异同。
    类是方法功能的实现和集合,接口是规范类.约束类.
    参考我的文章:http://lixianhuei.cnblogs.com/archive/2005/08/04/207123.html

    9.。net中读写数据库需要用到哪些类?他们的作用
    看第六题..答案差不多

    10.UDP连接和TCP连接的异同。
    这个说不清楚.

    11.ASP.net的身份验证方式有哪些?分别是什么原理?
    window验证:为每个用户开启window帐号,验证其身份.安全性较高.
    forms验证:为每个登陆用户写入一个身份验证票据..在web使用最广的验证方式..灵活方便.

    12.进程和线程分别怎么理解?
    这个是新人最容易迷惑的东西..
    进程:Process

    13.什么是code-Behind技术。
    新建一个VS.NET下的项目..看到ASPX,RESX和CS三个后缀的文件了吗??这个就是代码分离.实现了HTML代码和服务器代码分离.方便代码编写和整理.

    14.活动目录的作用。
    活动目录是window2000的最重要的功能.可以将用户信息全部集成起来,登陆以后可以访问多个不同的网络服务..没深入研究过.
    查看一下帖子:http://www.ies.impu.edu.cn/resource/os/windowsx/WindowsGeneral/WinGeneral0008.htm

    15..net中读写XML的类都归属于哪些命名空间?
    System.XML类

    16.解释一下UDDI、WSDL的意义及其作用。
    解释不清楚了..又是一大块..

    17.什么是SOAP,有哪些应用。
    simple object access protocal,简单对象接受协议.以xml为基本编码结构,建立在已有通信协议上(如http,不过据说ms在搞最底层的架构在tcp/ip上的soap)的一种规范
    是微软大力推广的Web Service使用的协议..

    18.如何部署一个ASP.net页面。
    不清楚问的什么意思...如果非要回答的话,就写一个带.aspx的后缀文件..然后安装IIS和FrameWork环境..浏览就好了.

    19.如何理解.net中的垃圾回收机制。
    垃圾回收体制如下:
    如果发现内存不够,则垃圾回收器,将全部对象作为无效对象(被回收对象),然后先将全局变量,static,处于活动中的局部变量,以及当前CG指针指向的对象放入一个表中.然后
    会搜索新列表中的对象所引用的对象.加入列表中,其他没有被加入列表的对象都会被回收.

    20.常用的调用webservice方法有哪些?
    我一般用的是WSDL..或者web引用..


     
     
    Top 
     charlie36(奈良鹿丸) ( ) 信誉:100  2005-9-18 16:27:06  得分: 0 
     
     
      
    要是刚毕业的本科生找工作,面试人员也会出这样的题?

     
     
    Top 
     zxbyhcsdn(沙子) ( ) 信誉:98  2005-10-5 1:03:32  得分: 0 
     
     
      
    其实这些,去买一本砖头一样的.net书,认真看,应该是没有问题的

     
     
    Top 
     weichaozu131083() ( ) 信誉:99  2005-10-5 1:14:17  得分: 0 
     
     
      
    对不起,我一个也不会,我只会编程

     
     
    Top 
     N_ccw(N神) ( ) 信誉:100  2005-10-5 2:01:09  得分: 0 
     
     
      
    up
    谢谢

     
     
    Top 
     wjlrual(佳林) ( ) 信誉:100  2005-10-5 10:26:16  得分: 0 
     
     
      
    up

     
     
    Top 
     iuhxq(小灰) ( ) 信誉:100  2005-10-5 10:47:35  得分: 0 
     
     
      
    学习呀,太难了。

     
     
    Top 
     chenghp(CHP) ( ) 信誉:100  2005-10-5 10:52:58  得分: 0 
     
     
      
    天哪。。。。。。。。。。这么难。。。。。。。天哪!@#¥#^%%¥#¥&*&%(&^

     
     
    Top 
     antoniusguo(anton) ( ) 信誉:100  2005-10-5 11:14:54  得分: 0 
     
     
      
    强贴,是男人就顶

     
     
    Top 
     shrinerain(圣影雨) ( ) 信誉:100  2005-10-5 11:43:38  得分: 0 
     
     
      
    to top1000(天天向上)
    呵呵,今天去华为面试了,全是些算法题,而且考的太细致了。人又多,实在没意思,等了会就走了!
    现在还记得最后两道:
    1。有个字符串,下个函数删除从i开始后j个字符。
    2。写个方法判断什么是对称数。比如121,34543,6678766。

    1.构建一个链表,第i个单元的next指针指向j以后个单元就行了。中间的那些delete
    2.回文判断,标准采用stack

    这两个题算数据结构,没什么算法可言。


     
     
    Top 
     turenjie(拉倒) ( ) 信誉:100  2005-10-5 13:26:40  得分: 0 
     
     
      
    收藏学习中......

     
     
    Top 
     xxxxxxxxx() ( ) 信誉:32  2005-10-5 13:51:39  得分: 0 
     
     
      
    MRAK

     
     
    Top 
     shrinerain(圣影雨) ( ) 信誉:100  2005-10-5 16:22:11  得分: 0 
     
     
      
    to top1000(天天向上)
    呵呵,今天去华为面试了,全是些算法题,而且考的太细致了。人又多,实在没意思,等了会就走了!
    现在还记得最后两道:
    1。有个字符串,下个函数删除从i开始后j个字符。
    c++数据结构解法,一般都是考这些。。。
    #include <iostream>
    #include <list>
    using namespace std;
    int main()
    {
    string myName="shrinerain";
             list <char> myList;
    list <char>::iterator curr=myList.begin();
    for (int m=0;m<myName.length();++m)
    {
    myList.insert(curr,myName[m]);
    }
    int i=5;//第5个开始
    int j=3;//删除三个字符
    int n=0;
    curr=myList.begin();
    while (n<=i+j)
    {
    if (n<=i)
    {
    curr++;
    }
    else
    {
    curr=myList.erase(curr);
    }
    ++n;
    }
    curr=myList.begin();
    while (curr!=myList.end())
    {
    cout<<*curr;
    curr++;
    }
    cin.get();
    return 0;
    }

    c#解法:
                       string myName="shrinerain";
     int i=5;//第5个开始删除
     int j=3;//删除3个
     string myName2=myName.Substring(0,i)+myName.Substring(i+j,myName.Length-i-j);
     Console.WriteLine(myName2);

    2。写个方法判断什么是对称数。比如121,34543,6678766
    #include <iostream>
    #include <stack>
    using namespace std;
    int main()
    {
    string myName="ssass";
             stack <char> myStack;
    for (int i=0;i<myName.length();++i)
    {
    if(i<myName.length()/2)
        myStack.push(myName[i]);
    else
    {
    if (myName[i]==myStack.top())
    {
    myStack.pop();
    }
    }
    }
        if (myStack.empty())
        cout<<"Yes!";
    else
        cout<<"No!";
    cin.get();
    return 0;
    }

    c#版本
      string myName="ssahss";
     bool flag=true;
     int i=0;
     while(i<myName.Length/2)
    {
       string tempStr=myName.Substring(i,myName.Length-2*i);
       if(tempStr.Substring(0,1)!=tempStr.Substring(tempStr.Length-1,1))
                        flag=false;
       ++i;
    }
    if(flag==true)
    Console.WriteLine("Yes!");
    else
    Console.WriteLine("No!");

     
     
    Top 
     renyu732(Sysinfo) ( ) 信誉:100  2005-10-5 17:01:51  得分: 0 
     
     
      
    还不错.

     
     
    Top 
     renepeng(边用边学asp.net) ( ) 信誉:100  2005-10-5 17:03:28  得分: 0 
     
     
      
    不错,收藏

     
     
    Top 
     sqfeiyu(流星雨) ( ) 信誉:100  2005-10-6 8:41:24  得分: 0 
     
     
      
    樓上的C#算法實在~~~~~~
    1。有个字符串,下个函数删除从i开始后j个字符
    string stmp="asdfghj";
    stmp.Remove(i,j);

    2。写个方法判断什么是对称数。比如121,34543,6678766。
    string sTmp="asdfgfdsa";
    Array.Reverse(sTmp.ToCharArray());
    System.Text.StringBuilder stb=new System.Text.StringBuilder("");
    if(sTmp==stb.Append(Array.Reverse(sTmp.ToCharArray())).ToString())
        return true;
    else
        return false;


     
     
    Top 
     zhangfire(色狼也可以学.net) ( ) 信誉:100  2005-10-6 9:24:11  得分: 0 
     
     
      
    mark

     
     
    Top 
     love_2008(信天游) ( ) 信誉:100  2005-10-6 10:22:12  得分: 0 
     
     
      
    这么多高人在此
    小弟就不现丑了
    看了这些面试题,
    看样我要看基础的东西了
    要不找工作就完蛋了呀??
    学习。。。。。。。。。。。。。。。。。。。。

     
     
    Top 
     leib_0474(夜之絮语) ( ) 信誉:100  2005-10-6 12:10:18  得分: 0 
     
     
      
    我还是标记一下的好

     
     
    Top 
     guenli() ( ) 信誉:100  2005-10-8 9:32:29  得分: 0 
     
     
      
    真的有史以来的好贴啊

     
     
    Top 
     Alang_79(欲寄相思千点泪,流不到,楚江东。) ( ) 信誉:100  2005-10-8 10:03:14  得分: 0 
     
     
      
    标记一下

     
     
    Top 
     hualin(林子) ( ) 信誉:100  2005-10-8 10:22:09  得分: 0 
     
     
      
    不错,收藏

     
     
    Top 
     lmz2004_01(数据孤岛) ( ) 信誉:94  2005-10-8 10:31:54  得分: 0 
     
     
      
    期待答案中

     
     
    Top 
     seekg() ( ) 信誉:100  2005-10-8 11:20:51  得分: 0 
     
     
      
    旁听

     
     
    Top 
     lih163(做自己喜欢的事) ( ) 信誉:87  2005-10-8 11:43:14  得分: 0 
     
     
      

     
     
    Top 
     chaobeyond(冷雪) ( ) 信誉:100  2005-10-8 11:45:52  得分: 0 
     
     
      
    楼主辛苦了!

     
     
    Top 
     fredlin(fred) ( ) 信誉:100  2005-10-8 11:52:13  得分: 0 
     
     
      
    hehe

     
     
    Top 
     net205(向MVP学习!) ( ) 信誉:100  2005-10-8 12:02:28  得分: 0 
     
     
      
    收藏了。。。

     
     
    Top 
     fanweiwei(黑暗凝聚力量,堕落方能自由) ( ) 信誉:100  2005-10-9 8:41:19  得分: 0 
     
     
      
    我再顶一下

     
     
    Top 
     Cry_Out(东北) ( ) 信誉:100  2005-10-9 9:25:57  得分: 0 
     
     
      
    mark

     
     
    Top 
     xiaxilin(good good study, day day up!) ( ) 信誉:100  2005-10-9 9:33:34  得分: 0 
     
     
      
    mark

     
     
    Top 
     morou_007(默柔) ( ) 信誉:100  2005-10-9 9:37:42  得分: 0 
     
     
      
    mark

     
     
    Top 
     bwtlyzl123(想飞的水) ( ) 信誉:100  2005-10-9 10:02:23  得分: 0 
     
     
      
    re

     
     
    Top 
     luoshulin(草莽) ( ) 信誉:100  2005-10-9 10:28:23  得分: 0 
     
     
      
    mark

     
     
    Top 
     davidyoung821(随云) ( ) 信誉:98  2005-10-9 11:20:14  得分: 0 
     
     
      
    我只能做个记号了!

     
     
    Top 
     pshy(无心) ( ) 信誉:100  2005-10-9 11:38:27  得分: 0 
     
     
      
    好东西,收藏起来~~

     
     
    Top 
     Liao_0769(路人甲) ( ) 信誉:100  2005-10-10 8:27:37  得分: 0 
     
     
      
    感謝!!!

     
     
    Top 
     julong88((无锋之刃)) ( ) 信誉:100  2005-10-10 8:51:28  得分: 0 
     
     
      
    其实很多问题很扯蛋

     
     
    Top 
     xjking0331(Michael J) ( ) 信誉:100  2005-10-10 14:54:44  得分: 0 
     
     
      
    up

     
     
    Top 
     copine() ( ) 信誉:100  2005-10-10 15:20:59  得分: 0 
     
     
      
    现在不能收藏了吗?只能mark一下了。

     
     
    Top 
     itmingong(nous+wisdom+courage) ( ) 信誉:100  2005-10-10 16:10:12  得分: 0 
     
     
      
    mark

     
     
    Top 
     emedpengy(风云天下) ( ) 信誉:100  2005-10-10 17:25:47  得分: 0 
     
     
      
    实在是强,没得说,如果这是我得面试题,那我完了,回农村养猪算了。为了不回家养猪,大家还是找个事件一起切磋一下这些题目。

     
     
    Top 
     smallfish382(肖洁) ( ) 信誉:100  2005-10-10 19:41:00  得分: 0 
     
     
      
    找本讲理论的知识,狂啃算了———
      还有就是经验,经验重要啊!!

     
     
    Top 
     chenxy80(陈陈) ( ) 信誉:99  2005-10-10 19:50:19  得分: 0 
     
     
      
    同意smallfish382
    要理论啊

     
     
    Top 
     MaxIE(MaxIE) ( ) 信誉:100  2005-10-10 19:54:24  得分: 0 
     
     
      
    学习学习

     
     
    Top 
     sunbin6ji(刹那烟火) ( ) 信誉:100  2005-10-10 20:19:43  得分: 0 
     
     
      
    mark

     
     
    Top 
     zwlippi(里皮) ( ) 信誉:100  2005-10-14 15:28:59  得分: 0 
     
     
      
    事务是作为单个逻辑工作单元执行的一系列操作,要么全部执行,要么全部不执行...

     
     
    Top 
     chinazp(c#学习群【86013083】欢迎高手指点) ( ) 信誉:100  2005-10-14 15:47:58  得分: 0 
     
     
      
    收藏!
    好东西,从头学习。


     
     
    Top 
     fqhappier(疯清) ( ) 信誉:100  2005-10-18 9:02:04  得分: 0 
     
     
      
    多谢

     
     
    Top 
     GmLibra(平常心) ( ) 信誉:100  2005-10-18 9:08:38  得分: 0 
     
     
      
    收了

     
     
    Top 
     LGame(JGame) ( ) 信誉:100  2005-10-18 10:29:31  得分: 0 
     
     
      
    帮顶

     
     
    Top 
     me4tic(昵称) ( ) 信誉:100  2005-10-18 11:07:28  得分: 0 
     
     
      
    赞!!!

     
     
    Top 
     yzh0523(水手) ( ) 信誉:95  2005-10-18 11:18:53  得分: 0 
     
     
      
    Mark

     
     
    Top 
     claus2001(古风) ( ) 信誉:100  2005-10-18 12:53:07  得分: 0 
     
     
      
    mark

     
     
    Top 
     kension() ( ) 信誉:100  2005-10-18 13:32:43  得分: 0 
     
     
      
    受益非浅!回家去慢慢做。

     
     
    Top 
     mathsword(梦在流浪) ( ) 信誉:100  2005-10-18 13:45:49  得分: 0 
     
     
      
    又被顶上来了

     
     
    Top 
     wingnal(清淡天和) ( ) 信誉:100  2005-10-18 13:54:56  得分: 0 
     
     
      
    兄弟们帮忙看看这个
    http://community.csdn.net/Expert/topic/4333/4333138.xml?temp=.3283655

     
     
    Top 
     gb_boy(该昵称太帅_系统拒绝显示) ( ) 信誉:100  2005-10-18 13:59:49  得分: 0 
     
     
      
    好文,做个记号!

     
     
    Top 
     lliuxxingw(lliuxxingw) ( ) 信誉:100  2005-10-19 14:24:33  得分: 0 
     
     
      
    好好看看,有帮忙

     
     
    Top 
     wujinzhou(吴风) ( ) 信誉:100  2005-10-19 14:43:36  得分: 0 
     
     
      
    好贴啊,


     
     
    Top 
     xu770(我爱鱼儿) ( ) 信誉:100  2005-10-19 14:45:02  得分: 0 
     
     
      
    好人啊!

     
     
    Top 
     quanyi(长生天) ( ) 信誉:100  2005-10-19 14:47:05  得分: 0 
     
     
      
    mark

     
     
    Top 
     mybobby(天天晴) ( ) 信誉:100  2005-10-19 14:51:13  得分: 0 
     
     
      
    收~~

     
     
    Top 
     cestar2005(往事随风) ( ) 信誉:99  2005-10-19 15:07:56  得分: 0 
     
     
      
    UP

     
     
    Top 
     holym(小雨) ( ) 信誉:100  2005-10-19 15:14:27  得分: 0 
     
     
      
    mark

     
     
    Top 
     wendy_fw(文子) ( ) 信誉:100  2005-10-19 15:19:21  得分: 0 
     
     
      
    up

     
     
    Top 
     boylez(boylez) ( ) 信誉:100  2005-10-19 15:21:43  得分: 0 
     
     
      
    mark


     
     
    Top 
     Simonzy(寒冰石) ( ) 信誉:100  2005-10-19 16:31:34  得分: 0 
     
     
      
    up

     
     
    Top 
     maboy007(磨剑中) ( ) 信誉:100  2005-10-20 0:59:12  得分: 0 
     
     
      
    2。请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。
    可以在网页增加属性,通过 属性传值


     
     
    Top 
     coffeeant(喝咖啡的蚂蚁) ( ) 信誉:100  2005-10-20 9:37:38  得分: 0 
     
     
      
    mark

     
     
    Top 
     Naola2001(摆地摊.Net) ( ) 信誉:93  2005-10-21 10:34:54  得分: 0 
     
     
      
    mark


     
     
    Top 
     dcrensky(想象乡相) ( ) 信誉:100  2005-10-21 16:55:53  得分: 0 
     
     
      
    顶上去大家看

     
     
    Top 
     pupo(泡泡) ( ) 信誉:100  2005-10-21 17:04:21  得分: 0 
     
     
      
    mark

     
     
    Top 
     diandian82(点点) ( ) 信誉:99  2005-10-21 19:10:08  得分: 0 
     
     
      
    ok

     
     
    Top 
     wanjun830(Spider) ( ) 信誉:97  2005-10-21 19:27:57  得分: 0 
     
     
      
    全专业的呀
    一个也不会
    有作品不知道有没有人要?!

     
     
    Top 
     yeerh(边城浪) ( ) 信誉:100  2005-11-8 20:50:09  得分: 0 
     
     
      
    好帖,莫沉了,顶上切.......
    明天面试..看了这些问题...感觉悬啊...

     
     
    Top 
     Hemee() ( ) 信誉:98  2005-11-8 23:17:43  得分: 0 
     
     
      
    Mark

     
     
    Top 
     kapil() ( ) 信誉:80  2005-11-9 0:25:35  得分: 0 
     
     
      
    mark

     
     
    Top 
     cshmai(四海为家) ( ) 信誉:100  2005-11-9 1:09:28  得分: 0 
     
     
      
    问题这么多?楼主辛苦了!顶

     
     
    Top 
     amethyst8989(紫水晶) ( ) 信誉:100  2005-11-9 1:17:09  得分: 0 
     
     
      
    up

     
     
    Top 
     baffling(迷茫困惑中) ( ) 信誉:100  2005-11-9 11:37:12  得分: 0 
     
     
      
    gz

     
     
    Top 
     min_jie(止戈) ( ) 信誉:100  2005-11-9 12:04:46  得分: 0 
     
     
      
    作个记号,学习一下。。

     
     
    Top 
     huancaimihai(幻彩谜海) ( ) 信誉:100  2005-11-9 12:10:36  得分: 0 
     
     
      
    哈哈,我会的问题在个位数!惨啊……

     
     
    Top 
     oriega() ( ) 信誉:100  2005-11-9 12:13:08  得分: 0 
     
     
      
    mark...
    好贴,顶...
    学习中....

     
     
    Top 
     dcrensky(想象乡相) ( ) 信誉:100  2005-11-17 17:19:34  得分: 0 
     
     
      
    贴,顶...

     
     
    Top 
     beyondtkl(大龙驹<*想好好学学CPP*>) ( ) 信誉:100  2005-11-17 17:26:59  得分: 0 
     
     
      
    HOHO hao...

     
     
    Top 
     ljasmine(无妄) ( ) 信誉:100  2005-11-17 17:34:32  得分: 0 
     
     
      
    up

     
     
    Top 
     BigIdiot628(大笨蛋,谁叫你不努力!) ( ) 信誉:95  2005-11-17 17:37:46  得分: 0 
     
     
      
    太长了,看晕了。
    学习中

     
     
    Top 
     shine_88() ( ) 信誉:100  2005-11-26 2:32:33  得分: 0 
     
     
      
    谢谢!

     
     
    Top 
     shine_88() ( ) 信誉:100  2005-11-26 2:36:02  得分: 0 
     
     
      
    我星期一就要去面试了,不知道会考什么样的题?应届的。我同学面试都是一些智力方面的题,比如测量东方电视塔之类的,量杯子重量。。。。。。。

     
     
    Top 
     junhao_666() ( ) 信誉:100  2005-11-26 8:22:35  得分: 0 
     
     
      
    受益了 !

     
     
    Top 
     xmxcw(xmxcw) ( ) 信誉:100  2005-11-26 15:27:28  得分: 0 
     
     
      
    up

     
     
    Top 
     chenxianping(做好程序員﹐向SA發展) ( ) 信誉:95  2005-11-26 15:37:54  得分: 0 
     
     
      
    好貼

     
     
    Top 
     apollolb2005(apollo) ( ) 信誉:100  2005-11-26 15:53:39  得分: 0 
     
     
      
    好东西 顶


     
     
    Top 
     ShengNet(打败.net) ( ) 信誉:100  2005-11-26 15:55:06  得分: 0 
     
     
      
    好贴!收藏了!

     
     
    Top 
     netgyc(Maldini_fans) ( ) 信誉:100  2005-11-26 15:58:27  得分: 0 
     
     
      
    thanks!!

     
     
    Top 
     HenryGo(孺子牛) ( ) 信誉:98  2005-11-29 12:07:36  得分: 0 
     
     
      
    MAKR

     
     
    Top 
     Kenny_Glacier(冰坼) ( ) 信誉:100  2005-11-29 12:59:50  得分: 0 
     
     
      
    mark

     
     
    Top 
     crossrowman(godi) ( ) 信誉:100  2005-11-29 13:03:36  得分: 0 
     
     
      

    10天掌握ORACLE9/10g核心技术 
     


     
     
    Top 
     mybobby(天天晴) ( ) 信誉:100  2006-2-24 8:45:18  得分: 0 
     
     
      
    up

     
     
    Top 
     hy98521(11) ( ) 信誉:100  2006-2-24 9:00:32  得分: 0 
     
     
      
    up

     
     
    Top 
     hjm1980_2004(浪迹天涯) ( ) 信誉:100  2006-2-24 9:44:30  得分: 0 
     
     
      
    我感觉有太多不懂了,实在惭愧呀!

     
     
    Top 
     LGame(JGame) ( ) 信誉:100  2006-2-24 10:25:15  得分: 0 
     
     
      
    答案呢?

     
     
    Top 
     Night_Elf(风暴虫) ( ) 信誉:105  2006-2-24 10:39:54  得分: 0 
     
     
      
    只为占个位置

     
     
    Top 
     yf1025(小桥,流水,人家) ( ) 信誉:100  2006-2-24 10:46:56  得分: 0 
     
     
      
    占个位啊

     
     
    Top 
     gxingmin(小高) ( ) 信誉:84  2006-2-24 11:11:33  得分: 0 
     
     
      
    好帖,学习

     
     
    Top 
     rxx(CSER) ( ) 信誉:99  2006-2-24 11:23:35  得分: 0 
     
     
      
    好贴啊

     
     
    Top 
     xiaoxiaoshan(萧萧) ( ) 信誉:100  2006-2-24 11:29:37  得分: 0 
     
     
      
    ASP。NET与ASP相比,主要有哪些进步?
    asp.net 支持界面和代码分离;
      可以利用IDE进行快速开发;
      编译执行速度快;
      可重用性代码的封装好
     


     
     
    Top 
     xiaoxiaoshan(萧萧) ( ) 信誉:100  2006-2-24 11:31:16  得分: 0 
     
     
      
    ADO。NET相对于ADO等主要有什么改进?
    增加了面向对象的结构

     
     
    Top 
     xiaoxiaoshan(萧萧) ( ) 信誉:100  2006-2-24 11:32:29  得分: 0 
     
     
      
    第八,GC是什么? 为什么要有GC?
    垃圾回收
    释放被视为垃圾的内存

     
     
    Top 
     giggsjw(秋叶) ( ) 信誉:100  2006-2-24 11:46:16  得分: 0 
     
     
      
    看了,不懂的东西太多了,看来得好好学习下这些基础知识了

     
     
    Top 
     jijl2001(jijl2001) ( ) 信誉:100  2006-2-24 11:47:46  得分: 0 
     
     
      
    如果都用这种题目,那还有几人

     
     
    Top 
     lingbo_wx(上海小浪人) ( ) 信誉:100  2006-2-24 13:22:21  得分: 0 
     
     
      
    看来基础知识还是很重要的
    不能光会code

     
     
    Top 
     qwerttyy(猫猫抱抱狗狗跳跳) ( ) 信誉:101  2006-2-24 13:36:01  得分: 0 
     
     
      
    我倒,做了这么久开发,只会答几个题。

     
     
    Top 
     zeusvenus(清柳)(C#/ASP.NET) ( ) 信誉:128  2006-2-24 13:37:29  得分: 0 
     
     
      
    置顶了,也许有兄弟需要!

     
     
    Top 
     Rail100(It's a good day to die)(能忘掉结果,未能忘记遇上) ( ) 信誉:100  2006-2-24 14:03:13  得分: 0 
     
     
      
    mark
    虽然很基础,但有些很实用

     
     
    Top 
     Qqwwee_Com(http://qqwwee.com) ( ) 信誉:100  2006-2-24 14:12:11  得分: 0 
     
     
      
    mark下。

     

    ====CSDN 小助手 V2.5 ====
    CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件
    速度快;使用方便;提供源代码。
    界面:http://blog.csdn.net/Qqwwee_Com/category/146601.aspx
    下载:http://szlawbook.com/csdnv2

     

     
     
    Top 
     v888(做鬼也风流) ( ) 信誉:100  2006-2-24 14:20:56  得分: 0 
     
     
      
    mark`

     
     
    Top 
     lingfeng0626(网络游侠) ( ) 信誉:78  2006-2-24 14:23:45  得分: 0 
     
     
      
    部分答案:

    1. C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?
    一个是属性,用于存取类的字段,一个是特性,用来标识类,方法等的附加性质

    2. 讲一讲你理解的web service,在dot net framework中,怎么很好的结合xml?(讲概念就行了)
    不会,正在学习中

    3. C#, Java 和 c++的特点,有什么相同的地方,不同的地方,C#分别从c++和java中吸取了他们那些优点?
    相同点:都是C系的,都是面向对象
    不同点:Java,C#都是建立在虚拟机机制上,而C++不是

    4. C#可否对内存进行直接的操作?(这可是个难点哦?要注意!)
    可以

    5. 用Visual C++ 6.0编写的代码(unmanaged code),如何在CLR下和其他dot net component结合?
    编译Dll,[DLLImport]

    6. 以前作过的一些项目?介绍一下自己的编程经验。(这是蒙混不过去的,基本一问就知道是真是假)
    7. 你对公司有什么期望?你的薪水期望值?为什么学计算机?以前的工作经验(这非常重要)?

    Q3: 维护数据库的完整性、一致性、你喜欢用触发器还是自写业务逻辑?为什么
    触发器,性能好,事务性

    Q4:ADO。NET相对于ADO等主要有什么改进?
    新增dataset等,不需要随时保持连接,性能提高

    Q5:ASP。NET与ASP相比,主要有哪些进步?
    asp解释形,aspx编译型,性能提高,有利于保护源码

    Q6:C#中的委托是什么?事件是不是一种委托?
    委托是一种安全的函数指针,事件是一种消息机制

    Q7:描述一下C#中索引器的实现过程,是否只能根据数字进行索引?
    不会

    Q8:C#中要使一个类支持FOREACH遍历,实现过程怎样?
    实现一个接口

    Q10:写一个HTML页面,实现以下功能,左键点击页面时显示“您好”,右键点击时显示“禁止右键”。并在2分钟后自动关闭页面。
    JS代码

    Q11:你对XMLHTTP、WEBSERVICE 了解吗?简单描述其特点、作用
    xmlhttp可以主动获取远端web代码,类似HttpWebRequest

    Q12:接口和抽象类有什么区别?你选择使用接口和抽象类的依据是什么?
    接口用于规范,抽象类用于共性。

    Q15:UML
    统一建模语言

    Q16:面向对象的概念,主要特点
    封装,基层,多态

     

    数据库方面:

    1.存储过程和函数的区别
    存储过程是编译好的存储在数据库的操作,函数不用说了。。。

    2.事务是什么?
    具有原子性特点

    3.游标的作用?如何知道游标已经到了最后?
    指示当前记录的位置,检查NULL

    4.触发器分为事前触发和事后触发,这两种触发有和区别。语句级触发和行级触发有何区别。
    一个是操作前,一个是操作后

    1。用C#实现以下功能
    a 产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
            int[] intArr=new int[100];
    ArrayList myList=new ArrayList();
           Random rnd=new Random();
    while(myList.Count<100)
    {
     int num=rnd.Next(1,101);
     if(!myList.Contains(num))
     myList.Add(num);
    }
    for(int i=0;i<100;i++)
        intArr[i]=(int)myList[i];

    b 对上面生成的数组排序,需要支持升序、降序两种顺序
    ArrayList本身就能排序

    2。请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。
    session(viewstate) 简单,但易丢失
    application        全局
    cookie             简单,但可能不支持,可能被伪造
    input ttype="hidden"     简单,可能被伪造
    url参数                  简单,显示于地址栏,长度有限
    数据库                   稳定,安全,但性能相对弱


    3。请说明.net中的错误处理机制,并举例
    try catch final

    4。请说出强名的含义
    具有自己的key,可以在GAC为公用

    5。请列出c#中几种循环的方法,并指出他们的不同
    for wile foreach

    6。请指出.net中所有类型的基类
    object

    7。请指出GAC的含义
    全局程序集缓存

    8。SQL SREVER中,向一个表中插入了新数据,如何快捷的得到自增量字段的当前值
    select @@id... 什么的,忘了

    您在什么情况下会用到虚方法?它与接口有什么不同?
    前面已说

    Q:Override与重载有什么区别?
    一个是重写父类函数,一个是同一个函数的几种形式

    Q:值类型与引用类型有什么区别?
    值和指针的区别

    Q:怎样理解静态变量?
    所有实例公用一个的变量

    Q:向服务器发送请求有几种方式?
    get post

    Q:DataReader与Dataset有什么区别?
    一个是只能向前的只读游标,一个是内存中的表

    Q:如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理?
    input type=""
    url
    数据库

    Q:用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层?
    三层,表现,逻辑,数据, 安全性,维护性

    Q:软件开发过程一般有几个阶段?每个阶段的作用?
    需求分析,架构设计,代码编写,QA,部署

    Q:请列举一些您用到过的设计模式以及在什么情况下使用该模式?
    著名的singleton


    Q:您对编程的兴趣如何?工作中遇到不懂的问题是怎样去解决的?您一般怎样去提高自己的编程水平?
    Q:您离职的原因是什么?
    Q:通过超链接怎样传递中文参数?
    URLEncode URLDecode

    Q:请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
    foreach

    1.有哪几种方法可以实现一个类存取另外一个类的成员函数及属性,并请举列来加以说明和分析.
    同一个名称控件直接,或者反射

    2.如果需记录类的实例个数,该如何实现,请写一个简单的类于以证明.
    const static int classNum=0;
    classNum++;

    3.A类是B类的基类,并且都有自己的构造,析构函数,请举例证明B类从实例化到消亡过程中构造,析构函数的执行过程.
    构造先父后子,析够反之

    4.需要实现对一个字符串的处理,首先将该字符串首尾的空格去掉,如果字符串中间还有连续空格的话,仅保留一个空格,即允许字符串中间有多个空格,但连续的空格数不可超过一个.
    string inputStr=" xx   xx  ";
    inputStr=Regex.Replace(inputStr.Trim()," *"," ");

     

     
     
    Top 
     lingfeng0626(网络游侠) ( ) 信誉:78  2006-2-24 14:24:02  得分: 0 
     
     
      
    二.简答题
    1.在c#中using和new这两个关键字有什么意义,请写出你所知道的意义?using 指令 和语句 new 创建实例 new 隐藏基类中方法
    using 引入名称空间或者使用非托管资源
    new 新建实例或者隐藏父类方法

    4.谈谈类和结构的区别?
    类是引用类型、结构是值类型

    5.一个长度为10000的字符串,通过随机从a-z中抽取10000个字符组成。请用c#语言编写主要程序来实现。
    和前面那个差不多,一样

    6.对于这样的一个枚举类型:
    enum Color:byte{
    Red,
    Green,
    Blue,
    Orange
    }
    string[] ss=Enum.GetNames(typeof(Color));
    byte[] bb=Enum.GetValues(typeof(Color));
    试写一段程序显示出枚举类型中定义的所有符号名称以及它们对应的数值。
    foreach

    9.什么叫做SQL注入,如何防止?请举例说明。
    利用sql关键字对网站进行攻击。过滤关键字'等

    10.下面这段代码输出什么?为什么?
    int i=5;
    int j=5;
    if (Object.ReferenceEquals(i,j))
    Console.WriteLine("Equal");
    else
    Console.WriteLine("Not Equal");
    //不相等,因为比较的是对象

    1.写一个实现对一段字符串翻转的方法,附加一些条件,如其中包括“,”、“.”,对其设计测试用例 。
    inputStr=inputStr.ToCharArray().Reverse().ToString();

    2.对一支纸杯设计测试用例(可以是广义的杯,不一定是某一支特定功能的杯)
    太宽了。。。

    开发语言概念题
    3.什么是反射?
    动态获取程序集信息

    4.用Singleton如何写设计模式
    static属性里面new ,构造函数private

    5.C#中的垃圾回收机制是怎样的?
    三个generation,当每个generation内存满了的时候检查引用,无引用就回收内存

    6.什么是Application Pool?
    Web应用,类似Thread Pool,提高并发性能

    7.链表和数组的区别,各有什么优缺点.
    一个可以动态增长,一个固定(VB中可以Redim),性能数组教好

    8.Remoting在客户端服务器怎么实现 ?
    9.什么是友元函数?
    friendly声明,可以访问protect级别方法

    11.什么是虚函数?
    可以被重写

    12.什么是抽象函数?
    必须被重写

    13.什么是内存泄漏,怎样最简单的方法判断被存泄漏 ?
    C++,C中忘了释放内存,内存不会再次分配

    数据库知识题
    17.使用什么工具来调用存储过程
    任何一种语言

    18.SQL Server的两种索引是何形式?索引的作用?索引的优缺点?
    cluster和非cluster,加速查找,占用额外控件,维护索引耗费时间

    19.触发器的作用
    保证数据库操作变更能接到通知

    其它知识题及问题
    20.什么是Web Service?
    使应用程序在整个网上可以被调用

    21.什么是XML?
    可扩展标记语言,可以做配置文件,可以传输数据,可以存储数据

    22.Socket怎么实现?
    这个不知道怎么说了。。。

     

    补充中:

    1.面向对象的思想主要包括什么?
    面向对象三大特征:继承,封套,多态.面相对象的思想也不是一句两句就能说清楚..主要思想就是减少代码重复,增大代码复用率..

    2.什么是ASP.net中的用户控件
    问这样的问题,一般是迷惑你.因为新手还是分不清楚用户控件和服务器控件(也称自定义控件)..用户控件一般用在内容多为静态,或者少许会改变的情况下..用的比较大..类似ASP中的include..但是功能要强大的多..

    3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?
    这个需要当前描述了..东西太多..打字要打死了..找个比较简单的说说吧!
    CTS:公共类型系统.主要是为了语言之间的进行标准化处理.
    CLS:公共语言规范.主要是确保代码可以在任何语言中访问的最小标准集体
    CLR:公共语言运行时.主要是管理代码..处理,加载代码,以及所有服务的代码

    4.列举一下你所了解的XML技术及其应用
    xml用于配置,用于保存静态数据类型.接触XML最多的是web Services..和config

    5.值类型和引用类型的区别?写出C#的样例代码。
    值类型是在内存中保存,引用类型是在内存中保存一副本.你在内存中可以有多个某种引用对象..但是值类型始终只有一个.
    最常见的值类型就是static,struct;
    例如:
    static int aa = 1;//值类型
    如果多个用户改变aa的值则,aa的值会以最后一个修改的记录为准.其他人的修改则会被冲掉.
    引用类型,最能说明问题的就是实例化..你new出来的对象单独分配一个独立的内存..所以值不会互相冲突/
    具体的区别参考我的文章:http://lixianhuei.cnblogs.com/archive/2005/08/31/227274.html

    6.ADO.net中常用的对象有哪些?分别描述一下。
    Connection 数据库连接对象
    Command 数据库命令
    DataReader 数据读取器
    DataSet 数据集

    7.如何理解委托?
    委托的概念,最好的说明就是事件.因为事件使用的就是委托.例如:this.Load += new System.EventHandler(this.Page_Load);这个就是使用了一个委托.
    具体的用法请参考.我以前的帖子,设计猫鼠联动..

    8.C#中的接口和类有什么异同。
    类是方法功能的实现和集合,接口是规范类.约束类.
    参考我的文章:http://lixianhuei.cnblogs.com/archive/2005/08/04/207123.html

    9.。net中读写数据库需要用到哪些类?他们的作用
    看第六题..答案差不多

    10.UDP连接和TCP连接的异同。
    这个说不清楚.

    11.ASP.net的身份验证方式有哪些?分别是什么原理?
    window验证:为每个用户开启window帐号,验证其身份.安全性较高.
    forms验证:为每个登陆用户写入一个身份验证票据..在web使用最广的验证方式..灵活方便.

    12.进程和线程分别怎么理解?
    这个是新人最容易迷惑的东西..
    进程:Process

    13.什么是code-Behind技术。
    新建一个VS.NET下的项目..看到ASPX,RESX和CS三个后缀的文件了吗??这个就是代码分离.实现了HTML代码和服务器代码分离.方便代码编写和整理.

    14.活动目录的作用。
    活动目录是window2000的最重要的功能.可以将用户信息全部集成起来,登陆以后可以访问多个不同的网络服务..没深入研究过.
    查看一下帖子:http://www.ies.impu.edu.cn/resource/os/windowsx/WindowsGeneral/WinGeneral0008.htm

    15..net中读写XML的类都归属于哪些命名空间?
    System.XML类

    16.解释一下UDDI、WSDL的意义及其作用。
    解释不清楚了..又是一大块..

    17.什么是SOAP,有哪些应用。
    simple object access protocal,简单对象接受协议.以xml为基本编码结构,建立在已有通信协议上(如http,不过据说ms在搞最底层的架构在tcp/ip上的soap)的一种规范
    是微软大力推广的Web Service使用的协议..

    18.如何部署一个ASP.net页面。
    不清楚问的什么意思...如果非要回答的话,就写一个带.aspx的后缀文件..然后安装IIS和FrameWork环境..浏览就好了.

    19.如何理解.net中的垃圾回收机制。
    垃圾回收体制如下:
    如果发现内存不够,则垃圾回收器,将全部对象作为无效对象(被回收对象),然后先将全局变量,static,处于活动中的局部变量,以及当前CG指针指向的对象放入一个表中.然后
    会搜索新列表中的对象所引用的对象.加入列表中,其他没有被加入列表的对象都会被回收.

    20.常用的调用webservice方法有哪些?
    我一般用的是WSDL..或者web引用..

     


    呵呵,今天去华为面试了,全是些算法题,而且考的太细致了。人又多,实在没意思,等了会就走了!
    现在还记得最后两道:
    1。有个字符串,下个函数删除从i开始后j个字符。
    c++数据结构解法,一般都是考这些。。。
    #include <iostream>
    #include <list>
    using namespace std;
    int main()
    {
    string myName="shrinerain";
             list <char> myList;
    list <char>::iterator curr=myList.begin();
    for (int m=0;m<myName.length();++m)
    {
    myList.insert(curr,myName[m]);
    }
    int i=5;//第5个开始
    int j=3;//删除三个字符
    int n=0;
    curr=myList.begin();
    while (n<=i+j)
    {
    if (n<=i)
    {
    curr++;
    }
    else
    {
    curr=myList.erase(curr);
    }
    ++n;
    }
    curr=myList.begin();
    while (curr!=myList.end())
    {
    cout<<*curr;
    curr++;
    }
    cin.get();
    return 0;
    }

    c#解法:
                       string myName="shrinerain";
     int i=5;//第5个开始删除
     int j=3;//删除3个
     string myName2=myName.Substring(0,i)+myName.Substring(i+j,myName.Length-i-j);
     Console.WriteLine(myName2);

    2。写个方法判断什么是对称数。比如121,34543,6678766
    #include <iostream>
    #include <stack>
    using namespace std;
    int main()
    {
    string myName="ssass";
             stack <char> myStack;
    for (int i=0;i<myName.length();++i)
    {
    if(i<myName.length()/2)
        myStack.push(myName[i]);
    else
    {
    if (myName[i]==myStack.top())
    {
    myStack.pop();
    }
    }
    }
        if (myStack.empty())
        cout<<"Yes!";
    else
        cout<<"No!";
    cin.get();
    return 0;
    }

    c#版本
      string myName="ssahss";
     bool flag=true;
     int i=0;
     while(i<myName.Length/2)
    {
       string tempStr=myName.Substring(i,myName.Length-2*i);
       if(tempStr.Substring(0,1)!=tempStr.Substring(tempStr.Length-1,1))
                        flag=false;
       ++i;
    }
    if(flag==true)
    Console.WriteLine("Yes!");
    else
    Console.WriteLine("No!");

     
     
    Top 
     din1001(技术还是非技术?) ( ) 信誉:100  2006-2-24 14:28:15  得分: 0 
     
     
      
    mark

     
     
    Top 
     half_bucket(半桶水) ( ) 信誉:100  2006-2-24 15:26:09  得分: 0 
     
     
      
    很多概念不看就模糊了!

     
     
    Top 
     cgzwwy(王伟晔) ( ) 信誉:100  2006-2-24 15:41:16  得分: 0 
     
     
      
    从面试的问题 看到 ,中国依然 落后很多 ,人家都已经 解决 问题了 ,而中国人还在 背唐诗

     
     
    Top 
     mabuchi() ( ) 信誉:100  2006-2-24 18:20:16  得分: 0 
     
     
      
    模糊

     
     
    Top 
     Kevin_jun() ( ) 信誉:100  2006-2-24 19:00:26  得分: 0 
     
     
      
    收藏

     
     
    Top 
     alang_jj(阿郎) ( ) 信誉:100  2006-2-24 19:26:33  得分: 0 
     
     
      
    谢谢,收下了.正想换工作...

     
     
    Top 
     asp_love(书山有路勤为径,学海无涯苦作舟) ( ) 信誉:85  2006-2-24 21:38:58  得分: 0 
     
     
      
    ding

     
     
    Top 
     whutcl8110(whut) ( ) 信誉:95  2006-2-24 21:48:00  得分: 0 
     
     
      
    收藏

     
     
    Top 
     vision_n(小聂子) ( ) 信誉:100  2006-2-24 21:57:55  得分: 0 
     
     
      
    收藏

     
     
    Top 
     hzfu007(幻影) ( ) 信誉:100  2006-2-25 8:47:05  得分: 0 
     
     
      
    好!

     
     
    Top 
     guoxinwei() ( ) 信誉:100  2006-2-25 9:50:40  得分: 0 
     
     
      
    好贴子,收藏标记一下!

     
     
    Top 
     happycoolsky(学习专用帐号) ( ) 信誉:100  2006-2-27 8:35:38  得分: 0 
     
     
      
    好贴子,收藏标记一下!

     http://ike.126.com
     
    Top 
     julong88((无锋之刃)) ( ) 信誉:100  2006-2-27 8:47:01  得分: 0 
     
     
      
    1。用C#实现以下功能
    a 产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
            int[] intArr=new int[100];
           Random rnd=new Random();
    int i = 0;
    while(i<100)
    {
     int num=rnd.Next(1,101);
    if(intArr[num]==0])
    {
    i++;
    intArr[num] = num;
    }
    }


     
     

    展开全文
  •  ... 公司一直在招聘程序员,效果一直都很不理想。我是做技术的,我以我的体会来说明一下。 1、公司是大公司,整天几百个职位挂在中国人才热线,卓博人才网上。 ... 我也找过工作,很辛苦的找过
    

    原文引自:http://group.cnblogs.com/topic/38042.html
    公司一直在招聘程序员,效果一直都很不理想。我是做技术的,我以我的体会来说明一下。
    1、公司是大公司,整天几百个职位挂在中国人才热线,卓博人才网上。
    人家看了也怕,这样的公司,是不是在做广告,或是不是真招聘人。还有的会想到,这样人员的流动率也太高了吧,还是大公司呢。 我也找过工作,很辛苦的找过工作,我一看到人家几十上百个的职位的招聘信息,我通常都不会去。如果你在深圳,肯定听说过富士康(Foxconn),这家企业为深圳的人才市场的繁荣做出了卓越的贡献,功不可末。这也不能怪他们公司太有钱,人力资源部每天总要有活可干才行。

    2、人力资源部的问题比较多。
    求职者好不容易想好了,看好了要求,开始投个人简历给公司,简历一直停滞在人力资源部职员手里。
    人力资源部对求职者的过去的工作有种与生俱来的追究爱号,问在哪里做过,做过几个项目,为什么离职,平时喜欢做些什么。其实这都是费话,烈火炼真金,关于工作经验,让开发人员问一下不就知道了,或是考核一下就可以知道大概。你问你家用过.NET,能有作用吗? 还有就是人力资源部的不懂技术,把C#(sharp)读成C井,SQL也读不出来,尽让人家看笑话。有时人力资源部要招聘员工,是开发部的boss私下决定的,估计是想开除员工,但是也不想让下面的开发员知道,贴出去的是招聘Java的要求,要会hibernate,spring,结果来面试的时候却是面试C#,ASP.NET,真不知道说什么好。
    问为什么离职,这也是费话。现在出来工作的,特别是干程序员这一行的,付出与回报不成正比的很多。
    你给人家2000块一个月,人家做了半年就走了,你只好再招聘员工,还一直抱怨人家不忠心,品德有问题。你再加一点到3000块,说好了只做程序,进来后什么需求调研,客户沟通都要你做,有时候还要帮公司折腾打印机,并且公司还理直气壮的说,这是给你机会培养你,你不要错过机会。

    一个人能擅长的就那么几件事,能做好的就那么几件事,而且工作年龄越长,就越发知道自己,只能干好那么几件事,不可能既能搞销售,也能写代码,还会懂管理。
    销售,管理,我也想干,那些做销售的,平时陪客户到处吃吃喝喝,高兴了还去KTV唱《我的未来不是梦》;做管理的,早上起来跟老婆吵架了,死板着个脸来公司上班,员工看了会觉得很压抑,平时的沟通一般都是下达命令,很少问下你对当前工作有什么好建议,有什么改善效率的办法。
    我不是不会主动去找boss提意见,我提了大家都无所谓,boss无所谓。我不是leader,管不了自己的同事,只是算是个建议。建议说久了,没有喝彩,没有响应,就再没有兴趣去提建议。

    其实作为boss的你,稍微抽点时间和下属谈下改善意见和方法,大家的工作会更有效率。
    我明白大公司里面推出一项变革,会触动一些人的工作方式和利益。大家的工作都是routine,多一天工作,少一天工作没有什么区别。既没有勇气打破常规,对当前的状态也又不满意,每天工作很压抑,心情也很压抑。工作都把人折腾的疲惫,下班回家了,还要哄老婆开心,哪里能高兴的起来。

    3、一个求职者能会的就那么几项技术,被刷掉的可能性太大。
    现在的企业招聘都指望用一个人的工资,招聘能干两个人的活的全能人才。以我的求职经验,做ASP.NET项目,还要会DreamWeaver,Flash,
    因为这个原因,我失去一些机会,但也没有觉得什么遗憾。 有的企业比较开明,说会用DW局部修改网页,这样的情况还好。如果直接说要会DIV+CSS页面布局,恐怕很多人都不适合,你这分明是招聘一个网页设计师嘛。还有的招聘,要会sharepoint,Biztalk之类的技术,而且要多年的经验,这种要求也会过滤掉很多人。还有报表,熟悉SQL Server Reporting Services制作报表,这项技术也比较偏,会的比较少,有实际经验的更少。

    4、做技术的,一般都没有那么能说会道的能力,被刷掉的可能性太大。
    做技术的,一般表达能力不算好。先经过人力资源部面试,人力资资源部看你说话小声小气的,像个蚊子在哪里嗡嗡的叫,你走了以后背后说里没信心,信心都没有,哪里敢把任务交你给做。如果你说话太张扬,又怕你只会吹水,没有实干才能,也会拒绝你。反正,你在这种HR手里,你里外都不是人,怎么做你都没有机会进来。人力资源部的没有通过,开发部都没有机会去面试你的技术能力,真是可惜。
    此外,人力资源部要卡住一些硬性的规定,比如工资不能超过4K,工作年限不能低于2年,做过的项目不能低于三个,这一条也会把很多人拒之门外。
    如果再加上开发部负责面试的员工,心胸不够宽阔,能力也不很强,但是特别喜欢虐待求职者。一上来就搞些偏门的知识考核求知者,把人家折腾的垂头丧气的,然后去告诉老板,这个人技术不行,不能用。
    我没有做到leader,没有权力去指挥他怎么面试程序员。如果换成我面试,我的指导思想是,发现人的价值,看看他会什么,能力够不够用来开发公司的项目,这些就足够了。来我这里面试,我会给你增强信心,不会去打击你。想打击你太容易了,但是这样没有任何好处,只能说明自己的心理不健康。

    5、公司承诺的多,兑现的少。
    人力资源部其实不能代表公司的,他们也是个打工的,也不知道能做到哪一天,为了完成招聘任务,拿到绩效奖金,在招聘的时候会给出一些额外的承诺,至于你进来后的情况,你就再没有机会和他对话,想追究都没有依据。
    比较常用的句型是:公司是看能力的,等你做出成绩后,公司会考虑你的合理要求。请记住,入职时工资就是你的全部。
    不要指望年终奖,不要指望项目奖。 如果公司有年假,我就很感激了。工作累了,陪老婆去旅行,回来后再高兴的工作。
    每年年底的时候大家都在吵作年终奖,其实大家心里都清楚,更多的公司是没有年终奖的。年终奖要看公司业绩,看赢利,本来开个公司这税那费的就已经很重了,还要发年终奖,来年的发展基金就更少了。 公司只有先活下来,才会考虑发展。然后考虑员工的各项福利。今年一波人走,又招聘来一波人,对技术主导型的公司伤害太多,除非技术对公司不重要,比如卖域名和空间。
    想维持一个稳定的team,把那么几个关键的员工把握住了,这项工作就做好了。当然,也要做好技术管理,把每个人的工作量化,流程化,防止核心员工真的要走,你的team一下子就瘫痪了。 做公司的,比我更懂这里面的道理,为什么做不好呢?

    6 、你的上司喜欢你,你才有得干。
    这个道理很明显,虽然有足够的技术能力可以保证你在公司的安全,但是这还不够。 进入一个新公司,公司的前辈,公司的管理层,项目组的同事,这些关系都要处理好。虽然有的前辈写代码不如你,但是你也要充分的尊重人家,不要去要求人家怎么做,怎么配合你,是你要去主动的配合人家。有的team成员可能不太喜欢你的打扮,不愿意和你沟通,时间久了,你们的距离就真的远了,这些情况你都要注意到。还有最重要的上司,平时工作怎么安排,每周要做什么报表,要主动去问。你不主动问,上司宁愿让你在那里玩,也不想告诉你该做什么。反正他也是打工的,不在乎发你几天的工资,却没有干活。倒是过几天后,你的上司会说你沟通能力有问题,工作方式有问题,以后你在公司的各方面都会有问题。这真是无奈,今天他坐在这个位置上,他要这样折腾,你一点办法也没有。 有一天你坐到他的位置上,我真希望你不学他那样。你痛苦过的岁月,然后又加倍的让别人来体会你曾经经历过的痛苦,真不值得这样做。
    最后一点,想干就留下来,不想干就走人。不要和上司做对,你这样干没有好下场。即使你如何的瞧不起你的上司,他今天坐在这个位置上,有他的道理。我经历过的几个程序员,因为与上司关系不好而被迫离开,直是惋惜不已。
    做技术的员工,很老实的在自己的岗位上工作,却因不懂办公室政治而被迫离开,而且还要说是自己有问题,公司是对的。对于一个漂在异乡的人,这给人一种很无奈的苍凉。
    招聘一个好员工不容易,找份合适的工作也不容易。
    最后,送大家一句话:众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
    再坚持一会儿,You can do it。

    转自http://group.cnblogs.com/topic/38042.html


    展开全文
  • 一份完整的useEffect指南

    万次阅读 2019-03-26 17:00:04
    本文原文:一份完整的useEffect指南 原文档: A Complete Guide to useEffect 你使用hooks写了一些组件。也许只是一个小的应用。你基本上是满意的。你对这个API游刃有余,并在此过程中学会了一些技巧。你甚至做了...

    本文太长,谨慎阅读。
    本文原文:一份完整的useEffect指南
    原文档: A Complete Guide to useEffect

    你使用hooks写了一些组件。也许只是一个小的应用。你基本上是满意的。你对这个API游刃有余,并在此过程中学会了一些技巧。你甚至做了一些自定义Hook来提取重复逻辑(300行代码消失了!)并向你的同事展示了它。他们会说,“干得好”。

    但是有时候当你使用useEffect的时候,有些部分并不完全合适。你有一种挥之不去的感觉,觉得自己错过了什么。它似乎与类生命周期相似…但它真的如此吗?你发现自己会问这样的问题:

    • ? 如何使用useEffect替代componentDidMount
    • ? 如何在useEffect中正确的获取数据?[]是什么?
    • ? 我是否需要将函数指定为效果(effect)依赖项?
    • ? 为什么有时会得到一个无限重复获取循环?
    • ? 为什么我有时会在效果(effect)中获得旧的状态或prop值?

    当我刚刚开始使用Hooks时,我也对所有这些问题感到困惑。即使在写最初的文档时,我也没有对其中的一些细节有一个很好的把握。从那以后,我有一些“啊哈”(豁然开朗)的时刻,我想和你们分享。这个的深入研究将使这些问题的答案对你来说显而易见。

    为了 到答案,我们需要后退一步。本文的目的不是给你一个方法列表去用。主要是为了帮助你真正“理解”useEffect。没有太多要学的东西。事实上,我们需要花费大部分时间去忘记学习的东西(unlearning)。

    直到我不再通过熟悉的类生命周期方法来看待useEffect Hook之后, 这一切才融会贯通。

    “忘掉你学到的东西”。— Yoda

    image


    本文假设你对useEffectAPI有点熟悉。

    本文的确很长。就像一本迷你小书。这只是我喜欢的版式。但是如果你很忙或者不在乎,我在下面写了一个TLDR供你快速了解。

    如果你对深度学习不怎么喜欢,你可能想等到这些解释出现在其他地方再学习。就像React在2013年推出时一样,人们需要一段时间才能认识到一种不同的思维模式并进行教学。


    TLDR

    如果你不想阅读整篇文章,这里有一个快速的TLDR。如果有些部分没有意义,可以向下滚动,直到找到相关的内容。

    如果你打算阅读整篇文章,可以跳过它。我会在最后链接到它。

    ? 问题:如何使用useEffect替代componentDidMount

    虽然可以用useEffect(fn, []),但它并不是完全等价的。与componentDidMount不同,它将捕获(capture) props和状态。所以即使在回调中,你也会看到最初的props和状态。如果你想看到“最新”的东西,你可以把它写到ref。但是通常有一种更简单的方法来构造代码,这样你就不必这样做了。请记住,效果(effect)的心理模型与componentDidMount和其他生命周期不同,试图找到它们的确切对等物可能会让你感到困惑,而不是有所帮助。为了提高效率,你需要“思考效果”,他们的心智模型更接近于实现同步,而不是响应生命周期事件。

    ? 问题:如何在useEffect中正确获取数据?什么是 []

    这篇文章是使用useEffect进行数据获取的一个很好的入门读物。一定要把它读完!它不像这个那么长。[]表示该效果不使用参与React数据流的任何值,因此可以安全地应用一次。当实际使用该值时,它也是一个常见的bug源。你需要学习一些策略(主要是useReduceruseCallback),这些策略可以消除对依赖项的需要,而不是错误地忽略它。

    ? 问题:我是否需要将函数指定为效果依赖项?

    建议将不需要props或状态的函数提到组件外部,并将仅由效果内部使用的函数拉出来使用。如果在此之后,你的效果仍然使用渲染范围中的函数(包括来自props的函数),那么将它们封装到定义它们的useCallback中,并重复该过程。为什么这很重要?函数可以“看到”来自props和状态的值——因此它们参与数据流。我们的常见问题解答中有更详细的答案

    ? 问题:为什么有时会得到一个无限重复获取循环?

    如果在没有第二个依赖项参数的情况下在一个效果中执行数据获取,则可能会发生这种情况。没有它,效果会在每次渲染后运行 - 设置状态将再次触发效果。如果指定的这个值始终在依赖关系数组中改变,也可能发生无限循环。你可以通过一个一个地把它们移除来辨别是哪个。但是,删除你使用的依赖项(或盲目指定[])通常是错误的修复。相反,从源头解决问题。例如,函数可能会导致这个问题,将它们放在效果中、将它们提出来或使用useCallback包装它们会有所帮助。为避免重新创建对象,useMemo可用于类似目的。

    ? 为什么我有时会在效果中获得旧的状态或props值?

    效果总是从定义的渲染中“看到”props和状态。这有助于防止错误,但在某些情况下可能会令人讨厌。对于这些情况,你可以显式地在可变ref中维护一些值(链接里的文章在最后对此进行了解释)。如果你认为你从旧的渲染中看到了一些props或状态,但并不是你期望的,那么你可能错过了一些依赖项。尝试使用lint规则来锻炼自己发现它们。过几天,它就会成为你的第二天性。请参阅常见问题解答中的此答案


    我希望这个TLDR很有帮助!否则,我们继续吧。

    每个渲染都有自己的props和状态

    在我们谈论效果之前,我们需要讨论渲染。

    这是一个counter。仔细查看突出显示的行:

    function Counter() {
      const [count, setCount] = useState(0);
    
      return (
        <div>
    +     <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    

    这是什么意思?是否count以某种方式“监视”状态的更改并自动更新? 当你学习React时,这可能是一个有用的第一直觉,但它不是一个准确的心理模型

    在此示例中,count只是一个数字。 它不是神奇的“数据绑定”,“观察者”,“代理”或其他任何东西。这是一个很古老的数字:

    const count = 42;
    // ...
    <p>You clicked {count} times</p>
    // ...
    

    我们的组件第一次渲染时,我们从useState()得到的count变量是0。当我们调用setCount(1)时,React再次调用我们的组件。这一次,count将是1。依此类推:

    // During first render
    function Counter() {
      const count = 0; // Returned by useState()
      // ...
      <p>You clicked {count} times</p>
      // ...
    }
    
    // After a click, our function is called again
    function Counter() {
      const count = 1; // Returned by useState()
      // ...
      <p>You clicked {count} times</p>
      // ...
    }
    
    // After another click, our function is called again
    function Counter() {
      const count = 2; // Returned by useState()
      // ...
      <p>You clicked {count} times</p>
      // ...
    }
    

    每当我们更新状态时,React都会调用我们的组件。每个渲染结果“看到”它自己的counter状态值,这是我们函数内的常量。

    所以这一行没有做任何特殊的数据绑定:

    <p>You clicked {count} times</p>
    

    它只是在渲染输出中嵌入一个数值。 该数字由React提供。当我们setCount时,React再次使用不同的count值调用我们的组件。然后React更新DOM以匹配我们最新的渲染输出。

    关键是,任何特定渲染中的count常量都不会随时间变化。再次调用的是我们的组件——每个渲染都“看到”自己的count值,该值在渲染之间是独立的。

    (有关此过程的深入概述,请查看我的帖子React作为UI运行时。)

    每个渲染都有自己的事件处理程序

    到现在为止还挺好。那么关于事件处理程序是怎样的?

    看看这个例子。它会在三秒钟后显示count的弹框:

    function Counter() {
      const [count, setCount] = useState(0);
    
      function handleAlertClick() {
        setTimeout(() => {
          alert('You clicked on: ' + count);
        }, 3000);
      }
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
          <button onClick={handleAlertClick}>
            Show alert
          </button>
        </div>
      );
    }
    

    假设我执行以下步骤:

    • 增加 计数到3
    • 点击 “Show alert”
    • 增加 到5,在timeout触发之前

    image

    你希望弹出框显示什么?它会显示5 - 这是弹框时的计数器状态吗?或者它会显示3 - 我点击时的状态?


    剧透


    来吧,[亲自尝试一下](try it yourself!)!

    如果这种行为对你没有意义,想象一个更实际的例子:一个聊天应用程序,当前收件人ID在状态中,并有一个发送按钮。这篇文章深入探讨了原因,但正确的答案是3。

    弹框(alert)将在我单击按钮时“捕获”状态。

    (有一些方法可以实现其他行为,但我现在将关注默认情况。当我们建立一个心理模型时,重要的是我们要区分“最小阻力路径”和选择进入逃生舱。)


    但它是如何工作的?

    我们已经讨论过count值对于我们函数的每个特定调用都是常量。值得强调的是这一点 — 我们的函数被调用了很多次(每次渲染一次),但是每次调用的count值都是常量,并被设置为一个特定的值(该渲染的状态)。

    这不是React所特有的 - 常规函数以类似的方式工作:

    function sayHi(person) {
      const name = person.name;  setTimeout(() => {
        alert('Hello, ' + name);
      }, 3000);
    }
    
    let someone = {name: 'Dan'};
    sayHi(someone);
    
    someone = {name: 'Yuzhi'};
    sayHi(someone);
    
    someone = {name: 'Dominic'};
    sayHi(someone);
    

    此示例中,外部someone变量被重新分配多次。(就像React中的某个地方一样,当前 的组件状态可以改变。) 但是,在sayHi中,有一个本地name常量与特定调用中的person相关联。 那个常量是本地的,所以它在调用之间是独立的!因此,当超时触发时,每个弹框都会“记住”他自己的name

    这解释了我们的事件处理程序如何在单击时捕获count。如果我们应用相同的替换原则,每个渲染“看到”它自己的count

    // During first render
    function Counter() {
    + const count = 0; // Returned by useState()  // ...
      function handleAlertClick() {
        setTimeout(() => {
          alert('You clicked on: ' + count);
        }, 3000);
      }
      // ...
    }
    
    // After a click, our function is called again
    function Counter() {
    + const count = 1; // Returned by useState()  // ...
      function handleAlertClick() {
        setTimeout(() => {
          alert('You clicked on: ' + count);
        }, 3000);
      }
      // ...
    }
    
    // After another click, our function is called again
    function Counter() {
    + const count = 2; // Returned by useState()  // ...
      function handleAlertClick() {
        setTimeout(() => {
          alert('You clicked on: ' + count);
        }, 3000);
      }
      // ...
    }
    

    如此有效,每个渲染都返回自己“版本”的handleAlertClick。每个版本都“记住”自己的count

    // During first render
    function Counter() {
      // ...
      function handleAlertClick() {
        setTimeout(() => {
    +     alert('You clicked on: ' + 0);
        }, 3000);
      }
      // ...
      <button onClick={handleAlertClick} /> // The one with 0 inside
      // ...
    }
    
    // After a click, our function is called again
    function Counter() {
      // ...
      function handleAlertClick() {
        setTimeout(() => {
    +     alert('You clicked on: ' + 1);
        }, 3000);
      }
      // ...
      <button onClick={handleAlertClick} /> // The one with 1 inside
      // ...
    }
    
    // After another click, our function is called again
    function Counter() {
      // ...
      function handleAlertClick() {
        setTimeout(() => {
    +     alert('You clicked on: ' + 2);
        }, 3000);
      }
      // ...
      <button onClick={handleAlertClick} /> // The one with 2 inside
      // ...
    }
    

    这就是为什么在这个演示中 事件处理程序“属于”特定渲染,当你点击时,它会继续使用 渲染中的counter状态。

    在任何特定渲染中,props和状态永远保持不变。 但是,如果在渲染之间隔离了props和状态,那么使用它们的任何值(包括事件处理程序)都是独立的。它们也“属于”特定的渲染。因此,即使事件处理程序中的异步函数也会“看到”相同的count值。

    旁注:我将具体count值内联到上面的handleAlertClick函数中。这种心理替代是安全的,因为count不可能在特定渲染中改变。它被声明为const并且是一个数字。以同样的方式考虑其他值(比如对象)是安全的,但前提是我们同意避免状态的变化。使用新创建的对象调用setSomething(newObj)而不是对其进行修改,因为属于以前渲染的状态是完整的。

    每个渲染都有自己的效果(effects)

    这应该是一个关于效果的论述,但我们还没有谈到效果!我们现在要纠正这个问题。事实证明,效果并没有什么不同。

    让我们回到文档中的一个例子:

    function Counter() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        document.title = `You clicked ${count} times`;
      });
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    

    这里有一个问题:效果如何读取最新的count状态?

    也许,有某种“数据绑定”或“观查”使得count更新在效果函数中生效?也许count是一个可变变量,React在我们的组件中设置,以便我们的效果总能看到最新值?

    不。

    我们已经知道count在特定组件渲染中是恒定(常量)的。事件处理程序从渲染中“查看”它们“所属”的count状态,因为count是它们作用域中的一个变量。效果也是如此!

    count变量不是以某种方式在“不变”效果中发生变化。效果函数本身 在每个渲染上都是不同的。

    每个版本从其“所属”的渲染中“看到”count值:

    // During first render
    function Counter() {
      // ...
      useEffect(
        // 主要是看这里
        // Effect function from first render
        () => {
          document.title = `You clicked ${0} times`;
        }
      );
      // ...
    }
    
    // After a click, our function is called again
    function Counter() {
      // ...
      useEffect(
        // 主要是看这里
        // Effect function from second render
        () => {
          document.title = `You clicked ${1} times`;
        }
      );
      // ...
    }
    
    // After another click, our function is called again
    function Counter() {
      // ...
      useEffect(
        // 主要是看这里
        // Effect function from third render
        () => {
          document.title = `You clicked ${2} times`;
        }
      );
      // ..
    }
    

    React会记住你提供的效果函数,刷新对DOM的更改并让浏览器绘制到屏幕后运行该函数。

    因此,即使我们在这里谈到单一概念的效果(示例中的更新文档标题(document.title='')),它也会在每个渲染上用不同的函数 表示 — 并且每个效果函数从它所属的特定渲染中“看到”props和状态。

    从概念上讲,你可以想象效果是 渲染结果的一部分

    严格地说,它们不是(为了允许Hook组合而没有笨拙的语法或运行时开销)。但是在我们构建的心理模型中,效果函数属于特定的渲染,就像事件处理程序一样。


    为了确保我们有一个扎实的理解,让我们回顾一下我们的第一次渲染:

    • React: 给我一个当状态为0时UI。
    • 你的组件:
      • 这是渲染结果:<p>You clicked 0 times</p>
      • 还记得在完成后运行此效果:() => { document.title = 'You clicked 0 times' }
    • React: 当然。更新UI。嘿浏览器,我正在向DOM添加一些东西。
    • Browser: 很酷,我把它画到了屏幕上。
    • React: 好的,现在我要运行你给我的效果了。
      • 运行 () => { document.title = 'You clicked 0 times' }

    现在让我们回顾点击后发生的事情:

    • 你的组件: 嘿React,把我的状态设置为1
    • React: 给我状态为1时的UI。
    • 你的组件:
      • 这是渲染结果:<p>You clicked 1 times</p>
      • 还记得在完成后运行此效果:() => { document.title = 'You clicked 1 times' }
    • React: 当然。更新UI。嘿浏览器,我改变了DOM。
    • Browser: 很酷,我把你的更改画到了屏幕上。
    • React: 好的,现在我将运行属于我刚刚做的渲染的效果。
      • 运行 () => { document.title = 'You clicked 1 times' }

    每个渲染都有它自己…一切

    我们现在知道在每次渲染之后运行的效果在概念上是组件输出的一部分,并且“看到”来自该特定渲染的props和状态。

    我们来试试吧。考虑以下代码:

    function Counter() {
      const [count, setCount] = useState(0);
    
      // 手动高亮
      useEffect(() => {
        setTimeout(() => {
          console.log(`You clicked ${count} times`);
        }, 3000);
      });
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    

    如果我稍微点击几次,那么log会是什么样子?


    剧透


    你可能认为这是一个问题,最终结果是不直观的。不是这样的!我们将看到一系列日志 - 每个日志属于特定的渲染,因此具有自己的count值。你可以自己试试

    image

    你可能会想:“当然,这就是它的工作原理!不然它还能怎样工作?“

    好吧,这不是this.state在类上的运作方式。很容易错误地认为这个类的实现是等价的:

    componentDidUpdate() {
      setTimeout(() => {
        console.log(`You clicked ${this.state.count} times`);
      }, 3000);
    }
    

    但是,this.state.count始终指向最新计数而不是属于特定渲染的计数。所以你会看到每次记录5

    image

    我认为具有讽刺意味的是,Hook严重依赖于JavaScript闭包,然而正是类实现遭受了典型的超时错误值的混淆,而这种混淆通常与闭包相关。这是因为本例中混淆的实际来源是突变(react使类中的this.state发生突变,以指向最新状态),而不是闭包本身。

    当你相关的值永远不变时,闭包是非常棒的。这使得它们易于思考,因为你实质上是指向常量。 正如我们所讨论的,props和状态永远不会在特定渲染中发生变化。顺便说一句,我们可以通过使用闭包修复类版本中的问题。

    逆势而行(逆流而上)(Swimming Against the Tide)

    在这一点上,我们明确地称之为:组件渲染中的 每个 函数(包括事件处理程序、效果、超时或其中的API调用)都会捕获定义它的渲染调用的props和状态。

    所以这两个例子是等价的:

    function Example(props) {
      useEffect(() => {
        setTimeout(() => {
    +     console.log(props.counter);    }, 1000);
      });
      // ...
    }
    
    function Example(props) {
    + const counter = props.counter;
      useEffect(() => {
        setTimeout(() => {
    +     console.log(counter);    }, 1000);
      });
      // ...
    }
    

    无论你是否在组件内部从props或状态中"提前"读取都无关紧要。 他们不会改变!在单个渲染的作用域内,props和状态保持不变。 (解构props使这更加明显。)

    当然,有时你希望在效果中定义的某些回调中读取最新而非捕获的值。最简单的方法是使用refs,如本文最后一节所述。

    注意,当你想从 过去 渲染的函数中读取 未来 的props或状态时,你是在逆潮流而上。这并没有错(在某些情况下是必要的),但打破这种模式可能看起来不那么“干净”。这是一个有意的结果,因为它有助于突出哪些代码是脆弱的,并且依赖于时间而改变。在类上,发生这种情况时不太明显。

    这是我们的计数器示例的一个版本,它复制了类的行为:

    function Example() {
      const [count, setCount] = useState(0);
      const latestCount = useRef(count);
    
      useEffect(() => {
        // Set the mutable latest value
        latestCount.current = count;
        setTimeout(() => {
          // Read the mutable latest value
          console.log(`You clicked ${latestCount.current} times`);
        }, 3000);
      });
      // ...
    

    image

    在React中改变一些东西似乎很古怪。但是,这正是React本身在类中重新分配this.state的方式。与捕获的props和state不同,你无法保证读取latestCount.current会在任何特定回调中为你提供相同的值。根据定义,你可以随时改变它。这就是为什么它不是默认值,你必须选择它。

    那么清理呢?

    正如文档所解释的那样,某些effect可能会有一个清理阶段。本质上,它的目的是“撤消”订阅等情况的效果。

    考虑以下代码:

    useEffect(() => {
      ChatAPI.subscribeToFriendStatus(props.id, handleStatusChange);
      return () => {
        ChatAPI.unsubscribeFromFriendStatus(props.id, handleStatusChange);
      };
    });
    

    假设props在第一个渲染时为{id:10},在第二个渲染上为{id:20}。你 可能 认为会发生这样的事情:

    • React清除{id:10}的效果。
    • React为{id:20}渲染UI。
    • React运行{id:20}的效果。

    (情况并非如此。)

    使用这个心理模型,你可能认为清理“看到”了旧的props,因为它在我们重新渲染之前运行,然后新的效果“看到”了新props,因为它在重新渲染之后运行。这是直接从类生命周期中提取的心智模型,这里并不准确 。让我们看看这是为什么。

    React仅在让浏览器绘制后运行效果。这使你的应用程序更快,因为大多数效果不需要阻止屏幕更新。效果清理也会延迟。使用新props重新渲染,前一个效果会被清除:

    • React为{id:20}渲染UI。
    • 浏览器绘制画面。我们在屏幕上看到了{id:20}的用户界面。
    • React清除{id:10}的效果。
    • React运行{id:20}的效果。

    你可能想知道:但是如果在props变为{id:20}之后运行,那么前一效果的清理如何仍能“看到”旧的{id:10} props?

    我们以前来过这里…?

    image

    引用上一节:

    组件渲染中的 每个 函数(包括事件处理程序、效果、超时或其中的API调用)都会捕获定义它的渲染调用的props和状态。

    现在答案很明确!不管这意味着什么,效果清理不会读取“最新”的props。它读取属于它定义的渲染的props:

    // First render, props are {id: 10}
    function Example() {
      // ...
      useEffect(
        // Effect from first render
        () => {
          ChatAPI.subscribeToFriendStatus(10, handleStatusChange);
          // Cleanup for effect from first render
          // 嘿,你的关注点放在这里(手动高亮)
          return () => {
            ChatAPI.unsubscribeFromFriendStatus(10, handleStatusChange);
          };
        }
      );
      // ...
    }
    
    // Next render, props are {id: 20}
    function Example() {
      // ...
      useEffect(
        // Effect from second render
        () => {
          ChatAPI.subscribeToFriendStatus(20, handleStatusChange);
          // Cleanup for effect from second render
          return () => {
            ChatAPI.unsubscribeFromFriendStatus(20, handleStatusChange);
          };
        }
      );
      // ...
    }
    

    王国将会升起并化为灰烬,太阳将会褪去它的外层成为一颗白矮星,最后的文明将会终结。但是除了{id:10}之外,没有任何东西可以使第一个渲染效果的清理“看到”props。

    这就是让React在绘制后立即处理效果的原因——默认情况下让你的应用程序运行得更快。如果我们的代码需要它们,旧的props仍然存在。

    同步,而不是生命周期

    关于React,我最喜欢的一点是它统一了对初始渲染结果和更新的描述。这会使你的程序降低熵

    假设我的组件是这样的:

    function Greeting({ name }) {
      return (
        <h1 className="Greeting">
          Hello, {name}
        </h1>
      );
    }
    

    如果我渲染<Greeting name ="Dan"/>并且后面加上<Greeting name ="Yuzhi"/>,或者我只渲染<Greeting name ="Yuzhi"/>,都无关紧要。最后,我们将在两种情况下看到“Hello, Yuzhi”。

    人们常说:“重要的是过程,而不是目的地。”而对于React,情况正好相反。重要的是目的地,而不是旅程。 这就是jQuery代码中的$.addClass$.removeClass调用之间(我们的“旅程”)的区别,并指定了在React代码中CSS类应该是 什么(我们的“目的地”)。

    React根据我们当前的props和状态同步DOM。 渲染时“mount”或“update”之间没有区别。

    你应该以类似的方式思考效果。useEffect允许你根据我们的props和状态同步React树之外的东西。

    function Greeting({ name }) {
      useEffect(() => {
        document.title = 'Hello, ' + name;
      });
      return (
        <h1 className="Greeting">
          Hello, {name}
        </h1>
      );
    }
    

    这与熟悉的 mount/update/unmount 心理模型略有不同。将其内在化是非常重要的。如果你试图编写一个根据组件是否第一次渲染而表现不同的效果,那么你就是在逆流而上! 如果我们的结果取决于“旅程”而不是“目的地”,我们就无法同步。

    无论我们是使用props A,B和C渲染,还是使用C立即渲染,都无关紧要。虽然可能会有一些暂时的差异(例如,在获取数据时),但最终的结果应该是相同的。

    当然,在每个渲染上运行所有效果可能并不是很高效。(在某些情况下,这会导致无限循环。)

    那我们怎么解决这个问题呢?

    教React去Diff你的Effects

    我们已经从DOM本身吸取了教训。React只更新DOM中实际发生更改的部分,而不是在每次重新渲染时都修改它。

    当你更新

    <h1 className="Greeting">
      Hello, Dan
    </h1>
    

    <h1 className="Greeting">
      Hello, Yuzhi
    </h1>
    

    React看到两个对象:

    const oldProps = {className: 'Greeting', children: 'Hello, Dan'};
    const newProps = {className: 'Greeting', children: 'Hello, Yuzhi'};
    

    它检查它们的每个props,并确定子元素已经更改,需要DOM更新,但className没有。所以它可以这样做:

    domNode.innerText = 'Hello, Yuzhi';
    // No need to touch domNode.className
    

    我们可以用效果做这样的事吗?如果不需要应用效果,最好避免重新运行它们。

    例如,由于状态更改,我们的组件可能会重新渲染:

    function Greeting({ name }) {
      const [counter, setCounter] = useState(0);
    
      useEffect(() => {
        document.title = 'Hello, ' + name;
      });
    
      return (
        <h1 className="Greeting">
          Hello, {name}
          {/* 你的关注点在这里 */}
          {/* 原文此处是count, 实则为counter */}
          <button onClick={() => setCounter(count + 1)}>
            Increment
          </button>
        </h1>
      );
    }
    

    但是我们的效果不使用counter状态。我们的效果将document.titlename prop同步,但name prop是相同的。 在每次计数器更改时重新分配document.title似乎并不理想。

    好吧,那么React会不会只是…差异效果(diff effects)?

    let oldEffect = () => { document.title = 'Hello, Dan'; };
    let newEffect = () => { document.title = 'Hello, Dan'; };
    // Can React see these functions do the same thing?
    

    并不是的。React无法在不调用该函数的情况下猜测该函数的功能。(源代码实际上并不包含特定的值,它只是在name prop上结束。)

    这就是为什么如果你想避免不必要地重新运行效果,你可以为useEffect提供一个依赖数组(也称为“deps”)参数:

    seEffect(() => {
      document.title = 'Hello, ' + name;
    }, [name]); // Our deps
    

    就像我们告诉React一样:“嘿,我知道你看不到这个函数内部,但我保证它只使用name而不是渲染作用域中的任何其他内容。”

    如果这个效果在当前和上次之间的每个值都相同,则无法同步,因此React可以跳过效果:

    const oldEffect = () => { document.title = 'Hello, Dan'; };
    const oldDeps = ['Dan'];
    
    const newEffect = () => { document.title = 'Hello, Dan'; };
    const newDeps = ['Dan'];
    

    如果甚至依赖项数组中的一个值在渲染之间是不同的,我们知道运行效果不能被跳过。同步所有的东西!

    不要因为依赖而撒谎

    在依赖关系上撒谎会带来不好的后果。从直觉上看, 这是有道理的, 但我看到几乎每个人都尝试使用useEffect与类中的心理模型试图欺骗规则。(一开始我也这么做了!)

    function SearchResults() {
      async function fetchData() {
        // ...
      }
    
      useEffect(() => {
        fetchData();
      }, []); // Is this okay? Not always -- and there's a better way to write it.
    
      // ...
    }
    

    (Hook FAQ解释了应该怎么做。我们将在下面回到这个例子。)

    “但我只想在mount时运行它!”,你会这么说。现在,请记住:如果你指定deps,组件内部的效果所使用的所有 值都 必须 在那里。 包括props,状态,函数 - 组件中的任何内容。

    有时,当你这样做时,它会导致问题。例如,你可能会看到一个无限重取循环,或者一个socket被重新创建得太频繁。 该问题的解决方案不是删除依赖项。 我们很快就会看到这些解决方案。

    但在我们跳到解决方案之前,让我们更好地理解问题。

    当依赖关系欺骗时会发生什么

    如果deps(依赖项)包含了效果使用的所有值,React知道什么时候重新运行它:

    useEffect(() => {
      document.title = 'Hello, ' + name;
    }, [name]); // 关注这个依赖项
    

    image

    (依赖关系是不同的,所以我们重新运行效果。)

    但是,如果我们为此效果指定了[],则新效果函数将不会运行:

    useEffect(() => {
      document.title = 'Hello, ' + name;
    }, []); // Wrong: name is missing in deps
    
    

    image

    (依赖项是相同的,所以我们跳过这个效果。)

    在这种情况下,问题可能显而易见。但是,在其他情况下,当类解决方案从你的记忆中“跳出”时,这种直觉可能会欺骗你。

    例如,假设我们正在编写一个每秒递增一次的计数器。对于类,我们的直觉是:“设置间隔(interval)一次,销毁间隔一次”。这是一个我们如何做的例子。当我们在心理上将此代码翻译为useEffect时,我们本能地将[]添加到deps中。“我想让它跑一次”,对吗?

    function Counter() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        const id = setInterval(() => {
          setCount(count + 1);
        }, 1000);
        return () => clearInterval(id);
      }, []); //你的关注点在这里
    
      return <h1>{count}</h1>;
    }
    

    但是,此示例仅递增一次。哎呀。

    如果你的心理模型是“依赖关系让我指定何时我想重新触发效果”,这个例子可能会给你一个存在的危机。你想要触发它一次,因为它是一个间隔 - 所以它为什么会引起问题?

    但是,如果你知道依赖项是我们的提示,用于对效果在渲染范围中使用的所有内容作出反应,那么这样做是有意义的。它使用count,但我们使用[]撒谎说它没有依赖。它会坑道我们,这只是时间问题!

    在第一次渲染中,count0。因此,第一个渲染效果中的setCount(count + 1)表示setCount(0 + 1)。因为[] deps我们永远不会重新运行效果,所以它会每秒调用setCount(0 + 1)

    // First render, state is 0
    function Counter() {
      // ...
      useEffect(
        // Effect from first render
        () => {
          const id = setInterval(() => {
    +       setCount(0 + 1); // Always setCount(1)
          }, 1000);
          return () => clearInterval(id);
        },
    +   [] // Never re-runs
      );
      // ...
    }
    
    // Every next render, state is 1
    function Counter() {
      // ...
      useEffect(
    +   // This effect is always ignored because
    +   // we lied to React about empty deps.
        () => {
          const id = setInterval(() => {
            setCount(1 + 1);
          }, 1000);
          return () => clearInterval(id);
        },
        []
      );
      // ...
    }
    
    

    我们撒谎说我们的效果不依赖于组件内部的值,而实际上它依赖于组件内部的值!

    我们的效果使用count - 组件内部的值(但在效果之外):

    +const count = // ...
    
    useEffect(() => {
      const id = setInterval(() => {
    +   setCount(count + 1);
      }, 1000);
      return () => clearInterval(id);
    }, []);
    

    因此,将[]指定为依赖项将产生一个错误。React将比较依赖项,并跳过更新此效果:

    image

    (依赖性是相同的,所以我们跳过这个效果。)

    像这样的问题很难想到。因此,我鼓励你将其作为一项硬性规则,始终诚实地遵循效果依赖关系,并将其全部(效果所用到的)指定。(如果你想在团队中强制执行此操作,我们会提供一个[lint规则](lint rule)。)

    诚实对待依赖关系的两种方法

    有两种策略可以诚实地对待依赖关系。通常应该从第一个开始,然后根据需要应用第二个。

    第一种策略是修复依赖关系数组,以包含在效果中使用的组件内的所有 值。 我们将count作为dep(依赖)包括:

    useEffect(() => {
      const id = setInterval(() => {
        setCount(count + 1);
      }, 1000);
      return () => clearInterval(id);
    }, [count]);
    
    

    这使依赖项数组正确。它可能不太理想,但这是我们需要解决的第一个问题。现在改变count将重新运行效果,每一个下一个间隔引用count从其渲染在setCount(count + 1):

    // First render, state is 0
    function Counter() {
      // ...
      useEffect(
        // Effect from first render
        () => {
          const id = setInterval(() => {
    +       setCount(0 + 1); // setCount(count + 1)
          }, 1000);
          return () => clearInterval(id);
        },
    +   [0] // [count]
      );
      // ...
    }
    
    // Second render, state is 1
    function Counter() {
      // ...
      useEffect(
        // Effect from second render
        () => {
          const id = setInterval(() => {
    +       setCount(1 + 1); // setCount(count + 1)
          }, 1000);
          return () => clearInterval(id);
        },
    +   [1] // [count]
      );
      // ...
    }
    

    这样可以解决问题,但只要count发生变化,我们的间隔就会被清除并再次设置。这可能是不受欢迎的:

    image

    (依赖关系是不同的,所以我们重新运行效果。)


    第二种策略是更改我们的effect代码,这样它就不需要比我们想要的值频繁的更改。 我们不想在依赖关系上撒谎——我们只是想改变我们的效果,使依赖关系更少

    让我们看一些删除依赖项的常用技巧。

    使效果自给自足

    我们希望摆脱效果中的count依赖性。

    useEffect(() => {
      const id = setInterval(() => {
        setCount(count + 1);
      }, 1000);
      return () => clearInterval(id);
    }, [count]);
    

    要做到这一点,我们需要问自己:我们使用count用来做什么? 好像我们只将它用于setCount调用。在这种情况下,我们实际上在作用域里根本不需要count。当我们想要根据以前的状态更新状态时,我们可以使用setState函数更新形式

    useEffect(() => {
      const id = setInterval(() => {
        // 你的关注点在这里
        setCount(c => c + 1);
      }, 1000);
      return () => clearInterval(id);
    }, []);
    

    我喜欢将这些情况视为“错误(假的)依赖”。是的,count是一个必要的依赖项,因为我们在效果中编写了setCount(count + 1)。但是,我们真正的需要count只是去将其转换为count + 1并将其“发回”给React。但是React已经知道了 当前的count我们需要告诉React的是增加这个状态——不管它现在是什么状态。

    这正是setCount(c => c + 1)的作用。你可以将其看作是向React“发送一条指令”来对状态应该如何变化做出反应。这种“更新形式”在其他情况下也有帮助,例如批量多次更新时。

    请注意,我们实际上已经完成了删除依赖项的工作。我们没有欺骗他。我们的效果不再从渲染作用域读取counter值:

    image

    (依赖项是相同的,所以我们跳过这个效果。)

    你可以在这里试试。

    即使此效果仅运行一次,属于第一个渲染的间隔回调完全能够在每次间隔触发时发送c => c + 1更新指令。它不再需要知道当前的计数器状态。 React已经知道了。

    功能更新和Google文档

    还记得我们如何谈论同步是效果的心理模型吗?同步的一个有趣方面是,你经常希望保持系统之间的“消息”与其状态无关。例如,在Google Docs中编辑文档实际上并不会将整个页面发送到服务器。那将是非常低效的。相反,它会发送用户尝试执行操作的表示。

    虽然我们的用例是不同的,但是类似的哲学适用于效果。它只有助于将最少的必要信息从效果内部发送到组件。setCount(c => c + 1)这样的更新形式传递的信息严格少于setCount(count + 1),因为它没有被当前计数(count)“污染”。它只表示动作(“递增”)。在React中思考涉及到找到最小的状态。这是相同的原则,但对于更新。

    编码意图(而不是结果)类似于谷歌文档解决协作编辑的方式。虽然这是延伸的类比,但功能更新在React中也扮演着类似的角色。它们确保来自多个源的更新(事件处理程序、效果订阅等)能够以可预测的方式正确地应用于批处理中。

    但是,即使是setCount(c => c + 1)也不是那么好。 它看起来有点奇怪,它能做的非常有限。例如,如果我们有两个状态变量,它们的值相互依赖,或者如果我们需要根据prop来计算下一个状态,这对我们没有帮助。幸运的是,setCount(c => c + 1)有一个更强大的姐妹模式。它的名称是useReducer

    将更新与操作解耦

    让我们修改前面的例子,让它有两个状态变量:countstep。我们的间隔将使count增加step输入的值:

    function Counter() {
      const [count, setCount] = useState(0);
      const [step, setStep] = useState(1);
    
      useEffect(() => {
        const id = setInterval(() => {
          setCount(c => c + step);
        }, 1000);
        return () => clearInterval(id);
      }, [step]);
    
      return (
        <>
          <h1>{count}</h1>
          <input value={step} onChange={e => setStep(Number(e.target.value))} />
        </>
      );
    }
    

    (这里是一个例子)

    请注意,我们没有欺骗。 由于我开始在效果中使用step,我将它添加到依赖项中。这就是代码正确运行的原因。

    此示例中的当前行为是更改step重新启动间隔 - 因为它是其中一个依赖项。在许多情况下,这正是你想要的!拆除一个效果并重新设置它没有错,除非我们有很好的理由,否则我们不应该避免这样做。

    但是,假设我们希望间隔时钟不会在step更改时重置。我们如何从效果中删除step依赖?

    设置状态变量时,取决于另一个状态变量的当前值,你可能希望尝试使用useReducer替换它们。

    当你发现自己正在编写setSomething(something =>…)时,是时候考虑使用reducer了。reducer允许你 将表示组件中发生的“操作”与状态更新的响应方式解耦。

    在我们的效果中,让我们将step依赖关系替换为dispatch依赖关系:

    const [state, dispatch] = useReducer(reducer, initialState);
    const { count, step } = state;
    
    useEffect(() => {
      const id = setInterval(() => {
        dispatch({ type: 'tick' }); // Instead of setCount(c => c + step);
      }, 1000);
      return () => clearInterval(id);
    }, [dispatch]);
    

    (查看这里例子)

    你可能会问我:“这怎么会更好?”答案是 React保证dispatch函数在整个组件生命周期内保持不变。所以上面的例子不需要重新订阅间隔。

    我们解决了问题!

    (你可以省略deps中的dispatchsetStateuseRef容器值,因为React保证它们是静态的。但指定它们也没有坏处。)

    它不是在效果中读取状态,而是发送一个动作来编码 发生了什么 的信息。这允许我们的效果保持与step状态解耦。我们的效果并不关心我们如何更新状态,它只是告诉我们发生了什么。reducer集中了更新逻辑:

    const initialState = {
      count: 0,
      step: 1,
    };
    
    function reducer(state, action) {
      const { count, step } = state;
      if (action.type === 'tick') {
        return { count: count + step, step };
      } else if (action.type === 'step') {
        return { count, step: action.step };
      } else {
        throw new Error();
      }
    }
    

    (如果你之前错过了,那么这是一个演示)

    为什么useReducer是Hooks的欺骗模式

    我们已经看到当效果需要根据以前的状态或另一个状态变量设置状态时如何删除依赖关系。但是如果我们需要props来计算下一个状态呢? 例如,我们的API可能是<Counter step = {1} />。当然,在这种情况下,我们不能避免将props.step指定为依赖项?

    事实上,我们可以!我们可以将reducer本身 放在我们的组件中来读取props:

    function Counter({ step }) {
      const [count, dispatch] = useReducer(reducer, 0);
    
      function reducer(state, action) {
        if (action.type === 'tick') {
          // 你的关注点应该在这里
          return state + step;
        } else {
          throw new Error();
        }
      }
    
      useEffect(() => {
        const id = setInterval(() => {
          dispatch({ type: 'tick' });
        }, 1000);
        return () => clearInterval(id);
      }, [dispatch]);
    
      return <h1>{count}</h1>;
    }
    

    这个模式禁用了一些优化,所以尽量不要在任何地方都使用它,但是如果需要,你可以完全从reducer访问props。(这里是一个例子)

    即使在这种情况下,重新渲染之间仍然保证dispatch标识是稳定的。 因此,如果需要,你可以从效果deps中省略它。它不会导致重新运行效果。

    你可能想知道:这怎么可能有效呢?当从属于另一个渲染效果的内部调用时,reducer如何“知道”props?答案是,当你dispatch时,React会记住该操作 - 但它会在下一次渲染期间调用你的reducer。在那时,新的props将在作用域内,你不会在一个效果内。

    这就是为什么我喜欢将useReducer视为Hooks的“作弊(欺骗)模式”。它让我将更新逻辑从描述所发生的事情中解耦出来。反过来,这有助于我从我的效果中删除不必要的依赖项,并避免更频繁地重新运行它们。

    移动函数到效果内

    一个常见的错误是认为函数不应该是依赖关系。例如,这似乎可以工作:

    function SearchResults() {
      const [data, setData] = useState({ hits: [] });
    
      async function fetchData() {
        const result = await axios(
          'https://hn.algolia.com/api/v1/search?query=react',
        );
        setData(result.data);
      }
    
      useEffect(() => {
        fetchData();
      }, []); // Is this okay?
      // ...
    

    (这个例子改编自Robin Wieruch的一篇精彩文章 - 看看吧)

    需要明确的是,此代码确实有效。但是简单地忽略局部函数的问题是,当组件增长时,很难判断我们是否在处理所有的情况!

    想象一下,我们的代码是这样拆分的,每个函数都要大(很长,不易维护)五倍:

    function SearchResults() {
      // Imagine this function is long
      function getFetchUrl() {
        return 'https://hn.algolia.com/api/v1/search?query=react';
      }
    
      // Imagine this function is also long
      async function fetchData() {
        const result = await axios(getFetchUrl());
        setData(result.data);
      }
    
      useEffect(() => {
        fetchData();
      }, []);
    
      // ...
    }
    

    现在让我们说我们稍后在其中一个函数中使用一些状态或prop:

    function SearchResults() {
      const [query, setQuery] = useState('react');
    
      // Imagine this function is also long
      function getFetchUrl() {
    +   return 'https://hn.algolia.com/api/v1/search?query=' + query;
      }
    
      // Imagine this function is also long
      async function fetchData() {
        const result = await axios(getFetchUrl());
        setData(result.data);
      }
    
      useEffect(() => {
        fetchData();
      }, []);
    
      // ...
    }
    

    如果我们忘记更新调用这些函数的任何效果的deps(可能通过其他函数!),我们的效果将无法同步来自props和state的更改。这听起来不太好。

    幸运的是,这个问题有一个简单的解决方案。如果你只在效果中使用某些函数,请将它们直接移动到该效果中:

    function SearchResults() {
      // ...
      useEffect(() => {
        // 你的关注点在这里
        // We moved these functions inside!
        function getFetchUrl() {
          return 'https://hn.algolia.com/api/v1/search?query=react';
        }
        async function fetchData() {
          const result = await axios(getFetchUrl());
          setData(result.data);
        }
    
        fetchData();
      }, []); // ✅ Deps are OK
      // ...
    }
    

    (这里是一个示例)

    那么有什么好处呢?我们不再需要考虑“传递依赖”。我们的依赖数组不再欺骗你: 我们真的没有在我们的效果中使用来自组件外部作用域的任何东西。

    如果我们稍后修改getFetchUrl以使用query状态,我们更有可能注意到我们在效果编辑它 - 因此,我们需要向效果依赖项添加query

    function SearchResults() {
      const [query, setQuery] = useState('react');
    
      useEffect(() => {
        function getFetchUrl() {
          return 'https://hn.algolia.com/api/v1/search?query=' + query;
        }
    
        async function fetchData() {
          const result = await axios(getFetchUrl());
          setData(result.data);
        }
    
        fetchData();
      }, [query]); // ✅ Deps are OK
    
      // ...
    }
    
    

    (这里是一个例子)

    通过添加此依赖项,我们不仅仅是“安抚React”。当query发生更改时,重新获取数据是有意义的。useEffect的设计迫使你注意到我们的数据流中的变化,并选择我们的效果应该如何同步它——而不是忽略它,直到我们的产品用户遇到bug。

    感谢eslint-plugin-react-hooks插件中的exhaustive-deps lint规则,你可以在编辑器中输入时分析效果,并获得有关缺少哪些依赖项的建议。换句话说,计算机可以告诉你组件未正确处理哪些数据流更改。

    image

    很甜蜜。

    但我不能把这个函数放在一个效果中

    有时你可能不想把函数移到效果。例如,同一组件中的多个效果可能会调用相同的函数,并且你不希望复制和粘贴其逻辑。或许这是一个prop。

    你应该在效果依赖中跳过这样的函数吗?我想不是。同样,效果不应该在依赖关系上撒谎。 通常有更好的解决方案。一个常见的误解是“一个函数永远不会改变”。但正如我们在整篇文章中所学到的,这不可能是事实。实际上,组件内定义的函数会在每个渲染中发生变化!

    这本身就是一个问题。 假设两个效果调用getFetchUrl

    function SearchResults() {
      function getFetchUrl(query) {
        return 'https://hn.algolia.com/api/v1/search?query=' + query;
      }
    
      useEffect(() => {
        const url = getFetchUrl('react');
        // ... Fetch data and do something ...
      }, []); // ? Missing dep: getFetchUrl
    
      useEffect(() => {
        const url = getFetchUrl('redux');
        // ... Fetch data and do something ...
      }, []); // ? Missing dep: getFetchUrl
    
      // ...
    }
    

    在这种情况下,你可能不希望在任何一个效果中移动getFetchUrl,因为这样你就无法共享逻辑。

    另一方面,如果你对效果依赖性“诚实”,则可能会遇到问题。由于我们的效果都依赖于getFetchUrl每个渲染都不同 ),我们的依赖数组是无用的:

    function SearchResults() {
      // ? Re-triggers all effects on every render
      // 你的关注点在这里
      function getFetchUrl(query) {
        return 'https://hn.algolia.com/api/v1/search?query=' + query;
      }
    
      useEffect(() => {
        const url = getFetchUrl('react');
        // ... Fetch data and do something ...
      }, [getFetchUrl]); // ? Deps are correct but they change too often
    
      useEffect(() => {
        const url = getFetchUrl('redux');
        // ... Fetch data and do something ...
      }, [getFetchUrl]); // ? Deps are correct but they change too often
    
      // ...
    }
    

    一个诱人的解决方案是直接跳过deps列表中的getFetchUrl函数。但是,我不认为这是一个很好的解决方案。这使我们很难注意到何时向数据流添加需要由效果处理的更改。这会导致我们之前看到的“永不更新间隔(interval)”等错误。

    相反,还有另外两种更简单的解决方案。

    首先,如果函数不使用组件范围中的任何内容,你可以将其提升到组件外部,然后在效果中自由使用它:

    // ✅ Not affected by the data flow
    function getFetchUrl(query) {
      return 'https://hn.algolia.com/api/v1/search?query=' + query;
    }
    
    function SearchResults() {
      useEffect(() => {
        const url = getFetchUrl('react');
        // ... Fetch data and do something ...
      }, []); // ✅ Deps are OK
    
      useEffect(() => {
        const url = getFetchUrl('redux');
        // ... Fetch data and do something ...
      }, []); // ✅ Deps are OK
    
      // ...
    }
    

    无需在deps中指定它,因为它不在渲染范围内,并且不受数据流的影响。它不能偶然地依赖于props或状态。

    或者,你可以将其包装到useCallback Hook中:

    function SearchResults() {
      // ✅ Preserves identity when its own deps are the same
      // 你的关注点在这里
      const getFetchUrl = useCallback((query) => {
        return 'https://hn.algolia.com/api/v1/search?query=' + query;
      }, []);  // ✅ Callback deps are OK
    
      useEffect(() => {
        const url = getFetchUrl('react');
        // ... Fetch data and do something ...
      }, [getFetchUrl]); // ✅ Effect deps are OK
    
      useEffect(() => {
        const url = getFetchUrl('redux');
        // ... Fetch data and do something ...
      }, [getFetchUrl]); // ✅ Effect deps are OK
    
      // ...
    }
    

    useCallback实际上就像添加另一层依赖性检查。它正在另一端解决问题 — 我们只在必要时更改函数本身,而不是避免函数依赖。

    让我们看看为什么这种方法很有用。以前,我们的示例显示了两个搜索结果(针对'react''redux'搜索查询)。但是,假设我们要添加一个输入,以便可以搜索任意query。因此,getFetchUrl现在不会将query作为参数,而是从本地状态读取它。

    我们会立即看到它缺少query依赖项:

    function SearchResults() {
      const [query, setQuery] = useState('react');
      const getFetchUrl = useCallback(() => { // No query argument
        return 'https://hn.algolia.com/api/v1/search?query=' + query;
      }, []); // ? Missing dep: query
      // ...
    }
    

    如果我修复了useCallback deps以包含query,那么每当query更改时,deps中的getFetchUrl的任何效果都会重新运行:

    function SearchResults() {
      const [query, setQuery] = useState('react');
    
      // ✅ Preserves identity until query changes
      const getFetchUrl = useCallback(() => {
        return 'https://hn.algolia.com/api/v1/search?query=' + query;
      }, [query]);  // ✅ Callback deps are OK
    
      useEffect(() => {
        const url = getFetchUrl();
        // ... Fetch data and do something ...
      }, [getFetchUrl]); // ✅ Effect deps are OK
    
      // ...
    }
    

    感谢useCallback,如果query相同,则getFetchUrl也保持不变,并且我们的效果不会重新运行。但是如果query更改,getFetchUrl也会更改,我们将重新获取数据。这很像在Excel电子表格中更改某些单元格时,使用它的其他单元格会自动重新计算。

    这只是拥抱数据流和同步思维的结果。相同的解决方案适用于从父级传递的函数props:

    function Parent() {
      const [query, setQuery] = useState('react');
    
      // 你的关注点在这里
      // ✅ Preserves identity until query changes
      const fetchData = useCallback(() => {
        const url = 'https://hn.algolia.com/api/v1/search?query=' + query;
        // ... Fetch data and return it ...
      }, [query]);  // ✅ Callback deps are OK
    
      return <Child fetchData={fetchData} />
    }
    
    function Child({ fetchData }) {
      let [data, setData] = useState(null);
    
      useEffect(() => {
        fetchData().then(setData);
      }, [fetchData]); // ✅ Effect deps are OK
    
      // ...
    }
    

    由于fetchData只在query状态发生变化时才会在Parent内部发生变化,所以我们的Child在应用程序真正需要时才会重新获取数据。

    函数是数据流的一部分吗?

    有趣的是,用类打破了这种模式,真正显示了效果和生命周期范例之间的差异。考虑一下这个转换:

    class Parent extends Component {
      state = {
        query: 'react'
      };
      // 你的关注点在这里(手动高亮)
      fetchData = () => {
        const url = 'https://hn.algolia.com/api/v1/search?query=' + this.state.query;
        // ... Fetch data and do something ...
      };
      render() {
        return <Child fetchData={this.fetchData} />;
      }
    }
    
    class Child extends Component {
      state = {
        data: null
      };
      componentDidMount() {
        this.props.fetchData();
      }
      render() {
        // ...
      }
    }
    

    你可能会想:“得了吧,Dan,我们都知道useEffect就像componentDidMountcomponentDidUpdate结合在一起,你无法继续再摇旗呐喊了!” 然而,即使使用componentDidUpdate,这也不起作用:

    class Child extends Component {
      state = {
        data: null
      };
      componentDidMount() {
        this.props.fetchData();
      }
      componentDidUpdate(prevProps) {
        // ? This condition will never be true
        if (this.props.fetchData !== prevProps.fetchData) {
          this.props.fetchData();
        }
      }
      render() {
        // ...
      }
    }
    

    当然,fetchData是一个类的方法!(或者,更确切地说,一个类属性——但这不会改变任何东西。)由于状态的变化,它不会有所不同。所以this.props.fetchData将保持等于prevProps.fetchData,我们将永远不会重新获取。让我们删除这个条件呢?

    componentDidUpdate(prevProps) {
      this.props.fetchData();
    }
    

    哦等等,这会在每次重新渲染时获取。(在上面的树中添加一个动画是发现它的一种有趣的方式。) 也许让我们将它绑定到特定的查询?

    render() {
      return <Child fetchData={this.fetchData.bind(this, this.state.query)} />;
    }
    
    

    但是,即使query没有改变,this.props.fetchData!== prevProps.fetchData始终true!所以我们总是会重新获取。

    对于类的这个难题,惟一真正的解决方案是咬紧牙关,将query本身传递给Child组件。Child实际上并没有最终使用query,但它可以在更改时触发重新获取:

    class Parent extends Component {
      state = {
        query: 'react'
      };
      fetchData = () => {
        const url = 'https://hn.algolia.com/api/v1/search?query=' + this.state.query;
        // ... Fetch data and do something ...
      };
      render() {
        return <Child fetchData={this.fetchData} query={this.state.query} />;
      }
    }
    
    class Child extends Component {
      state = {
        data: null
      };
      componentDidMount() {
        this.props.fetchData();
      }
      componentDidUpdate(prevProps) {
        if (this.props.query !== prevProps.query) {
          this.props.fetchData();
        }
      }
      render() {
        // ...
      }
    }
    

    在多年使用React类的过程中,我已经习惯了传递不必要的props并破坏父组件的封装,直到一周前我才意识到为什么必须这样做。

    对于类,函数props本身并不是数据流的真正组成部分。 方法过于紧密于可变的this变量,这样我们就不能依赖它们的标识来表示任何内容。 因此,即使我们只想要一个函数,我们也必须传递一堆其他数据,以便能够“区分”它。我们无法知道从父级传递的this.props.fetchData是否依赖于某种状态,以及该状态是否刚刚更改。

    使用useCallback,函数可以完全参与数据流。 我们可以说,如果函数输入发生了变化,函数本身就会发生变化,但如果没有变化,它就会保持不变。由于useCallback提供的粒度,对props.fetchData等props的更改可以自动向下传播。

    同样,useMemo让我们对复杂对象也这样做:

    function ColorPicker() {
      // Doesn't break Child's shallow equality prop check
      // unless the color actually changes.
      const [color, setColor] = useState('pink');
      const style = useMemo(() => ({ color }), [color]);
      return <Child style={style} />;
    }
    

    我想强调的是,在任何地方使用useCallback都非常笨重。 当一个函数传递下去并从一些子组件的效果内部调用时它很有用。或者,如果你试图阻止破坏子组件的记忆。但Hooks更适合于避免回调完全传递下来

    在上面的例子中,我更希望fetchData位于我的effect(它本身可以被提取到一个自定义的钩子中)或顶层导入中。我希望保持effect简单,并且其中的回调对此没有帮助。(“如果在请求运行期间某些props.onComplete回调发生了更改,该怎么办?”) 你可以模拟类行为,但这并不能解决竞争条件。

    说说竞争条件

    使用类的经典数据获取示例可能如下所示:

    class Article extends Component {
      state = {
        article: null
      };
      componentDidMount() {
        this.fetchData(this.props.id);
      }
      async fetchData(id) {
        const article = await API.fetchArticle(id);
        this.setState({ article });
      }
      // ...
    }
    

    你可能知道,这段代码有些问题。它不处理更新。所以你可以在网上找到的第二个经典例子是这样的:

    class Article extends Component {
      state = {
        article: null
      };
      componentDidMount() {
        this.fetchData(this.props.id);
      }
      componentDidUpdate(prevProps) {
        if (prevProps.id !== this.props.id) {
          this.fetchData(this.props.id);
        }
      }
      async fetchData(id) {
        const article = await API.fetchArticle(id);
        this.setState({ article });
      }
      // ...
    }
    

    这肯定更好!但他仍然有些问题。它有问题的原因是请求顺序可能出现问题。因此,如果我正在获取{id:10}的数据,切换到{id:20},但{id:20}请求首先出现,先前开始但稍后完成的请求将错误地覆盖我的状态。

    这被称为竞争条件,它在代码中是典型的,将async/await(假定有东西在等待结果)与自顶向下的数据流(当我们处于异步函数的中间时,属性或状态可能会改变)混合在一起。

    效果并不能神奇地解决这个问题,但是如果你试图将async函数直接传递给效果,它们会警告你。(我们需要改进这个警告,以便更好地解释你可能遇到的问题。)

    如果你使用的异步方法支持取消,那就太棒了! 你可以在清理函数中取消异步请求。

    或者,最简单的权宜之计方法是使用布尔值跟踪它:

    function Article({ id }) {
      const [article, setArticle] = useState(null);
    
      useEffect(() => {
    +   let didCancel = false;
        async function fetchData() {
          const article = await API.fetchArticle(id);
    +     if (!didCancel) {        
          	setArticle(article);
          }
        }
    
        fetchData();
    
    	// 这里也是你的关注点
        return () => {      
        	didCancel = true;    
        };  
      }, [id]);
    
      // ...
    }
    

    这篇文章详细介绍了如何处理错误和加载状态,以及将该逻辑提取到自定义Hook中。如果你有兴趣了解有关使用Hooks获取数据的更多信息,我建议你查看一下。

    提高标准

    使用类生命周期思维模式,副作用与渲染输出的行为不同。渲染UI由props和state驱动,并保证与它们一致,但副作用不是。这是bug的常见来源。

    使用useEffect的思维模式,默认情况下会同步事物。副作用成为React数据流的一部分。对于每个useEffect调用,一旦你做对了,你的组件就会更好地处理边缘情况。

    然而,做好这件事的前期成本更高。这可能很烦人。编写能够很好地处理边缘情况的同步代码,本质上比引发与渲染不一致的一次性副作用更困难。

    如果useEffect是你大多数时间使用的工具,这可能会令人担忧。然而,它是一个低层的构建块。现在是使用钩子的早期阶段,所以每个人都一直在使用低级别的钩子,尤其是在教程中。但是在实践中,随着好的API获得发展势头,社区很可能会开始转向更高级别的钩子。

    我看到不同的应用程序创建了它们自己的钩子,比如封装了它们的一些应用程序的auth逻辑的useFetch或使用主题上下文的useTheme。一旦你有了这些工具箱,你就不会经常使用useEffect。但它带来的弹性使每个Hook都能在其上构建。

    到目前为止,useEffect最常用于数据获取。但是数据提取并不是一个同步问题。这一点尤其明显,因为我们的deps经常是[]。我们在同步什么?

    从长远来看,数据获取的suspense将允许第三方库以一种一流的方式告诉React暂停渲染,直到异步(任何东西:代码、数据、图像)就绪。

    随着suspense逐渐覆盖更多的数据获取用例,我预计当你真正想要同步props和状态到某个副作用时,useEffect将作为一个高级用户工具淡出背景。与数据获取不同,它可以很自然地处理这种情况,因为它是为这种情况而设计的。但在此之前,这里所示的自定义钩子是重用数据获取逻辑的好方法。

    结束

    现在你已经了解了我使用效果的所有知识,请在开始时查看TLDR。有意义吗?我错过什么了吗?(我的纸还没有用完呢!)

    我很想在Twitter上收到你的来信!谢谢阅读。

    笔者个人总结

    其实这个就像前面所说的类和函数的区别了。因为在React中,props是不会改变的,而this(state)是可变的。所以造成了改变。由于props是不可变的,这样针对每次的渲染,都会有一个特定的渲染(每次的渲染)。

    对于effect内使用的函数,最好是放在effect中,这样可以避免以后组件增加而未处理所有的情况。如果有复用,可以把这些函数提到effect外面,使用useCallback包裹起来。

    展开全文
  • 工作总结10:毕业这一年的收获

    万次阅读 多人点赞 2017-07-05 22:21:08
    总结去年七月初毕业来到上海,转眼就又是七月了,这一年还是经历了不少事,回头看看,这年中的大多数选择还是比较满意的。今天趁着懒癌没发作,总结一下这一年的收获吧。当前状况毕业一年,上海,创业公司,安卓...
  • 工作总结9:这个月来犯的错

    千次阅读 多人点赞 2017-03-28 20:15:40
    今天是 2017 年 3 月 28 日星期二,距离我发表上篇博客已经过去了快个月,这个月左右的时间中,我浪费很多时间纠结个问题:要不要离职?现在看看,浪费的这段时间主要犯了以下几点错误: 没有及时反省 遇到...
  • 一份经典多线程并发面试题!

    千次阅读 2019-05-07 19:49:28
    面试中关于 synchronized 关键字的 5 连击 1.1 说说自己对于 synchronized 关键字的了解 synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在...
  • 如何写一份好的前端面试简历?

    万次阅读 2017-05-31 15:59:15
    比如你刚开始第一份前端工作你用的技术比较简单,你可以写你自己负责切图,用jQuery写逻辑,用sass写样式,然后再下一份工作你可能技术加强了,你就可以写你用vue,angular来开发了一个单页面应用,还负责写了部分...
  • 分享篇牛人的工作总结

    千次阅读 多人点赞 2019-06-19 10:31:36
    转自http://www.ituring.com.cn/article/497377,让大家感受一下什么叫优秀的架构师,我比较喜欢...掐指算,从 OneAPM 离职也快个月了,在 OneAPM 工作的种种,仿佛还像是在昨天。细数两年的工作经历,我很庆幸...
  • (图片截图自一份网易团队很早之前的一份分析报告) 如果上面这个表,用纯文字进行表述,你可以想象下写的人和看的人都会有多累。 在同一产品不同时间阶段的对比上,多结合不同时间段的背景和产品特点,...
  • 导读:在学习了有关深度学习的理论之后,很多人都会有兴趣尝试构建个属于自己的项目。本文将会从第步开始,告诉你如何解决项目开发中会遇到的各类问题。本文由六大部分组成,涵盖...
  • 拥有渠道的好处就是,每天你都能获得稳定的粉丝,而不是天进500粉丝,再过3天就没有粉丝关注。 以下方法是个人团队实战的一些总结,可以借鉴操作: A、微博引流 由于我们的市场是定位在本地,所以前期推广时候...
  • 可以说,学姐给我的这文档真的把我的知识查漏补缺,面试问到了好多,值得收藏。
  • 个互联网大佬的五年工作成长复盘

    万次阅读 多人点赞 2021-02-10 18:40:44
    ps1:【如何衡量价值】 其实外界衡量个人和 VC 衡量个公司很相似: 该公司处于什么阶段(这个人当下的阶段,我:社会上的菜鸟) 该公司目前的盈利能力如何(这个人当下能创造的价值,我:写点简单的代码) 该...
  • 工作就是我们人生中个巨大的悖论 2010-08-03 14:42:34 有工作时厌工作,没工作时想工作。 有人跟我说上学那会儿也这样,我觉着那不同。上学是你妈逼的或者说整个社会逼的,你是个雪白的豆包被丢进...
  • 随着MySQL的不断成熟,逐渐被用于更多大规模的网站和应用了,比如说当前最火的Facebook、淘宝、阿里、兰亭集势、宝宝树这样的大型的网站都在使用MySQL数据库,足见MySQL在稳定可靠性方面,并不会比我们的商业厂商的...
  • 你可能第次见到这么长的总结文,有点硬核,耐心阅读
  • 漫谈程序员系列:找工作的辟邪剑谱

    万次阅读 多人点赞 2014-12-09 08:05:27
    去咖啡厅喝个咖啡或者酒吧喝个小酒就把工作搞定的程序员可以洗洗睡了,记住回自己家睡……别 if - else 了,选择太多不是好事儿……
  • 测试项:fibjs优化前后性能对比 3个版本的fibjs,分别为: v0: 原版fibjs v1: 优化了SOCKET_ BUFF_ SIZE大小 v2: socket 等待时释放 buffer 内存 测试结果 QPS(req/sec) \ v0 ...
  • 工作11年 人生第二次跳槽的感悟

    千次阅读 多人点赞 2015-08-23 15:08:44
    工作11年 人生第二次跳槽的感悟 作者的亲身经历,告诉你IT外包行业只会造就码农,不会造就程序员 通过自己刻苦努力成为图像处理方面的骨灰级程序员。
  • 个FPGA工程师的个人工作经历总结

    千次阅读 2016-07-11 12:22:40
    很早之前就想对这几个月工作经历写的东西,是作为自己的总结,二是自己也很想将自己这段时间的一些经历和大家分享一下,希望对初学者而言能使得他们能少走一些弯路。只是公司里的事情很多,最近经常加班,所以一直...
  • 程序员如何边工作边创业?

    千次阅读 2015-02-11 21:14:48
    曾经,美好的生活意味着找到一份稳定的朝九晚五的工作,然后退休。但是对于现在的人来说,尤其是怀揣梦想的 80 后和 90 后,朝九晚五的工作却成为了漫长噩梦。 对于一些人来说,打工的生活并不适合他们。很...
  •  我专业是计算机科学与技术,因为我是从个乡镇出来的,在高中的时候在一些杂志也好等等的了解,觉得软件开发是我喜欢并适合的工作,首先我觉得机械啊电子电路啊那些东西需要动手,我不喜欢,我觉得应该十指不沾泥...
  • 我面试过数以百计的各个层面的员工,其中最让我感到遗憾的一个现象就是很多人有着非常好的素质,甚至有的还是名校的毕业生,因为不懂得去规划自己的职业,在工作多年后,依然拿着微薄的薪水,为了一份好一点的工作而...
  • 局里有公务员和事业编制人员,任务和工作是一样的,工资结构略有不同(同等资历工资数额差不太多),公务员拿行政工资,事业编制可以拿职称工资,具体结构我不清楚。 从毕业以工程审计专业的身份考进审计局,开始...
  • 我面试过数以百计的各个层面的员工,其中最让我感到遗憾的一个现象就是很多人有着非常好的素质,甚至有的还是名校的毕业生,因为不懂得去规划自己的职业,在工作多年后,依然拿着微薄的薪水,为了一份好一点的工作而...
  • 正在工作的程序员,生活状态都很苦逼?

    万次阅读 多人点赞 2020-07-18 21:48:16
    7 点半回家洗澡换衣服,有时候做饭,有时候油条胡辣汤鸡蛋买一份。 9 点左右到公司,逛论坛,写代码。 不到 12 点去吃午餐,避免吃饭高峰期。 1 点左右午休,扣会手机,刷刷朋友圈,看看足球等等。 2 点半继续敲...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,912
精华内容 17,164
关键字:

一份稳定的工作的好处