为了一个面试遇到的技术题目写的代码,请大家指教指教

2015-07-30 09:09:52 +08:00
 popbones

这是最近面试遇到的技术题目,虽然已经以失败告终,但是还是想听听大家对这样的代码的看法。

题目是这样的:

使用Python开发个命令行工具用于持久化一些个人信息(姓名、地址电话号码之类的)。支持至少两种持久话格式,其中一种为XML。然后通过两种方式显示他们(不需要使用图形界面)。不需要支持手动数据输入,可自行选择格式和测试数据。

此外还要让开发者能够简单的:1)添加其他的存储格式;2)查询当前支持的格式;3)提供其他的XML reader或writer。

要展示OO设计和设计模式知识。

这里是代码:https://github.com/popbones/CodeSample.Python.Serializer

对方的反馈:

代码太长,有点过于复杂了。建议简洁一些,例如少一些继承。避免在serializers中使用递归的__pack, __upack方法。

为了提高希望大家能给写建议。比如如何设计更好,哪里需要修改,哪里写的就是垃圾等等。

3155 次点击
所在节点    Python
14 条回复
virusdefender
2015-07-30 09:57:27 +08:00
大致看了下代码,没看懂用户输入的是什么,能否给个例子?觉得应该没有你写的这么复杂
popbones
2015-07-30 10:19:02 +08:00
@virusdefender 命令行本身来说是不需要这么复杂。但是也要能当作库使用。CLI例子: ./main.py -i xml -o json file.xml file.json
nooper
2015-07-30 10:22:00 +08:00
看了一些,按照TDD的思想,应该避免过多的if else 逻辑,但是if else 的判断过多会造成测试编写的困难,代码过于臃肿了,避免import * 这种,没有具体细看。
datou552211
2015-07-30 11:47:58 +08:00
添加格式可以使用多态来解决
ljcarsenal
2015-07-30 11:55:02 +08:00
这让你多长时间写出来?可以查资料么?感觉有点难度的样子
lilydjwg
2015-07-30 13:21:25 +08:00
文件命名好非主流啊。一般叫 src、docs、build 的,然后,build 目录是不放在仓库里的。
测试应该单独分个目录。源码文件还不少,为什么没有 setup.py 呢?也没有组织成一个 package,别人怎么安装呢?遇到模块命名冲突怎么办(反正它在我这里肯定跑不起来,因为我有个模块叫 serializer)?
saber000
2015-07-30 15:24:25 +08:00
代码没仔细看,因为我其实没看懂题目,不过建议楼主看下django的序列化实现:
https://github.com/django/django/tree/master/django/core/serializers
popbones
2015-07-30 16:58:04 +08:00
@ljcarsenal 一个星期,可以查资料。不过明显不是要写通用持久化程序所以并不算很难。

@lilydjwg 因为只是个trial的小程序,所以没有搞成模块,目录也比较随便。

@datou552211 请详述
czheo
2015-07-30 22:06:52 +08:00
第一感觉,目录结构的问题。文件夹首字母大写不能忍。

第二感觉,I/F的设计略晦涩。感觉lz应该是有java经验,在用java思维写python。

另外有些小细节。比如

命名晦涩缺乏一致性。
https://github.com/popbones/CodeSample.Python.Serializer/blob/master/Source/main.py#L5

if key in dict是合法的python语法,不用keys()。
https://github.com/popbones/CodeSample.Python.Serializer/blob/39dc43733314ceff47d262aa1069b1778c58f9d8/Source/serialization.py#L36
czheo
2015-07-30 22:32:58 +08:00
这么个课题,lz实现的东西倒是不少,但是有over design之嫌,吃力不讨好。
这种考核考察的主要还是代码结构,代码风格和代码习惯。
popbones
2015-07-31 05:36:26 +08:00
@czheo 一眼就被你看出来了,OO我确实是Java出身的。虽然这样,工作中Python也不会设计成这个样子,反而是被哪个展现OO知识的要求弄糊涂了。

你觉得Java和Python在面向对象设计方面最大的区别是什么?
czheo
2015-07-31 09:52:04 +08:00
Java程序员往往喜欢套一堆pattern,factory啊manager啊proxy啊什么的。
然后就是过渡的继承,又是爷爷又是爸爸又是儿子,不设计一个interface就不舒服。
Java的设计思想是class是最高级公民,所有东西必须定义在class里面,对于一些task往往是过度设计的,最简单的比如print这种其他语言基本都一行可以搞定的事情,java里面要写一堆没用的东西。

python里面variable,function和class/object都是平等的,该用哪个用哪个。
比如xml/json解析其实不需要什么serializer的概念,json.load/dump, xml.load/dump就够了,当你引入serializer的概念,就应该是serializer.serialze/deserialize,而你现在写的的I/F设计有点不伦不类。
又比如python下其实很多静态的helper method没必要在某个class下面,完全可以独立成function。
再比如很多不需要object的数据结构存dict/list/tuple就够解决问题了,像你的person_data,如果将来不在getter/setter里面做validation也没有其他的method,做一个class没太多必要;相反直接存dict/list,用现成的dicttoxml,json的包encode/decode就可以解决大多数问题,也不用自己再写轮子写递归这么复杂。

Java程序员很多说辞是,我这样写以后扩张性好。但实际上更多时候其实是过度的设计大大加大了代码复杂度,降低了代码可维护性。吃多少饭用多大的碗,没必要一上来就端个脸盆吃饭。

推荐看看这个视频,stop writing classes
<amp-youtube data-videoid="o9pEzgHorH0" layout="responsive" width="480" height="270"></amp-youtube>
popbones
2015-07-31 12:29:32 +08:00
@czheo 感谢你的回复

我跟你的想法一样,这也是拿到这个题目最令我纠结的地方。我的第一反应是感觉没什么可写的,如果实际工作中的代码,这样的需求,我觉得连继承都不是必须的。写的过程中我就一直纠结“要展示OO设计和设计模式知识。”这个要求,自己也是觉得越写越奇怪。

你觉得对于这样的一个题目,应该什么样的设计比较能满足它的要求呢?
czheo
2015-07-31 16:44:52 +08:00
主要还是看你的代码风格,工作中让人一眼就看的懂很重要。招聘者是在选择自己将来的同事,一看这代码理解起来就费劲,谁会愿意和这样的人共事呢?“展示“OO和设计模式又不是问你会多少pattern,而是看你是不是在合理的地方用了合理的继承和pattern,不必要的地方就不要写么。

其实,你的大的设计思路还是不错的,只是一些细节上写的繁琐了。这样的项目用一个类似Registry pattern控制用户添加的plugin的加载,顶多用个singleton控制plugin的单一实例就差不多了。其他也用不来太多的设计。

还有一个小tip,你写的serialization.py其实就是registry pattern的想法,只是你需要主动register,而其实可以通过metaclass或者是decorator做到auto registering。参考下面这个。
https://github.com/faif/python-patterns/blob/master/registry.py

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/209450

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX