关闭

<Vage:高级DBA的突破之路>

标签: 阿里巴巴职业生涯产品advice
682人阅读 评论(0) 收藏 举报
分类:



【Vage是这样的人】


Vage:高级DBA的突破之路



       有一个笑话,创世第一天,上帝创造了驴。上帝对驴说:“今天我创造了你!作为一头驴,你必须跟终日拉磨,任劳任愿。我给你50年的寿命。”
       驴不同意:“什么?这种苦日子你要我活50年?让我活20年吧,30年还给你。”
上帝同意了。
       第二天,上帝创造了猴子。上帝对猴子说:“你必须带给人们娱乐。你必须让他们开怀大笑,耍把戏。我给你20年寿命。”
       猴子不干:“什么?让他们开怀大笑?做鬼脸耍把戏?10年就够了,另外10年还给你。”
       上帝同意了。
       第三天,上帝创造了狗。上帝对狗说:“你应该终日坐在自家门口,有人进来就叫!我给你则20年寿命。”
       狗反对:“什么?整天坐在门口?绝对不行!我退给你10年寿命!”于是上帝同意了。
       第四天,上帝创造了人。
       上帝对人说:“你的工作就是吃喝玩乐睡大觉,尽情享受人生。只管享受,什么都不干。这种生活,我给你20年寿命。”
       人反对说:“什么?这样的好日子!除了吃喝玩乐,什么都不干。尽情享受,而你让我只活20年?不行,老兄!我们何不做个交易?既然驴退给你30年,狗还你10年,猴子退回10年,你把这些统统给我!这样我的寿命就有70年了。行吗?”
       上帝同意了。
       这就是为什么头20年,我们吃喝玩乐,尽情享受,无所事事。接下来的30年,我们终日像驴一样辛苦工作,养家糊口。之后的10年,我们像猴子一样扮鬼脸耍把戏让孙辈开心。最后10年,我们像狗一样呆在家里,坐在门口,对人大叫。

       虽是笑话,但成年后的人生,也的确如此。像驴一样工作,像猴子一样被人耍,……。就算是逍遥自在的头20年,《这个杀手不太冷》中玛蒂尔达和莱昂的对话,也让人绝望:
       玛蒂尔达:是不是人生总是如此艰难,还是只有童年如此? 莱昂:总是如此

       做人苦,做中国人更苦,做中国的IT人则苦上加苦。前段日了不是有则新闻吗,一美帝程序员将自己的工作包给几名中国程序员完成,自己每天就是享受生活。支付几名中国程序员薪水后,美帝程序员自己的工资还剩一大部分,足够优哉优哉的过日子。这则消息真是让国内程序员苦哈哈们泪奔。

       反差大的又何止程序员们,DBA也是如此。我经常观注一美帝DBA的BLOG,他BLOG有一段时间没更新。后来又开始更新,贴出了一些照片,原来是去爱琴海享受了十来天的阳光、白色沙滩、蓝海、……。我们的假期没有蓝海,只有人海。我的生活没有爱琴海,只有房贷。真是少壮不努力,至今在内地啊。

       但其实很多朋友都知道,比起生活上的苦,还有一种苦更难以名状,就是找不到前进的方向。

       我们似乎身处在一片浓浓的雾mai中,虽然想努力“自强不吸”,但遗憾的是我们不知道哪里是前、哪里是后。穿越雾mai区的过程,是人生最为艰辛的过程。你需要在不知道结果的情况下,朝向一个未知的方向前进。前方有可能是掌声和鲜花,也可能是绝壁断涯。

       做为在雾mai中行走多年的“行客”,今天和大家分享下Oracle DBA这条艰苦曲折之路,特别现在有很多朋友都被困扰的问题:“高级DBA如何突破”。

       DBA的特点,是“入行难、突破难”。

       先说入行难。由于直接负责企业最重要的资产:数据,因此,所有公司对DBA的要求都有一条:经验。没有公司肯把数据库交给没有经验的DBA。评价初、中、高级DBA的重要一点就是经验多少。

       没有经验的DBA想找到工作,是很难的。这间接催进了DBA培训行业的繁荣。通常从事培训工作的讲师,都是有一定经验的。通过讲师介绍,可以学到一些书本中没有的经验类东西。但其实如今网络如此发达,只要有心,自己在网络中找,也是能找到很多富含经验的技术文章。只不过纯靠自己找资料、自己学,会慢一些而已。

       能跨入了DBA的门槛后,一般成长都会很迅速。因为Oracle相关知识还是比较简单的。一般快则一、两年,慢则两、三年,差不多就是中级DBA了。是否再往下前进就看个人意愿了。如果有意研究技术,静下心来将Oracle的原理研究一下,再有个两年左右,差不多就是高级DBA了。这时,很多人的瓶径就到了。有希望转管理的人,纷纷转管理。没希望转管理的呢,这时会极度迷茫,因为已经到顶了。随着时间累积,经验越来越丰富,但总是无法突破,无法达到更高层次。这样再过个几年,就是经验更丰富的高级DBA。再过几年,就是经验更更丰富的高级DBA。说到底,其实还是普通DBA。

       我曾经在这一阶段迷茫很久,各种Oracle原理,能分析的都分析了。但Oracle又没有开源,很多原理,只能雾里看花的研究一下。大部分时候对调优、排故意义不大。这时,就遇到DBA行业的第二难:“突破难”。

       不突破,将一直是普通DBA,即使是“高级”,也还是普通的DBA。很多等待事件,很多资料,无法完全搞清楚其意义。只能被动的等待网络上几个国外大牛写些文章。但我们自己去研究的话,又始终摸不着头脑。

       举个简单的例子,比如关于向客户端发送信息的等待事件有两个:SQL*Net message to client和SQL*Net more data to client。按照文档中的解释,SQL*Net message to client等待事件说明了:The server is performing another send to the client. The previous operation was also a send to the client,翻译过来就是服务器进程正在完成另外的到客户端的发送,之前的操作将总是被发送到客户端。SQL*Net more data to client的解释是:The server process is sending more data/messages to the client. The previous operation to the client was also a send。服务器进程正在发送更多的数据/消息到客户端,之前的操作将总是被发送到客户端。

       按照这个解释,SQL*Net more data to client是发送的数据太多了,是这样不是呢?我做了一个测试。我建了一张小表,只有100行,全表扫描它,观察SQL*Net message to client和SQL*Net more data to client哪个会出现。结果当然是SQL*Net message to client。表不够大吗,当然不会有“More Data”。接下来,我将表的行数扩大到10万、100万、1000万、1亿。最后表的大小都上G了,还是没有“more data”等待。要多大的表,才会有SQL*Net more data to client等待事件呢?我没有测试出来。

       DBA都知道,10046事件是Oracle提供的研究Oracle的利器,接下来,可以用10046跟踪一下。我当时作过这样的跟踪,但很遗憾,在跟踪结果中,无法找到SQL*Net message to client、SQL*Net more data to client的进一步思路。

       我在网上也了解了一下这两个等待事件,大家的说法都含含呼呼。这也很正常,大家对这两个等待事件的理解都是来自于文档,文档中如此含呼,自然也就造成大家的理解各不相同、不太统一的情况。我在网上好一番查找,终于发现有人不知道根据从哪里搞来的资料,说“More Data”等待事件和SQL中Select语句的Fetch有关,然后就没了。根据这点资料猜想一下,应该是抓取的行太多了,就会有这个等待事件吧。在网上又一番查找,也没找到更进一步的资料,也只能放弃了。

