C# GDI+绘图高级编程

龙生   08 Jun 2016
View Details

高级T_SQL语法(2005)

排名函数: RANK() 返回结果集的分区内每行的排名,FIELD为排名依据。行的排名是相关行之前的排名数加1.例如有两个并列第一,那么后一个将排名第三,而不是第二。 语法:RANK() OVER([PARTITION BY clause]<ORDER BY clause>) 示例: select *, rank() over (partition by ClassID order by Mark DESC )as rank from dbo.Student 结果: DENSE_RANK():返回结果集分区中行的排名。在排名中没有任何间断。行的排名等于所讨论的行之前的所有排名数加1.例如有两个并列第一,那么下一个将排名第二,而不是第三。 语法:DENSE_RANK() OVER([PARTITION BY clause]<ORDER BY clause>) 示例: select *, dense_rank() over (partition by ClassID order by MarkDESC ) as rank from dbo.Student 结果: NTILE():将有序分区内的行分发到指定数目的组中。各个组由编号。,编号从1开始,对于每个行,NITLE()将返回此行所属组的编号。 语法:NTILE (int_expressions) OVER([PARTITION BY clause]<ORDER BY clause>) int_expressions:正整数常量表达式。用于指定每个分区必须被划分成的组数。 示例: select *,NTILE(4) over ( order by Mark DESC ) as NewCLASS fromdbo.Student   ROW_NUMBER()一般用于数据库分页。返回结果集分区内行的序列号。每个分区的第一行从1开始。 语法:ROW_NUMBER () OVER([PARTITION BY clause]<ORDER BY clause>) 示例: select *, ROW_NUMBER() over (partition by […]

龙生   07 Jun 2016
View Details

C#GDI+图像处理

支持格式:BMP、GIF、JPEG、EXIF、PNG、TIFF、ICON、WMF、EMF等,几乎涵盖所有常用格式 图像类: Image类:Bitmap和Metafile的类提供功能的抽象基类。 Metafile类:定义图形图元文件,图元文件包含描述一系列图形操作的记录,这些操作可以被记录(构造)和被回放(显示) Bitmap类:封装GDI+位图,此位图由图形图像及其属性的像素数据组成,Bitmap是用于处理由像素数据定义的图像的对象。 常用属性以及方法: 名称 说明 公共属性 Height 获取此Image对象的高度。 RawFormat 获取此Image对象的格式。 Size 获取此Image对象的宽度和高度。 Width 获取此Image对象的宽度。 公共方法 GetPixel 获取此Bitmap中指定像素的颜色。 MakeTransparent 使默认的透明颜色对此Bitmap透明。 RotateFlip 旋转、翻转或者同事旋转和翻转Image对象。 Save 将Image对象以指定的格式保存到指定的Stream对象。 SetPixel 设置Bitmap对象中指定像素的颜色。 SetPropertyItem 将指定的属性项设置为指定的值。 SetResolution 设置此Bitmap的分辨率。 构造BitMap实例: public Bitmap(Image ); //从现有图像创建,其中可换成等效参数 public Bitmap(int, int); public Bitmap(Image, bool );//bool:颜色校正标志位 public Bitmap(Type , string );//type提取资源的类, string 资源名 public Bitmap(int , int , PixelFormat );// PixelFormat像素格式 枚举 public Bitmap(int , int , Graphics);// Graphics设置分辨率 public Bitmap(int , int , int stride, PixelFormat , IntPtr );// stride 指定相邻扫描行开始处之间字节偏移量的整数。传递给此参数的值必须为4 的倍数。IntPtr指向包含像素数据的字节数组的指针。 PixelFormat枚举: 名称 说明 DontCare = 0 没有指定像素格式 […]

龙生   07 Jun 2016
View Details

C#GDI+基础(二)画刷详解

命名空间: System.Drawing.Drawing2D   SolidBrush:一般的画刷,通常只用一种颜色去填充GDI+图形 创建一般画刷: SolidBrush sdBrush1 = new SolidBrush(Color);   HatchBrush:阴影画刷,有两种颜色:前景色和背景色,以及6种阴影。 创建阴影画刷: HatchBrush(HatchStyle,Color);//前景 HatchBrush(HatchStyle,Color,Color);//前景、背景 HatchStyle对应阴影方案列表。 名称 说明 BackwardDiagonal 从右上到左下的对角线的线条图案。 Cross 指定交叉的水平线和垂直线。 DarkDownwardDiagonal 从顶点到底点向右倾斜的对角线,两边夹角比ForwardDiagonal小50%,宽度是其两倍。此阴影图案不是锯齿消除的。 DarkHorizontal 指定水平线的两边夹角比Horizontal小50%并且宽度是Horizontal的两倍。 DarkUpwardDiagonal 指定从顶点到底点向左倾斜的对角线,其两边夹角比BackwardDiagonal小50%,宽度是其两倍,但这些直线不是锯齿消除的。 DarkVertical 指定垂直线的两边夹角比Vertical小50%并且宽度是其两倍。 DashedDownwardDiagonal 指定虚线对角线,这些对角线从顶点到底点向右倾斜。 DashedHorizontal 指定虚线水平线。 DashedUpwardDiagonal 指定虚线对角线,这些对角线从顶点到底点向左倾斜。 DashedVertical 指定虚线垂直线。 DiagonalBrick 指定具有分层砖块外观的阴影,它从顶点到底点向左倾斜。 DiagonalCross 交叉对角线的图案。 Divot 指定具有草皮层外观的阴影。 ForwardDiagonal 从左上到右下的对角线的线条图案。 Horizontal 水平线的图案。 HorizontalBrick 指定具有水平分层砖块外观的阴影。 LargeGrid 指定阴影样式Cross。 LightHorizontal 指定水平线,其两边夹角比Horizontal小50%。 LightVertical 指定垂直线的两边夹角比Vertical小50%。 Max 指定阴影样式SolidDiamond。 Min 指定阴影样式Horizontal。 NarrowHorizontal 指定水平线的两边夹角比阴影样式Horizontal小 75%(或者比LightHorizontal小25%)。 NarrowVertical 指定垂直线的两边夹角比阴影样式Vertical小 75%(或者比LightVertica小25%)。 OutlinedDiamond 指定互相交叉的正向对角线和反向对角线,但这些对角线不是锯齿消除的。 Percent05 指定5%阴影。前景色与背景色的比例为5:100。 Percent90 指定90%阴影。前景色与背景色的比例为90:100。 Plaid 指定具有格子花呢材料外观的阴影。 Shingle 指定带有对角分层鹅卵石外观的阴影,它从顶点到底点向右倾斜。 SmallCheckerBoard 指定带有棋盘外观的阴影。 SmallConfetti 指定带有五彩纸屑外观的阴影。 SolidDiamond 指定具有对角放置的棋盘外观的阴影。 Sphere 指定具有球体彼此相邻放置的外观的阴影。 Trellis 指定具有格架外观的阴影。 Vertical 垂直线的图案。 […]

龙生   07 Jun 2016
View Details

C#GDI+编程基础(一)

GDI+存在的意义:将编程与具体硬件实现细节分开。 GDI+步骤:获取画布,绘制图像、处理图像   命名空间: System.Drawing命名空间提供对GDI+基本图形功能的访问 System.Drawing.Drawing2D:提供高级的二维和矢量图形功能 System.Drawing.Imaging:命名空间提供高级GDI+图像处理功能 System.Drawing.Text:提供高级GDI+排班功能 System.Drawing.Pringting:提供打印相关服务 System.Drawing.Design:扩展设计时,用户界面逻辑和绘制的类。用于扩展,自定义。   画图工具:   Graphics(画布):类封装一个GDI+绘图图面,提供将对象绘制到显示设备的方法,Graphics与特定的设备上下文关联。画图方法都被包括在Graphics类中,在画任何对象之前都需要创建一个Graphics类实例作为画布。 创建画布 (三种方法): 利用控件或窗体的Paint事件中的PainEventArgs。 适用场景:为控件创建绘制代码。 示例: //窗体的Paint事件的响应方法 private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; } //直接重载控件或窗体的OnPaint方法: protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; } 注意:Paint事件在重绘控件时发生。 调用某控件或窗体的CreateGraphics方法以获取对Graphics对象的引用,该对象表示该控件或窗体的绘图图面。 适用场景:在已存在的窗体或控件上绘图 Graphics g = this.CreateGraphics();   由从Image继承的任何对象创建Graphics对象。 适用场景: 需要更改已存在的图像 Image img = Image.FromFile(@"IMG\graph.jpg"); Graphics g = Graphics.FromImage(img);   方法成员: 名称 说明 DrawArc 画弧。 DrawBezier 画立体的贝尔塞曲线。 DrawBeziers 画连续立体的贝尔塞曲线。 DrawClosedCurve 画闭合曲线。 DrawCurve 画曲线。 DrawEllipse 画椭圆。 DrawImage 画图像。 DrawLine 画线。 DrawPath 通过路径画线和曲线。 DrawPie 画饼形。 DrawPolygon […]

龙生   07 Jun 2016
View Details

DrawString 抗锯齿

在绘制文字之前加上这一行,就可以绘制任意文字而不会出现锯齿: g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;   from:http://blog.sina.com.cn/s/blog_7744890b0102v13q.html

龙生   07 Jun 2016
View Details

SQL中Group By的使用

1、概述 2、原始表 3、简单Group By 4、Group By 和 Order By 5、Group By中Select指定的字段限制 6、Group By All 7、Group By与聚合函数 8、Having与Where的区别 9、Compute 和 Compute By 1、概述 “Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理。 2、原始表 3、简单Group By 示例1

返回结果如下表,实际上就是分类汇总。 4、Group By 和 Order By 示例2

返回结果如下表 在Access中不可以使用“order by 数量之和 desc”,但在SQL Server中则可以。 5、Group By中Select指定的字段限制 示例3

示例3执行后会提示下错误,如下图。这就是需要注意的一点,在select指定的字段要么就要包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中。 6、Group By All 示例4

示例4中则可以指定“摘要”字段,其原因在于“多列分组”中包含了“摘要字段”,其执行结果如下表 “多列分组”实际上就是就是按照多列(类别+摘要)合并后的值进行分组,示例4中可以看到“a, a2001, 13”为“a, a2001, 11”和“a, a2001, 2”两条记录的合并。 SQL Server中虽然支持“group by all”,但Microsoft SQL Server 的未来版本中将删除 GROUP BY ALL,避免在新的开发工作中使用 GROUP BY ALL。Access中是不支持“Group By All”的,但Access中同样支持多列分组,上述SQL Server中的SQL在Access可以写成

7、Group By与聚合函数 在示例3中提到group by语句中select指定的字段必须是“分组依据字段”,其他字段若想出现在select中则必须包含在聚合函数中,常见的聚合函数如下表: 函数 作用 支持性 sum(列名) 求和 […]

龙生   06 Jun 2016
View Details

“System.Data.Entity.Internal.AppConfig"的类型初始值设定项引发异常。

必须写在

之后 。 from:http://www.cnblogs.com/A2008A/archive/2012/08/10/2631443.html

龙生   02 Jun 2016
View Details

如何用开源经历为你的简历增加光彩

在这篇文章中,我将会分享我的方法,让大家利用开源贡献在技术领域的求职中脱颖而出,成为强有力的候选者。 凡事预则立,不预则废。在你即将进入一个新的领域或者正准备熬夜修订你的简历之前,清楚地定义你正在寻找的工作的特征是值得的。你的简历是一部有说服力的作品,因此你必须了解你的观众,从而让它发挥出所有的潜力。看你简历的可能是任何需要你的技能并且能在预算之内聘用你的人。当编辑简历的时候,读一读你的简历上的内容,同时想象一下,以他们的角度怎么看待这份简历。你看起来像是一个“你”将会聘用的候选人吗? 我个人认为,对于目标职位的理想候选人所表现出来的关键特征,列出一张清单是很有帮助的。我结合了个人经验、阅读工作招聘信息、询问相同角色的同事等方面来收集这个清单。LinkedIn 和各种会议是寻求一些乐意提供这种建议的人的很好的地方。一些人喜欢谈论他们自己,那么通过邀请他们讲述他们自己的一些故事可以帮助你来拓展你的知识面,这样大家都会感觉很好。当你和其他人谈论他们的职业路线时,你不仅将会明白怎样去得到你想要从事的工作,而且还能知道你应该避免那些容易让你失去工作机会的特征或行为。 例如,对于一个不太资深的工作位置来说,关键特征列表可能如下所示: 技术方面: 拥有 CI (持续集成) 方面的经验,特别是 Jenkins 深厚的脚本编写背景,如 Python 和 Ruby 精通 Eclipse IDE 基本的 Git 和 Bash 知识 个人而言: 自我驱动的学习者 良好的交流和文档技巧 在团队开发方面富有经验(团队成员) 精通事件跟踪的工作流 尽管去申请职位 记住,你没有必要为了得到一份工作而去满足上面的工作描述列表中列出的每个标准。 工作细节(JD)描述了这个角色,让你一开始就知道你即将签约并为之工作几年的公司的全部信息,并且这份工作并不会让你觉得有什么挑战性,或者要求你去拓展你的技能。如果你对你无法满足清单上的技能列表而感到紧张,那么检查一下自己是否有来自其他方面的经历并能与之媲美的技能。例如,即使有些人从来没有使用过 Jenkins[1],那他也可能从之前使用过Buildbot[2] 或者travis CI[3] 的项目经验中明白持续集成测试的原则。 如果你正在申请一家大型公司,他们可能拥有一个专门的部门和一套完整的筛选过程来确保他们不会聘用任何不能胜任职位的候选人。也就是说,在你求职的过程中,你所能做的只是提交申请,而决定是否拒绝你是公司管理层的工作。不要过早地将工作拒之门外。 现在你已经知道了你的任务是什么,并且还知道你将需要让面试官印象深刻的技巧。下一步要做的取决于你已有的经验。 制造已经存在的事物之间的关联 列出一张你过去几年曾经参与过的所有项目。下面是一条快速得到这张清单的方法,跳转到你的 Github profile 中的Repositories标签页,并且过滤掉 fork 过来的项目。除此之外,检查下你的清单上是否有曾经处于领导地位的Organizations[4]。如果你已经有了一份简历,那么请确保你已经将你所有的经历都列在了上面。 考虑下任何一个你曾经作为一个潜在的领导经历并拥有过特权的 IRC 频道。检查下你的 Meetup 和Eventbrite 账号,并将你曾经组织过或者作为志愿者参与过的活动添加到你的清单上。浏览你前几年的日程并且标注所有志愿服务,或者有作为导师的经历,又或者参与过的公共演讲。 现在进入了比较艰难的环节了,将清单上列出的必备技能与个人经历列表上的内容一一对照,我喜欢给该工作所需要的每个特征用一个字母或者数字作为标记,然后在每一段你经历或参与过并表现出了某一特征的地方标记相同的符号。当你不太确定的时候,那就毫不犹豫地标记上它,尽管这样做更像是在吹嘘,但也好过显示出你的无能。 在我们写简历的时候常常被这样的情况所困扰,就是我们不愿冒着过分吹嘘自己的技能的风险。通常应该这样去想,“那些组织了聚会的人会表现出了更好的领导才能和计划技巧吗?”,而不是“当我组织了这个聚会的时候我是否展示出了这些技巧?”。 如果你已经充分了解了你在过去的一两年里的业余时间都是怎么度过的,而且你写了很多代码,那么你可能现在正面临着一个令人奇怪的问题,你已经拥有了太多的经验以至于一张纸的简历已经无法容纳下这些经验了。那么,如果那些列在你的清单上的经验,但无法证明你尝试去表现的任何技能的话,那么请扔掉它们吧。如果这份已经被缩短的简历清单上的内容仍然超过一张单页纸的容量的话,那么将你的经验按照一定的优先级排序,例如根据与所需技术的相关经历或丰富经验。 在这一方面,显而易见,如果你想要磨练一个独特的技能,那么你就需要一个不错的经历。考虑使用一个类似 OpenHatch[5] 的问题聚合器,并用它来寻找一个通过使用你从没使用过的工具和技术来锻炼你的技能的开源项目。 让你的简历更加漂亮 一份简历是否美观取决于它的简洁度、清晰度和布局。每一段经历都应该通过足够的信息来展示给读者,并让他们立刻明白为什么你要将它包含进去,而且恰到好处。每种类型的信息都应该使用一致的文档格式来表示,一份含有斜体格式的日期或者右对齐的或者与整体风格不协调的部分绝对会让人分心。 使用工具来给你的简历排版会使之前设定的目标更加容易实现。我喜欢使用 LaTeX[6],因为它的宏系统能够使可视化一致性变得更加容易,并且大量的面试官都能一眼就认出它。你的工具的选择可能是LibreOffice[7] 或者 HTML,这取决于你的技能和你希望怎样去发布你的简历。 记住一点,一份以电子方式提交的简历可以通过关键字被浏览到。因此,当你需要描述你的工作经历的时候使用和工作招聘告示一样的英文缩写对你的求职会有很大的帮助。为了让你的简历更加容易被面试官看到,首先就要放上最重要的信息。 程序员通常难以在为文档排版时量化平衡和布局。我最喜欢的修改和评估我的文档中的空格是否处于正确位置的技术,就是全屏显示我的 PDF 或者打印出来,然后在镜子里面查看它。如果你正在使用 LibreOffice Writer,保存一份你的简历的副本,然后将你的简历中的字体换成一种你看不懂的语言。这两种技术都强制将你从阅读的内容中脱离出来,让你以一种新的方式查看文档的整体布局。他们把你从一个“那句话措辞不当!”这样的批评转到了注意如“在这行上只有一个字,看起来挺逗”之类的事情。 最后,再次检查你的简历是否在它将要的展示的多媒体上看起来完全正确。如果你以网页的形式发布它,那么在不同屏幕大小的浏览器中测试它的效果。如果它是一份 PDF 文档,那么在你的手机或者你的朋友的电脑上打开它,并确保它所需要的字体都是可用的。 接下来的步骤 最后,不要让你辛苦做出来的简历内容浪费了,将它完整的复制到你的 LinkedIn 帐号上(完全使用招聘公告中的流行词),然后毫无疑问招聘人员就会找到你了。尽管他们描述的工作内容并不是恰好适合你,但是你可以利用他们的时间和兴趣来得到关于你的简历中有哪些地方好与不好的反馈信息。 作者:edunham[8] 译者:pengkai[9] 校对:mudongliang[10],wxy[11] 本文由 LCTT[12] 原创编译,Linux中国[13] 荣誉推出 [1]: https://jenkins-ci.org/ [2]: http://buildbot.net/ [3]: https://travis-ci.org/ […]

龙生   02 Jun 2016
View Details

17 年编程生涯的三大经验总结

今年将迎来我编程的第十七个年头。我的编程之旅始于九十年代末,上大学的时候,主要涉足基于表格的网页设计,传统的ASP,和Microsoft Access数据库。原来只是当作业余爱好的编程现在已经成为了我的事业和激情。我一生一半的时间都在学习、蹒跚、成功、失败,并且经常情不自禁地为代码 美丽和复杂的天性而折腰。 我在代码上淫浸了足够长的时间,因此看到了很多语言和平台的兴盛和消亡,看到了很多模式被普及,被苛责,然后再次被推广。在某些时候,我常常分不清这是大势所趋还是明日黄花。 编程的流行趋势是短暂的,但我坚守的规则,往往在生活中的其他地方也能发挥作用。事实上,生活就像代码(我已经买了这个域名来证明这一点!)。以下是我总结的3个伟大的经验教训,历经一次又一次编程和生活的大浪淘沙。 1.可商榷的决定往往是一种权衡。 伟大的辩论总是发生在开发社区中。无论它是最近关于TDD作为web开发的一种可行方法的辩论,还是什么水平的开发人员应该使用ORM(或 micro-ORMs)。无论是.NET MVC应该优于WebForms还是以JavaScript为中心的app应该比基于页面的app更受青睐,对我来说,答案都一样:看你权衡之后的取舍? 在任何比较两种流行方法的辩论中,我们总是会从自己的立场出发,两利相权取其重,两害相权取其轻。在我的职业生涯早期,我曾执着于追求所谓的正确答 案。感觉过程是线性的:摆脱做事的老办法,转而投向新的并且更好的方法的怀抱。曾经有一段时间我深信,编写自己的SQL查询是一种过时的练习,并且 ORMs是最后赢家。 但是,我了解到,更好的办法应该由内容决定的。例如,今天完全成熟的ORMs在隔离映射相关数据网格到对象的冗长管道提供了伟大服务,但隔离也使得某种非标准查询变得困难并且有潜在的效率低下问题。n+1 select problem就是经典的在少写代码和写更多高效代码之间做权衡。我使用ORM的程度完全受我期待应用程序使用的数据量,我所受到的潜在的时间限制,app长期可扩展性需求这三者的影响。(顺便说一句,我目前是micro-ORMs,比如说Dapper的忠实粉丝,它能让我编写我自己的SQL和一些精巧的对象-关系映射)。 我已经将这个经验应用到了我生活的其他方面。我是应该买一套公寓还是长租房子?我是应该启动自己的生意还是工作于已经成立的公司?没有绝对正确的选择。当你权衡利弊了之后,你便可以更好地应对生活中的各种难题。 2.清晰并不总和简洁相关。 和大多数工程师一样,我对持续重构一直到代码尽可能地少和简洁的机会垂涎三尺。如果可以选择更少又更简洁的代码来完成同样的任务,那么我为什么要选 择要个更多代码的方案呢?通常情况下,更简洁的语言会导致更好的交流。画蛇添足只会阻碍核心信息的提取。但是,最终的目标不应该是简洁——而应该是可交 流。于我而言,下面这段直截了当的代码,在它更长的时候…… ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 if (HasFarm() && HasBoat()) {   Broadcast("You are wealthy!"); } else if (HasFarm() && !HasBoat()) {   Broadcast("You are OK!"); } else if (!HasFarm() && HasBoat()) {   Broadcast("You are OK!"); } else if (!HasFarm() && !HasBoat()) {   Broadcast("You are poor!"); } ……反而比这个简洁版本更明确。 ? 1 2 3 (HasFarm() && HasBoat()) ? Broadcast("You are wealthy!") :  (HasFarm() || HasBoat()) ? Broadcast("You are OK!") :  Broadcast("You are poor!"); 虽然这是一个品味问题(有些人可能会觉得后者看上去更加一目了然),但是我在这里要表述的观点是,有时候解释的最伟大方法并不是简化。这个经验也适 用于日常生活,我花了大量时间来思考怎么样才能更好地传达消息以便于对方接收——有时更详细的讲解并非没有价值,而是更明确传达信息的必须。 举例来说,我想要更明确和更详细地告诉我爸爸应该如何关闭iPad(“按住右侧的按钮一段时间……”)。或者,我看似多此一举地键入了一些我已经提 交到本地分支的内容给我的同事(“刚刚犯的错误已被修复”),然后当它涉及到部署更新到产品中时,我就能很明确地知道哪些具体的提交被合并和出现(“检查 4812-4822行,其中包括在6/15发行版本中的DoneDone问题,将在今晚的产品发布中提出来。”)。 3.累计良性债务,并且要持续偿还。 我在一个特别害怕欠债的家庭中长大。八十年代中期,我的父母倾其所有又东拼西凑,付了他们第一套房子75%的首付,然后在七年内付清了剩余款项。用现金支付是常态。信用支付在他们看来几乎是一种罪过。作为一个孩子,我的看法是,债务完全是坏的。我从不认为欠债是一种优势。 直到我看到其他人是如何对待债务的——在我20出头的时候——我终于知道了债务也可以是有益的。如果你能够合理地承担债务,那么之后你也能获得成功。如果借助现在更好的上升空间可以加速你之后的成长,那么债务可以成为一笔巨大的财富。 代码也是如此。有时它值得你现在承担一点债务——错过抽象或者有一些未优化的SQL代码——如果这样做可以让你更快地发布内容给不断增长的观众的话。关键是要了解你必须偿还它,以及你可以在适当的时间段之后偿还。 这就是债务在生活和编程中的窍门。偿还债务需要持续进行。将一周10%的时间用于重构,相当于你是在按时支付编码的信用卡账单。如果你保持一种持续、可支撑的还债状态,那么累积债务实际上对你是有好处的。 译文链接:http://www.codeceo.com/article/17-year-3-tips-programming.html 英文原文:Programming’s three life lessons 翻译作者:码农网 – 小峰 from:http://www.oschina.net/news/73943/17-years-code

龙生   02 Jun 2016
View Details
1 262 263 264 410