0%

第一章”Python Data Model”中主要介绍了Python中的特殊方法和一致性的优美。特殊方法在Python中无处不在,例如class中初始化__init__ 函数,对象的字符串表示__str____repr__ 等等。

使用特殊方法(special methods)

在Python中, 特殊方法又常被称为magic method, 命名以双下划线开头,双下划线结尾, 例如__init__.

  1. 特殊方法常被隐式的调用

    当使用方括号,例如obj[key] 的时候,其实Python解释器是调用了obj.__getitem__方法。

    for...in... 的时候,是解释器调用了__iter__方法, a in b 这里in用了__contains__

  1. 特殊方法一般由解释器调用

    有一些特殊例子例如len, 如果对象是用户定义的, 那len(a)会调用定义的__len__method。如果对象是Python内建对象,在CPython中则会直接返回PyVarObject中的ob_size值, 速度比调用自定义方法更快。一般很少手动调用特殊方法,最常用的应该就是初始化函数__init__了。 像len ,iter, str等方法在CPython中他们对于内建对象往往有特殊处理,会更快。

  2. __str____repr__的区别

    在class中我们经常用到这两个方法,如果2选1的话首先要实现__repr__方法,__str__往往返回一个人类易读的字符表示,__repr__则应该尽可能表现出这个class的唯一性,能够通过这个方法找到对应的对象。repr函数可以返回对象的字符串表示。

Python中的一致性(consistency)

作者开篇就提到:

One of the best qualities of Python is its consistency.

语言中的一致性可以让使用者在一些时候猜测或者自然的推理出正确的结果,特别是遇到一些新东西的时候。在设计中的这种一致性和符合人们直觉的设计让我想到了苹果的触摸控制,不论滑动还是放大缩小等操作,都符合人们的直觉。 最重要的是在手机上,iPad亦或者是在mac的触摸板上的操作保持着一致性,学习成本很低。

为什么len不是一个method

当我们想知道一个list的长度时,Python中使用len(a)而不是a.len().

作者在2013年就这个问题问了一位核心开发者。他对此的回答是:

the key to his answer wa a quote from the Zen of Python: “practicality beats purity”.

翻译一下就是实用性比纯粹更重要。在这里当对象是一个内建(built-in)对象的时候,len会比调用函数更快(第一部分中提到了)

关于The Zen of Python 可以进入Python iterpreter 输入import this 查看。

这是一篇纯吐嘈的记录。

上周三因为帮一家广州的公司去“鉴别”选择一些外包公司,所以周二聊了一下周三就飞到广州了。公司有一些业务需要开发一个主要在微信浏览器用的网站,之前看了一下需求觉得并不复杂,本以为两三天和几家公司谈谈价格定定工期就能谈完,没想到水太深,花了整整一周时间。

以前自己大二的时候也做过一些外包,同样也带过一个小团队在接一些开发任务。当时主要是冲着学习和熟练一下技术的目的做的,但这次去广州帮忙选择一圈发现原来那些外包公司的水真的很深。(城市套路深啊)

背景

这家公司本身没人懂技术,也没有大概的概念。之前已经找过一家小的工作室,但当时的工作室的老板估计不懂技术,费用和时间都随口说了一个,导致根本无法完成,不但浪费了钱还耽误了时间。我也怀疑那家工作室的程序猿半路离职了。所以这一次比较谨慎,让我当个小顾问去鉴别选择一下公司。我先对项目做了一个具体的需求整理和功能划分,然后估计了一下工期,大约2-3人花一个半月,其次是费用大约在6-8万。难度也不困难,主要功能也都比较基础,所以我一开始觉得给专业的外包公司做基本没什么问题。

鱼龙混杂的外包公司

各个公司的报价工期和水平简直天花乱坠。从5万到30万都有公司报, 因为每家公司第一次去的时候,我基本都会当作自己是不懂代码不懂行情的人。我感觉有些人明显就开启了忽悠模式。