其实很多时候,DBA有点像“考据”学家了。要在网上找各种各样的资料。

       考据学,就是埋首于故纸堆中,查阅各种经、史、子、集,论证著如秦始皇真是吕不韦后人吗之类的问题。由于大家所参考的史料有不同,因此某些问题常常分成几派,各执一词。DBA也是一样,我在由中级DBA到高级DBA的过程中,查看了大量的英文资料。但有些资料的说法相互矛盾,比如说“检查点系列问题”。包括增量检查点什么时候触发、日志切换是什么检查点,这类问题吵来吵去,从无定论。

       这使我想起一个有关程序员的笑话。程序员请女神吃饭,女神说:“只要你能让论坛里大家都吵起来,我就和你去吃饭”。程序员略加思索,说:“这好办,你等着看。”说着程序员在论坛上发一帖子:“Python好还是Perl好”。一时之间,大家各抒己见,看法各不相同。很快讨论就变成争吵,论坛闹翻了天。女神一看,说:“不错,你真行,我们去吃饭吧。”程序员回答:“等等,我要让他们相信,还是Python更好”。

       这个笑话也可以换成Oracle的,“增量检查点如何被触发”之类的话题,从来都能引起一番争论。

       和考据学一样,史料的来源,有正史、野史。Oracle资料的来源,也分等级。通常Oracle内部资料为上品,非内部资料为下品。英文资料为上品,中文资料为下品。英文的、Oracle内部的资料,绝对是上品中的上品。在争论问题的时候,能抛出一小段英文,注明这是Oracle内部资料。绝对的权威。

       实事上,好奇之心人皆有之。人都有求知欲的,对于自己想不明白的问题,如果有个地方可以告诉自己答案,就算这个答案有时候也比较朦胧,但总比没有答案好。相信我们都会有过疑问,这个世界、宇宙是从何而来,最早的答案是上帝、盘古他们创造的。这个答案在很长一段时期内,给了很多人以心灵的安慰。当人们仰望无尽的星空时,仿佛看到慈爱的天父在注视我们。当求知欲转变成信仰,这个时候就不要再挑战他了。因为他维护的不是知识本身,而是他的心灵。

       言归正传,对这两个等待事件的研究,就到此为止了,虽然我始终没有测试出来“More Data”的等待事件,但我也总算找到了答案,原来“More Data”是Fetch阶段的等待事件,应该是“抓取”数据太多时,会出现这一等待事件。这应该只能在一些大型企业较大规模的数据库上才能看到,所以我模拟不出来。我原来在阿里的数据库中,的确看到不少这个等待事件。看,有时候找到答案就是这么简单。

       但是,这样的“考据”,对实际调优、排故有帮助吗?答案当然是,没有。

       原理的研究,不能停留在“引经据典”,一定要自己验证、测试。但遗憾的是,Oracle的有些地方,运行的十分迅速,比如Latch、Mutex方面。相关这两点的测试,非常不容易做,因为它们的获得、释放太快了。

       因此,很长一段时期内,我同意一种说法,Oracle内部原理的研究,意义不大。只有一点意义,单纯的“考据”没有意义,通过自己设计实验,验证结论,这个过程可以让我们熟悉Oracle的各个方面,可以让我们尽快成长为高级DBA。

       高级DBA是如何炼成的,很简单,考据+验证,再加上从业5、6年的经验,基本就是高级DBA了。如果只有5、6年经验,没经历过“考据+验证”的洗礼,称不上高级,也就只是经验丰富的DBA。而且现在随着DBA的普及,从业5、6年的DBA已经很多了。如果在2005、06哪几年,如果谁说有5年专职DBA经验,大家都要敬仰一下。现在,已经很多了。所以只是从业时间长已经越来越没有优势了。

       我在高级DBA阶段,停留了很久。应该说到阿里之前,就已经是高级了。因为当时我已经可以解析部分Redo文件格式,对内部原理的“考据+验证”,已经做了很多。到加入阿里的时候,也正好有5年经验。十分符合“考据+验证+经验”,因此阿里也给了我高级数据库专家的Title。拥有高级专家头衔的在当年整个集团的技术人员中也就几十人,这也算是对我之前努力的认可。

       但在这之后,我遇到了DBA的另一大难题:突破难。到阿里之后我一直没有进步。一直停留在高级阶段,无法前进。这就是我前面说的“突破难”。如果你不突破,很难在技术职业上到达另一高峰,这时候你面前的路只有一条,做管理。但现阶段的我并不适合管理,其实并非每一个人都适合做管理。起码以我目前的年龄、心态,还不太适合做管理。一旦加入管理团队,个人技术成长基本宣告停滞。进入管理角色,你能做出多大的成绩,很大程度上取决于你之前的技术水平。技术,是管理的地基(除非是很有管理者天赋的管理型人才)。我还不想在地基很薄的时候,就匆匆在薄薄的地基上盖楼。以后我也会转去做管理,但不是现在。所以,我要先“突破高级DBA”。

       为什么DBA达到高级会“突破难”呢?想一想其实是很简单,就两个字:认可。IT业内对DBA的评价是有顶的。做程序员,只要牛B,可以做到Linus,开发个Linux造福人类。程序员,是没顶的行业。或者说有顶,不过这个顶太高了。而DBA不同,DBA不从事创造性行业。运维,而且是运维别人已经开发好的程序。就算你的运维技术登峰造极,在开发Oracle的程序员面前,不还是抬不起头来吗。DBA是有顶的,而且顶不高。从事DBA后少则5、6年,一定会到顶。

       我一直相信,有些事是看机缘的。佛家所谓“缘起”,就是对小概率、巧和事件的另一种说法。我的突破,就是一件巧合事件。突破之后,我慢慢发现,在高级DBA之后,还有两个层次。

       我的突破,“缘起”就是阿里搞了套GreenPulm系统,这是一种基于PostGre SQL的分布式数据库系统。由于是最初是SUN搞的,所以最早GreenPulm是装在Solaris系统上。公司的GreenPulm需要维护,由于阿里去Oracle运动如火如荼,我也要选择一个非Oracle方向的技术,我就选择了GreenPulm。我是从Solaris开始入手的,因为要先学Solaris的维护,然后才能维护GreenPulm。我买了一本《Solaris红宝书》开始啃,啃的很无趣。不过,我在Solaris中,发现一个特性,叫“动态跟踪语言”,也就是DTrace。这玩意非常强大,它基本上能跟踪一切。而且,在Solaris下的Oracle,和在Linux、AIX下等等其他系统下的Oracle,运行原理是一样的。如果在Solaris下装个Oracle,再用DTrace跟踪,不知道能不能有所突破。

       发现这东西之后,我基本上停止接手GreenPulm的维护。一门心思的开始研究用DTrace跟踪Oracle。果然,收获很大。我研究了大半年这玩意,比如前面所说的例子:SQL*Net message to client和SQL*Net more data to client的意义。使用DTrace跟踪,将非常容易发现它们的秘密。

       Oracle逻辑读其实就是调用memcpy函数,将数据从Buffer Cache中拷贝到PGA中。再从PGA中通过网络传送到客户端。用DTrace的PID类探针跟踪逻辑读Oracle都调了什么函数。在跟踪结果中可以发现,每次SQL*Net message to client事件发生,向客户端发送数据的量大小,有一个上限。

       大概过程是这样的,先要用DTrace挖掘出Oracle注册等待事件的函数,这样不必查询视图,在DTrace的跟踪结果中,就可以知道在哪段代码之后发生的等待事件是什么。比如数据到PGA开始用网络传输之后,Oracle就注册了SQL*Net message to client等待事件。

       数据拷贝到PGA中后,一定会占一块内存。一次拷贝多少数据,是受set arraysize控制的。我不断尝试新的arraysize值,统计memcpy函数拷贝的数据量。发现随着arraysize增大,Oracle只会在PGA中最分配8K内存,绝对不会超过这个数字。而当arraysize很大,一次逻辑读的数据量超过8K时,就会出现SQL*Net more data from client等待事件。

       比如说,arraysize设为很高的值,一次逻辑读要读10K数据。Oracle先memcpy 8K数据到PGA中,通过网络发送到客户端,这时等待事件是SQL*Net more data from client,逻辑读并没有结束。然后Oracle再memcpy 2K数据到PGA中,再通过网络发送到客户端,这次的等待事件就是SQL*Net message to client,不再是“More Data”,这时一次逻辑读才结束。

       这就是SQL*Net message to client和SQL*Net more data to client的区别。

       下面,问题是,明白了这些有什么用呢?这和普通高级DBA“考据+测试”所得出的结论,虽有不同,但同样没有意义。

       当然不是的,如果单纯只是无意义的“屠龙之术”,只为了装装门面,确实是没有意义的。但使用“动态跟踪”DTrace进行的深入研究,并非没有意义。以这个例子为例,有两点实际意义:
