clean code

i create stuff

《反倦怠能量站》读书笔记:重新找回你的能量感

| Comments

在这个人人喊累的时代,我们似乎陷入了一种奇怪的困境:明明没做什么体力活,却总觉得身心俱疲;明明想要努力,却总是拖延内耗。刀熊的《反倦怠能量站》像一面镜子,照出了现代人能量枯竭的真相——问题不在于我们不够自律,而在于我们一直在用错误的方式对待自己。

以下是我从书中整理的核心 takeaways,希望能帮你重新认识能量感,找到属于自己的能量恢复路径。

PHP的两个时间函数

| Comments

最近经常需要处理时间,一直在用这两个函数:

date()

date()可以将时间戳格式化成字符串,最常用的就是YYYY-mm-dd HH:ii:ss这种格式了。可以不加$timestamp参数,默认是当前时间。

1
$time_str = date('Y-m-d H:i:s', $timestamp)

PHP cURL使用小结

| Comments

实习这段时间主要在写PHP和很少的Python和Java。之前写过的PHP不超过100行,Java几乎没写过,算是都入了个门。

项目需要作为客户端发起HTTP请求,查一些API来分析一些数据,于是就接触了cURL这个库。作为天生的web语言,PHP在这方面真是太厉害了,居然自带了HTTP请求的函数。除了cURL外,file_get_contents这个函数也可以发起HTTP请求,不过不是专门干这个的,不好配置参数,还是cURL好。

MyISAM与InnoDB区别

| Comments

MyISAM和InnoDB是MySQL两种最常用的存储引擎,最近几次面试都有问到区别,感觉答得不好,今天专门抽时间研究下。

设计目标

InnoDB设计目标是处理大容量的数据,而MyISAM追求的是性能,两者产生的差异也是基于这点。 InnoDB是MySQL的默认存储引擎。

mac下向NTFS文件系统写入文件

| Comments

mac下默认是不支持NTFS格式的文件系统的写入的,可以用NTFS Paragon这款软件(不过是收费的,要找破解版或者激活码,搜了好多都不能用)或者是免费的ntfsMounter(在我的系统上不能用,也不知道为什么。)

判断欧拉回路

| Comments

昨天开始学习图算法,正好hihoCoder这周的题目是判断欧拉回路,AC之。

如何判断欧拉回路?

欧拉回路即小学时就学过的一笔画问题,不再分析了,判断条件为“奇点个数为0或2个的连通图”。所以首先要判断是否是连通图,从一个结点开始遍历图,如果最终存在结点没被访问,则不是连通图;然后计算奇点个数即可。

图的存储

第一次做图论的题目,怎么存就卡住了。首先想到的是邻接矩阵,但是邻接矩阵在结点数很多的情况下会占用很多内存,而且对于边数较少的图(稀疏图),大部分的边都是0,很浪费资源。所以一般用的是邻接表,开一个vector的数组,每个vector存该结点相邻的结点即可。

图的遍历

BFS和DFS听了很多了,即宽度优先搜索和深度优先搜索。深度优先就是访问一个结点A,假设与A相邻的结点还有B和C,接着访问B,再访问和B相邻的结点,直到不能再访问为止。DFS用到了栈,可以用递归隐式地调用栈,写起来就只有几行。BFS将与当前结点相邻的结点依次存入队列,再访问队列中的结点。

一次AC,爽爽爽!贴上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <cstdio>
#include <vector>

using namespace std;

const int MAX_N = 10000 + 1;
vector<int> g[MAX_N];
int vis[MAX_N] = {};

void dfs(int v) {
    if (vis[v]) return;
    vis[v] = 1;
    for (int i=0; i<g[v].size(); ++i) {
        dfs(g[v][i]);
    }
}

bool solve(int v) {
    dfs(1);
    for (int i=1; i<=v; ++i) {
        if (!vis[i])
            return false;
    }
    return true;
}

int main()
{
    int v, e;
    scanf("%d %d", &v, &e);
    for (int i=0; i<e; ++i) {
        int s, t;
        scanf("%d %d", &s, &t);
        g[s].push_back(t);
        g[t].push_back(s);
    }

    // 非连通图
    if (!solve(v)) {
        printf("Part\n");
        return 0;
    }

    // 判断奇点个数是否为0或2
    int odd_point_cnt = 0;
    for (int i=1; i<=v; ++i) {
        size_t v_cnt = g[i].size();
        if (v_cnt % 2)
            ++odd_point_cnt;
    }
    if (odd_point_cnt==0 || odd_point_cnt==2) {
        printf("Full\n");
    } else
        printf("Part\n");
    return 0;
}