第一种类型的就是直接20万以上的。有个典型特别不靠谱的公司藏在类似物流仓库的深处,老板上来跟我说他们都是接几百万单子的,也有自己的产品。然后就给我看了他们那个几百万的网站。我真的什么功能和业务都没看出来,我稍微具体问了问功能,他就拿出了一个只有“增删改查”功能的后台,给我科普“增删改查”功能之强大。(我当时真的想说我们大二数据库原理的大作业都比你做的好) 当然我继续做小白,提出想稍微看一下代码的样子之类的,问了问你们用的是什么语言,什么框架。然后他说他们用的是Java,语言安全性是最好的。(<-这是我看到java被黑的最惨的一次)。然后代码不让看,说他们公司准备上市了,因此保密。我接着问了问他们程序猿水平,能不能见一见。他又回答我说因为要上市了,程序猿在哪里不能告诉我。 (到这里已经无力吐嘈了..如果他们哪天上市了请告诉我,我一定清空我的A股。)
当然还是很礼貌的让他们给个具体的工期和报价单,然后他们给了个17万的价格, 还在括号里注明了”优惠10万”。后面我基本断定这家只是接下项目,然后再转包给其他外包公司,赚个差价。

第二种看起来就是虽然真的写代码,但是天知道在哪里埋了个地雷等你踩。 典型的一家看起来就是那种做一单是一单的外包公司,进门一看十几个很年轻的小伙子像黑作坊一样在里面写代码,他们说主要使用.net,开了个原价7万,工期一个半月。这一家奇葩的是当我问你们能不能申请软件著作权(因为有些政策会奖励有软件著作权的企业,也是公司需求之一)的时候,他跟我说申请软件著作权要一定要用原生框架,价格多2万,也就是一共9万,原生框架就是指不用那些类似Python中Django啊之类的框架。我一听,想想你们那么高端还能重头开发框架?于是提出想看一看框架,这是他一下子吱吱唔唔了起来,估计之前都忽悠的很成功,没人提出过要看所谓“原生框架”的代码。结果我一看,就是把框架生成的文件夹名字改了一改。例如如果框架自动生成了一个admin文件夹,那他们就改成xxadmin。改文件夹名你收我2万???而且实际上申请软著基本只要代码超过3000行再填一些表格就好了,审查的人能看得懂代码就怪了,还“原生”???

第三种就是打太极,上来先问了问公司的规模和发展,然后想要放长线掉大鱼。几个小时都在和我说迭代开发的概念,例如第一期先做一部分核心功能,不要做这个那个巴拉巴拉,然后投入市场看反应再修改云云,还能帮助我们一起运营和提升之类的。如果技术团队是自己的当然没做,但外包你这个模式是想吃多久的肉?在疯狂的砍了功能之后还提出报价17万,因为他说公司程序猿都是七八年经验的老司机了,我们要科学的按照有效工时来计算费用。当然最后也降价到12万,然后最后又降到10万下。

最后一种就是相对靠谱一些的,聊天过程也不坑你是个外行,有一说一很实在。技术上讨论起来也比较顺畅。大约报价8万,工期一个半月。 这一类就是属于正常的公司,看了下他们之前的作品和客户也有一些是大厂,例如快消行业和传统行业之类的,之前做的东西也都感觉不错。 看他们后台感觉图表做的都不错,他们也直言很简单就是用什么插件就可以了。真的是难得的老实..

第一轮初步接触下来,之后又对一些有希望的公司进行了第二轮细谈…这个过程真的比想象中累很多。也稍微理解了平时公司里Sales和一些负责前期落地和商谈的Manager的苦了。

感想

整个过程就像运用了“夹逼定理”,不断的压出各个方面的水分和忽悠..心累..

