V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
popbones
V2EX  ›  Python

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

  •  2
     
  •   popbones · 2015-07-30 09:09:52 +08:00 · 3146 次点击
    这是一个创建于 3390 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    题目是这样的:

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

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

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

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

    对方的反馈:

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

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

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

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

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

    第二感觉,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
        10
    czheo  
       2015-07-30 22:32:58 +08:00
    这么个课题,lz实现的东西倒是不少,但是有over design之嫌,吃力不讨好。
    这种考核考察的主要还是代码结构,代码风格和代码习惯。
    popbones
        11
    popbones  
    OP
       2015-07-31 05:36:26 +08:00
    @czheo 一眼就被你看出来了,OO我确实是Java出身的。虽然这样,工作中Python也不会设计成这个样子,反而是被哪个展现OO知识的要求弄糊涂了。

    你觉得Java和Python在面向对象设计方面最大的区别是什么?
    czheo
        12
    czheo  
       2015-07-31 09:52:04 +08:00   ❤️ 2
    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
    popbones
        13
    popbones  
    OP
       2015-07-31 12:29:32 +08:00
    @czheo 感谢你的回复

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

    你觉得对于这样的一个题目,应该什么样的设计比较能满足它的要求呢?
    czheo
        14
    czheo  
       2015-07-31 16:44:52 +08:00   ❤️ 1
    主要还是看你的代码风格,工作中让人一眼就看的懂很重要。招聘者是在选择自己将来的同事,一看这代码理解起来就费劲,谁会愿意和这样的人共事呢?“展示“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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2539 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:31 · PVG 09:31 · LAX 17:31 · JFK 20:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.