HackerRank Maximise Sum题解

| Comments

今晚被这道题折磨了好久,记录下。

题意

对数组的子序列(任意相连的元素)求和,找出所有和里对M的模中的最大值。

思路

开始就想到能不能按照“最大子序列和问题”的思路解决,后来发现无论是分治递归求解还是复杂度为O(N)的算法在这个问题中都没有用,于是看了题解。
Quora上找到了题解,看了半天才看明白。大意是,对于输入的数组v中的元素v[i],先找到v[i]之前所有数的和对M取模的值(包括v[i]),存到数组prefix中。这里有个技巧,

1
2
3
4
5
6
ull tmp = 0;  // unsigned long long
for (size_t i=0; i<v_size; ++i) {
    tmp += v[i];
    tmp %= m;
    prefix.push_back(tmp);
}

瞎扯淡 - 拖延症与项目延期

| Comments

我是一个资深的拖延症患者,症状最早可以追溯到小学的寒暑假,放假永远是痛并快乐着,整个假期基本就是一个拖延不做作业的过程,为了拖延,我真是什么事都干得出来,往往就是到了临近开学的时候就疯狂赶起作业来。那时挺羡慕“别人家的孩子”,能在放假一星期内完成所有作业。

多年的经验告诉我,拖延基本会让人陷入一个循环:拖延->愧疚->决定改变->失败->继续拖延。人人都想治好拖延症,可我发现拖延症似乎是绝症,并不能治好,了不起也就是缓解一下,该拖还得拖,但是我们也不能放弃治疗啊!

为什么拖延

知乎专栏幸福课里有一个关于拖延症的专题,我读完了大部分,感觉不错。动机在杭州老师分析出拖延的以下几个原因:

  • 诱惑导致的分心
  • 对压力的逃避
  • 对失败的恐惧
  • 弱者反抗的工具
  • 对未来的错估

完整的解释可以看这篇文章

我的拖延症总离不开社交网络,拖延的时候我常常会在微博、豆瓣、知乎中间来回刷,要知道这三个网站都是无底洞,随便哪一个一层层挖下去都能看很久。

我是怎么解决的

其实也并没有解决,只是稍微缓解了一点。好长一段时间里我手机的todo list软件都是爆满,150+的待办事项都很常见了、豆瓣上500+的书想读、300+的电影想看、浏览器书签里一大摞文章没看、一堆算法题没做。想到有好多事就很烦。最近发现我那些要做的事情总是存的很多,实际上分配的时间其实不多,真正沉下心来打码的时间也不多;另外,那些想做的事情都没有一个截止日期,导致我总是对要做的事感到很大压力却没有在具体的某一件事上有压力。对此,我做了几件事:

  • 睡前安排第二天的任务,把最想做的事情加到第二天的要做的事里,慢慢完成
  • 延期任务修改截止日期,因为延期任务放在列表里会让人感觉对它无能为力了,其实重新设定一个截止日期,设得宽松一些会让自己更有动力完成它
  • 多花时间,这个是必然的了,这段时间我基本上每天不在教室上课就是在启明做事情,感觉状态还是不错的
  • 过犹不及,不要太看重任务,完成的质量和热情还是很重要的

每天有自己的事之后,刷微博、微信等等的时间也少多了,形成了正反馈。

另外,专栏里还介绍了一种方法——试着和自己谈判。每当意识到自己要拖延时,告诉自己先做一会事情,比如做半个小时再玩,如果半个小时后自己进入了状态,想做事情了,那自然最好,如果不想做事了,就放松一下吧,也没关系~亲测有效。

项目中的拖延

项目管理是不是只是PM的事和程序员完全没有关系呢?我觉得不是,相反,项目的延期和程序员、设计师的关系是最大的,到今天在冰岩里合作过的几个PM我还没遇到一个能完全把控项目风险的。