1、当发生SQL*Net more data to client时,说明一次逻辑读的数据量要两次网络传输。而逻辑读期间,Oracle会一直持有Buffer Pin锁。也就是说,Buffer Pin锁的持有时间要包含一次网络传输。在网络稍差的环境中,这会导致Buffer Pin锁持有时间过长,加重系统CPU的负担。

2、PGA中满8K就发送一次数据。这个8K是固定的吗?还是可以调的。如果可以调的大些,不但可以减少Oracle和网络的交互次数,还可以减少SQL*Net more data from client的次数,这都对减少系统CPU负载有帮助。有了8K这个默认数字,在Oracle官方文档中搜索,又发现一个含含乎乎的参数,Session Data Unit,简称SDU。这个参数可以在sqlnet.ora、tnsnames.ora或监听配置文件中设置。你可以在文档中搜索SDU的介绍,保证你可以看懂、但不知道这玩意是干什么用的。它就是用来设置逻辑读在PGA的缓存大小的。

       其实简单点说,当你的数据库中SQL*Net more data to client等待事件比较多时,调大SDU,可以有效的降低CPU的负载。但这对网络的要求会更高。

       这就是DTrace跟踪出的结果。我用DTrace跟踪出的结果有很多,当然,单纯的DTrace,有时间会显得力不从心。这时候调试工具gdb就上场了。后来升级到Oracle 11GR2后,在Solaris下只有64位版本的11GR2,Solaris下64位的gdb我一直没装成功,所以后来我改用mdb了。

       gdb/mdb的作用,在研究Latch、Mutex时最明显。gdb/mdb可以在代码的任意地方设置断点,让运行的如脱缰野马般的Oracle,停在我们想让它停的地方。

       还有,这两年来我把CPU、汇编方面的知识又补了补。今年春节,我开始阅读Oracle部分重点代码的反汇编。比如Mutex的、逻辑读的。

       使用DTrace、gdb/mdb这类调试工具,很多人担心会对观察对象有影响。影响肯定是有的,量子物理中人类的一瞥,不是还可以影响量子的行为吗,我们去调试Oracle进程,一定会对被调试进程有影响的。不过,优秀的调试工具,能将影响降到最低。Solaris下的DTrace和mdb在这方面做的要好一些,对调试对象基本没有影响。Linux也正在慢慢赶上,gdb的低层Ptrace对进程影响稍大,不过这是以前了,Linux内核不断在进步,调试、动态跟踪技术也不断在进步。后来又有了PTrace Over Utrace,Utrace对进程的影响已经大大缩小。现在已经是最新的uprobes了,调试跟踪的性能、对进程的影响,已经非常小了。

       我们都知道许多昆虫都有的一种生长方式:蛹-->成虫。蛹的阶段,是初级阶段。从蛹到成虫,是一种飞越式的进化。蛹只能在泥土中钻来钻去,而多数成虫则能跳、能飞。这种飞越也是有代价的,成语有“破茧成蝶”。扔掉过去、打破自己的天花板,向更高级进化。将近一年的DTrace、gdb/mdb研究,使我在阿里的职业生涯走到了尽头。几次季度KPI考评,我都没有完成要求,GreenPulm维护工作无法胜任。这段时间是痛苦的,一方面我感觉到技术方面自己成长很快,快要实现我的目标:“突破高级DBA”。另一方面,考评如此之差,也让自己背付了巨大的压力。我想,是到了要告别的时候,阿里也是这么想的。于是,很自然的,在2012年初,我离开了阿里。

       我很感谢阿里巴巴,进公司前,我是一名普通的高级DBA。出公司后,我觉得我找到了突破高级DBA瓶颈的方法,哪就是Oracle DBA领域中新的方向:调试Oracle。将调试与运维合二为一的新领域。

       马云是舞台感很好的演说家,因此阿里的风格也是开放、高调。双11民间造节的成功,让所有人都无法怀疑这点。马云又在宣称要用双11撬动房价,无论撬动的结果如何,将双11和中国最具争议性字汇:“房价”联系在一起,无疑会让双11影响力进一步扩大。不但“造节”,阿里制造的概念,同样不乏震动业界的,比如“去IOE”。

       和双11一样,去IOE已经是一个充满魔力的词汇,它神秘、充满悬念,又极富争议。和双11一样,它也像风暴一样,席卷了数据库界。和双11一样,它也有伟大的理想。双11要最终撬动房价、改变中国,去IOE要撬动“核心技术国外论”,要使中国走上自主核心技术的发展之路。有人说2013双11第一分钟订单金额就已经过亿了,主要阻塞在银行,如果银行也可以去IOE,第一分钟订单金额就不只过亿了。先不说支付宝的去O情况,单想想去年双11淘宝的超买现象。如果银行也来个“超取”,那就真是太刺激了。

       不过,经过几年去IOE的宣传,Oracle技术圈的确被打压的萎靡不振,每个Oracle DBA都在考虑自己的未来之路,Oracle已经变成明符其实的夕阳产业。甚至连带着整个运维的大环境,都大不如前。一些前辈高人纷纷转管理、出国,新人们在去IOE的影响下,更加关注分布式、大数据、云这些新兴行业,很少人静下心来研究运维技术。导致一些奇怪的运维问题,无人可以解答清楚。2011年春、夏之交,有两套某存储厂商的中端存储背板有问题,导致存储宕机。因为两套存储先、后宕机,我们希望厂商能给个说法,最后的回复是“因为前段时间日本福岛核泄露,导致空气中微量元素的辐射超标,造成电子设备运行不稳。”还有一次是另一家存储设备供应商,在存储设备出问题后,给出的原因是“太阳黑子爆发,大量中微子等量子穿过设备,造成问题。”看来去IOE之后,运维工程师已经可以闲到研究量子物理了。

       我相信,随着去IOE风瀑的进一步影响,以后这样的奇怪回答将越来越多。我也相信总有企业不满足这样的奇怪答案,一些深入的问题,总要有人去研究。靠在这个新领域的研究成果,我迅速得到了很多Oracle DBA的认可。很多人说我给萎靡不振的Oracle技术圈注入了新的活力,我相信调试与运维的结合,将是DBA新的春天。也欢迎大家一起加入这个新领域,共同重振运维雄风。去年我写了很多文章,介绍如何使用DTrace、gdb/mdb研究Oracle,年初还写了一篇如何阅读Oracle反汇编代码的文章,今年以来写文章的进度慢了,因为我一直在著作《Oracle核心技术揭密》,随着这本书进入收尾阶段,我会更多分享文章,介绍如何“调试Oracle”。

       达到可以调试Oracle的级别,你可以解决一切Oracle问题,当然了,前题是只要有时间。因为一次调试、研究,需要大量时间。理解反汇编代码,没有相像中哪么容易。我的方法是,养兵千日,用在一时。平常多调试、钻研,如果遇到的问题正好是你以前研究过的,哪不就很快能搞定吗。

       最近我以高管级别的技术人员入职京东,证明了“调试ORACLE”这个方向正逐渐被技术圈接受、认可。但很可惜,由于自身、家庭原因,我只在京东待了两周。

       相比阿里,京东还是比较封闭的。每年各种IT技术大会,总少不了阿里人的身影,但京东鲜有人参加。但这两周在京东的耳闻目染,京东的技术还是很牛的。比如ORACLE数据库这块,数据库可用性,维护水平绝对不在全盛时的阿里之下,只可惜京东规定较严,通常不允许对外宣传,否则,大家又可以听到一些不错的技术思想。

       很可惜没能在这样的团队中和大家共创辉煌。但离开后也多了一些自由度,可以更多的宣传“调试ORACLE”的方法,让更多的人从中受益。

       在调试Oracle之后,还有一个最终级别。为了调试,C语言、数据结构要掌握的不错,还要有汇编、操作系统和CPU的相关知识。你已经把这些东西掌握的这么好了,完全可以根据需要开发自己的调试工具。如果不想老是在调试这一块搞,既然已经调试了Oracle这么多年,对Oracle机制如此熟悉,完全可以模仿Oracle,写一些自己的东西。比如,Oracle的内存管理是很优秀的,这已经被无数大型企业所验证。只是网上所能查到的资料,缺失了很多细节,比如LRU的算法,或者更具体的HASH算法。但现在不一样了,经过调试Oracle,你会看的比别人更清楚。这时,要吸收Oracle优秀的思想,设计自己程序的架构,也并非难事了。

       这是我所希望的最终方向,我目前还只处于调试Oracle阶段,希望以后有时间我可以再进一步。

       从前有个叫拉里.沃尔的SA(系统管理员),觉得UNIX下处理报表非常不方便,awk、sed等工具都有不足之外,就自己写了个工具方便处理报表,这个工具就是Perl。拉里.沃尔从些进入世界级IT神人名单,再也不用担心自己的未来之路。

       我并没有写个Perl这样远大的理想,我只想在运维、调试Oracle之余,写个工具可以更好的运维、使用数据库,让数据库跑的更快。这就是我的最终方向了。


refer to:http://bbs.51cto.com/thread-1085647-1.html

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:37796次
    • 积分:712
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:4篇
    • 译文:7篇
    • 评论:19条
    文章分类
    最新评论