上面四种也只是一些典型的,每一家公司都各有“特色”。如果是不懂外包的公司,遇上前三种哪一种都很危险。其实和外包团队合作最怕的一是第一期功能的实现和修改。 二是怕如果公司有一期二期的功能需求开发,那么第一次合作之后更换公司的成本就非常高,像前面提到的第三类,可能第一次价格愿意降低,但是在后期肯定会逐渐把该吃想吃的肉都吃回去的。因此存在多次合作的时候也要考虑公司老板的性格和历史记录等。

我感觉未来外包公司可能会更偏向于长期合作的关系,而不是以前那种快糙猛的接单模式了。或许会有越来越多的偏向技术入股和长期开发服务运营类。

这周真的遇到了各种各样的人和公司,写了这么多还是觉得一言难尽一言难尽……但总的来说应该算第一次作为甲方出去谈合作,感觉还是学习到了很多,也算是锻炼了自己梳理需求,谈判,商务等各种能力了:)

不同行业不同公司都过的不容易呀..算是解锁新成就新姿势了…

广州早茶

这次一星期倒是吃了一些广州的早茶和潮汕火锅之类的(当然也把所有品牌的Junk Food也都吃了一遍了),在广州好像大家都喜欢边喝茶边谈生意,有一天早上吃了将近4个小时。广州的那种虾饺点心之类的做的确实不错,很好吃。喝茶也感觉比较健康,不像北方猛喝酒,好像江浙这边基本是饭局,可能有些地方还是洗浴。也算是体验了一次不一样的商业文化吧。

博客使用Hexo搭建,今天想给文章里面加上音乐链接,记录一下教程和修改部分。

Aplayer

Aplayer是一个html5的嵌入式播放器。可以使用官网提供的CDN进行引入。
因为我用的主题是hexo-next, 所以这里只写一下我简单的修改,其它的主题应该修改都类似。

  1. 在themes文件夹下找到hexo-theme-next, 这里就是存放next主题的地方。

  2. hexo-theme-next/layout/_third-party 文件夹下存放着各种第三方插件的模板。

    • 在_third-party/ 下创建aplayer.swig模板文件

    • 在aplayer.swig中加入以下两行<scripts>引入aplayer,如果出现问题可能是因为player.js需要在jquery后引入, 可以查看自己对应的主题是否用了jquery

      <script src="https://cdn.bootcss.com/aplayer/1.6.0/APlayer.min.js"></script>

      <script src="https://api.i-meto.com/music/player.js"></script>

  3. 修改hexo-theme-next/layout/_layout.swig, 引入上一步中创建的aplayer.swig。 在</body>前加入:

    '_third-party/aplayer.swig'

  4. 保存之后hexo g 重新生成所有文件。

如何使用

使用方法很简单, 在markdown格式的博文中,在需要插入音乐的地方加入以下div即可:

<div class="aplayer" data-id="29713168" data-server=”netease" data-type="song" data-autoplay=”true” data-mode=”circulation”></div>

参数配置如下:

  1. data-id: 歌曲/专辑/歌单对应的id。注意这里需要是歌曲原本的id,不是你自己歌单中点击后显示的。 (必须)
  2. data-server: 音乐平台, 大致支持以下几个,我只测了一下网易音乐和虾米音乐。(必须)
  • netease(网易云音乐)
  • tecent(qq音乐)
  • xiami(虾米音乐)
  • kugou(酷狗音乐)
  1. data-type:请求类型(必须)
    • song(单曲)
    • album(专辑)
    • playlist(歌单)
    • search(搜索)
  2. data-mode: 播放模式(可选)
    • random(随即)
    • single(单曲)
    • circulation(列表循环)
    • order(列表)
  3. data-autoplay: 自动播放(可选)
    • false
    • true

其它参数可以看官方文档

例子

验证没有失效

今天给博客配置了一下HTTPS, 稍微记录一些步骤。
我博客的VPS是DigitalOcean上ubuntu16.04。

选择证书签发服务(Certificate Authority)