软件工程课上我学到两点,一是任何软件都是有bug的,就看有没有人能发现;二是大部分项目都会延期,程序员总是对自己的能力估计过高。不算丰富的开发经验告诉我,有时接手一个任务,一开始可能觉得任务非常简单,对需求的理解逐渐加深后可能会发现做坑越多,发现自己的漏洞越多,项目的时间慢慢就不在自己掌控之内了。

在实际开发过程中,我们会经历一个产品讨论->确定需求->技术选择->开发的过程。这个过程涉及到的人会很多,就会出现沟通不足导致拖延的现象。程序员多半是脸皮薄的,有些同学会觉得自己没弄清需求再去问会让人觉得很蠢,于是开始自己琢磨,造成拖延。这时团队人员的熟悉度就非常重要,非常熟悉的同学是不可能出现这种问题的;同时对不清楚的同学的包容也很重要,如果对ta的解答不耐烦或者嘲笑ta,很可能会导致下次ta出现问题时陷入自己纠结的状态。

第二个坑就是技术坑了。毕竟我们都处于学习阶段,有不会的东西很正常,并且技术的世界本来就是个无底洞,谁能保证自己样样精通。碰到技术坑师傅教我的一定要学会Google,我也一直这么干,并且鄙视那些伸手党。但是我发现Google解决问题只适合于对要解决的问题有些了解,很明确问题所在的时候,如果完全一头雾水,就应该找人聊一聊,看自己哪些东西不懂,弄清大概后再搜索效率会很高,也不会浪费别人很多时间。其实没事的时候大家在启明就可以多聊一聊,聊聊最近碰到的一些问题、看到的一些新东西,交流技术上的困惑和烦恼是非常爽的一件事,我就很喜欢跟强哥聊遇到的一些坑和一些不理解的东西,这样大家成长都很快~

第三个坑是互相拖,尤其在人多的情况下,A和B可能都不想干活,刚好都需要跟C交流,C的活还没干完,于是A和B也不干了。这种现象很常见,尤其是客户端,设计没出图、后台没接口都能成为拖延的理由。

最后

其实拖延是压力管理、时间管理、自我评价等等的综合问题,只是一种现象,至于根源,还是能不能和自己好好相处,实在不行,就拖吧,也没什么大不了的,不过一定要让自己舒服,不要压抑自己,身心健康比什么都重要。

[翻译]Python漫游指南 - 编程风格

| Comments

原文: Code Style

如果你问Python程序员他们最喜欢Python的什么,他们通常会说是Python的可读性。实际上,良好的可读性是Python设计时的一个核心思想,这是根据一个广为认可的事实 比起写,代码更容易被人读 的思想设计的。

Python代码易读易懂的一个原因是它相对完善的代码风格的规范和Pythonic的成语。

另外,当一个Python老手(Pythonista)指出一段代码不够Pythonic,通常意味着这几行代码没有按照一般的代码规范来并且没有用公认的最好的(通常是最易读的)方式表达其意图。

在某些情况下是找不到一个大家都认可的方式去用Python表达一个意图的,不过很少有这种情况。

一般概念

明确的代码

虽然在Python中,一切黑魔法都有可能发生,但我们更推荐最明确和最直接的方式。
Bad

1
2
3
def make_complex(*args):
    x, y = args
    return dict(**locals())

[翻译]Python文件读写

| Comments

原文: Reading and Writing Files in Python

概览

在Python中, 读写文件不需要import任何库, 第一步是使用open函数获取一个文件对象

文件类型

文件通常被分为文本文件二进制文件, 文本文件通常是由很多行组成的序列(sequence), 而每一行又是很多字符(characters)组成的序列. 每一行由EOL(End Of Line)终结, 最常见的行终结符是\n, 又叫换行符. 反斜杠(backslash)表明下一个字符将被当作一个新行(译注: 这里没理解). 基本上不是文本文件的文件就是二进制文件, 二进制文件只能被了解其文件结构的应用处理.

Open()

我们使用内置的open()函数打开一个文件. open()返回一个文件对象, 一般会传入两个参数. 语法是:

1
file_object = open(filename, mode)  # file_object是储存文件对象的变量

[老博文迁移]推土小记

| Comments