首先选择了 Let’s Encrypt 了, 这是由ISRG(Internet Security Research Group) 提供服务, 来自美国加利福尼亚一个公益组织。主要的Sponsors里也有Mozilla, Goolge, Facebook等大厂。

申请证书我用的是 acme-tiny 这个工具。 按照上面的步骤一步步做下来就OK了。

可以在github上看到更多关于ACME 的内容

配置证书

Step1. 创建Let’s Encrypt账号所需的私钥

首先在用户目录下创建了文件夹https-ssl,之后在这里存放各种证书文件。

openssl genrsa 4096 > account.key

Step2. 为域名创建CSR(certificate signing request)

Let’s Encrypt 使用的ACME协议需要一个CSR文件。NOTE: 你不能对account和domain使用同一个私钥。

为域名生成私钥:

openssl genrsa 4096 > domain.key

生成crs, 以下命令同时对www.yoursite.com 和 yoursite.com 生效。

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr

Step3. 创建challenges 文件

Let’s Encrypt需要对你的主机和域名进行验证。 你需要保证它可以访问到.well-known/acme-challenge/这个url路径。 NOTE:Let’s Encrypt 使用的是HTTP 请求(80端口),所以这些文件也必须能通过80端口访问到。

通过nginx 配置:

location /.well-known/acme-challenge/ {
  alias /home/xxx/www/challenges/;
  try_files $uri =404;
}

创建challenge 文件夹

mkdir -p /home/xxx/www/challenges/

我的nginx 文件配置例子

server {
    listen 80;
    listen [::]:80;
    server_name www.bucketzxm.me bucketzxm.me;

    location /.well-known/acme-challenge/ {
      alias /home/xxx/www/challenges/;
      try_files $uri =404;
    }


    root /home/xxx/blog/public;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }
    location images/ {
        root /home/xxx/blog/public/images;
        autoindex on;
        try_files $uri $uri/ =404;
    }
  # SSL configuration
    listen 443;
    listen [::]:443
    server_name bucketzxm.me, www.bucketzxm.me;
    ssl on;
    ssl_certificate /home/xxx/https-ssl/chained.pem;
    ssl_certificate_key /home/xxx/https-ssl/domain.key;
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 5m;
    ssl_session_tickets on;
}

Step4. 获取签名证书

下载acme-tiny 脚本到Step1中所创建的目录下/home/xxx/https-ssl

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py`

运行python脚本

python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt

Step5. 安装证书

先添加Let’s Encrypt的中间证书。

wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem

把中间证书和网站证书合并在一起

cat signed.crt intermediate.pem > chained.pem

(OPTIONAL)
为了之后启用OSCP Stapling, 把根证书和中间证书合并

wget -O - https://letsencrypt.org/certs/isrgrootx1.pem > root.pem
cat intermediate.pem root.pem > full_chained.pem

Step6. 重启nginx服务

可以通过命令
service nginx restart 或者 service nginx reload 重新加载配置文件。(可以先用nginx -t测试一下配置文件修改是否语法正确等)

之后访问网站应该就可以看到https的连接了。

Step7. 配置自动更新

因为Let’s Encrypt证书一次只能持续90天,所以需要90天续一次。把以下脚本添加到crontab任务中就可以了:

#!/usr/bin/sh
python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /var/www/challenges/ > /tmp/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat /tmp/signed.crt intermediate.pem > /path/to/chained.pem
service nginx reload

crontab -l 可以查看当前用户的定时任务

crontab example

0 0 1 * * /path/to/renew_cert.sh 2>> /var/log/acme_tiny.log

其它注意点

  1. 对于博客中的其它资源,例如图片等,访问方式也要变成https。否则会加载不出。

测试

以下几个网站可以用来测试安装正确性和网站的安全性等, ** 显然这个博客还需要改进…orz **

1. 测试chain是否正确

可以通过WhatsMyChaincert 来测试整个chain是否正确。

2. 测试安全性

2.1 Qualys SSL Lab’s SSL Server Test

2.2 HTTP Security Report