十一这几天留在学校没回家跟胡扬,胡淼,强哥一起“推土”加上写一点新版新闻网的后台,这次来客串写点php。“推土”就是把原来的像17,43,45这几台跑windows的老机器尽量换成linux的,还有几台跑在45上的虚拟机都搬到13,14上。哎,想想之前做的有那么多网站就觉得好累。

今天一天我完成了原来用discuz搭的bbs的迁移,冰岩博客的迁移和华中大知多少的迁移,原先代码都在43上,数据库在17上,都是windows服务器,43上还有ftp服务,17上就什么都没有,dump下来的表都是用百度云上传的==!最后把它们全都放到13上了,整个都是体力劳动啊,后面应该想想一些重复的劳动怎样用脚本来解决掉。

数据库导出与导入

mysqldump -u username -p dbname > name.sql

1
2
3
CREATE DATABASE dbname;
USE dbname;
SOURCE name.sql;

[老博文迁移]linux管道命令学习(一)

| Comments

继续看鸟哥私房菜,看一直很想弄懂的管道命令(pipe)。第一次知道管道这个词还是在学django的时候,模板里的过滤器很像这里的管道。管道就是将输出在标准输出中的信息一次次处理最终打印在标准输出中,所以管道命令必须是接受标准输出的命令,cp mv ls都不是管道命令。

好用的lesstail

less

ls -al /etc | less就能用类似vi的方式浏览在屏幕上打印的内容了。还能用vi里的查找命令/?,可以避免滚屏,非常好用。

tail

  • tail filename输出文件最后10行
  • tail -n 5 filename输出文件最后5行
  • tail -F filename监视文件的改变,一有变化就显示出来

在分析error log的时候非常有用,可以查看最近的错误信息。

选取命令cutgrep

cut

cut针对的是输出的每一行,解释两个命令:

  • echo $PATH | cut -d ':' -f 5 -d 选项后面紧跟分隔符,-f表示取第5段
  • export | cut -c 12- -c 选项表示选取的字符数,从12到结尾,也可是类似12-15这样

grep

grep真是神一般的命令,可以配合ps aux找到想要的进程。 参数

  • -c计算找到的被查找字符串的次数
  • -i忽略大小写
  • -v输出查找结果的补集 例如last | grep -v 'root'找出非root的登陆

睡觉,明天继续整理剩下的内容ww

2014-9-22 于博客园

迁移批注:
Yesterday you said tomorrow…有了”一”就再没”二”了…
不过后来除了cut外这几个命令都很常用, 使用linux时还是带来了很大帮助~ 需要继续学习~

[老博文迁移]linux进程管理

| Comments

作为一个新手,部署Python网站的时候总会出各种各样的问题,这个时候我就很想知道是哪个程序没有运行。这几天读了鸟哥私房菜的进程管理这一章,还没读完,先做下笔记。

使用Flask实现用户认证API

| Comments

我们在开发网站时会采用sessioncookie的方式来处理登录权限问题, 而在移动应用中要验证用户身份采用登录时给用户生成一个token(令牌)的方式. 每次用户发出需要身份认证的请求时, 就需要验证一次token是否有效, 无效的情况包括token无法被解析等. 另一个问题是如果token被泄露, 用户的安全将受到威胁, 所以应当对这个token设置一个过期时间, 超过这个时间后应当重新登录, 这样可以将用户信息泄露的风险降低.

[老博文迁移]web.py+fastcgi+nginx 502

| Comments

web.py照着官方文档在服务器上搭好了后台。这次很奇怪地出现了一个Nginx 502 Bad Gateway的错误。

执行上面的kill `pgrep -f "python /path/to/www/index.py"`会出现错误提示,可是启动脚本的时候明明是提示spawn-fcgi: child spawned successfully: PID: 32401的信息的,然后还可以继续执行spawn-fcgi -d /path/to/www -f /path/to/www/index.py -a 127.0.0.1 -p 9002的脚本 ,同样会提示成功。

新博客终于搭起来了

| Comments

啰嗦

去年大概这个时候, 用jekyllgithub pages搭了一个静态博客, 当时乱折腾把ruby环境给折腾坏了, 加上对之前的主题始终不满意(代码高亮差以及审美疲劳等…), 一年都没有更博. 然后在博客园写了十几篇博客, 隔段时间看, 擦, 写得好low!

比较好的办法就是经常写, 把那些很low的文章顶到很多页之前, 就没人笑话了.