用tput做一个简单的倒计时

以前一直很好奇那种在shell里面出现的动态改变当前行内容的效果,比如你用apt-get install安装包时,shell最下面一行是进度,是不会被冲掉的,内容会动态改变;还有类似wget下载文件时的进度效果等。

最近学习shell,发现这些效果可以通过一个叫做tput的命令来实现,以下就是我在学习tput时做出来的一个简单的倒计时效果。shell脚本如下:

第一段是简单的参数检查,要求必须带一个参数,即count,比如10。
从echo -n ‘Countdown: ‘开始倒计时。tput这里有三次命令sc, rc, ed分别是保存当前光标位置,恢复保存的光标位置和清除从当前光标位置到设置行末尾的内容。
你可以想象,当前位置不断显示不同内容的原理是动态改变这个位置上的内容,对于图像来说,记录某个对象的位置,刷新显示时定位笔刷到对象的位置,清除对象所在位置上的内容,最后绘制内容。用tput来说,就是rc -> ed -> “绘制”命令。sc肯定是在最前面只做一次的,因为只要记录一次光标位置就行。

重点讲解完之后,为了显示出效果,用sleep 1按秒计时,否则你什么都看不到,因为太快了。输入上count参数对应$1,但是貌似不能用{1..$1}输出1到$1的序列,所以使用seq做,同时用tac反转顺序。

最后,各位可以运行一下脚本试试看。虽然很简单,但是个人对shell了解更进了一步。

导出并整理android通话记录的简单方法

最近需要导出自己手机的通话记录,找了个应用导出,之后自己做一些处理,得到了表格样子的通话记录。

应用我用的是Call Logs Backup & Backup,没有用腾讯手机助手之类的,简单为上。

简单的应用操作也很简单,Backup按钮帮你导出最近500条通话记录,默认备份到内部存储,建议备份到/mnt/sdcard下。
应用备份出来的是一个XML,同目录下还有一个XSL文件,用来美化XML样式的。XML的格式大致是这样:

calls.xsl就是同目录下的样式文件。
用浏览器显示XML时,默认会应用XSL,样子就是表格。和我的要求很接近了,除了默认通话记录是从最早到最近的,我想要的是最近到最早的。应用的配置我大致看了下,没有设置排序依据。写一段简单的python/ruby脚本肯定是可以做的。不过我看到call记录都是一行一行的,又知道有一个shell命令tac倒序输出,所以我自己做了点简单处理:

第一条命令复制第一行和第二行,即XML meta和起始标签。第二条命令倒序中间所有的call,行区间是[3:-1](python表达形式)。最后第三条命令补上结束标签

经过上述处理之后,用浏览器打开,再打印到文件(PDF),样子还是不错的。

shell学习小记1

以下内容为本人学习《Linux Shell脚本攻略》的一些笔记。如果你想好好学shell的话,个人非常推荐这本书。

关于软链接和链接文件

除了常规的ls -l找出链接文件之外,还有以下两种方式:

上面的命令直接打印链接文件的目标文件。

上面的命令查找当前目录下的所有链接文件。

链接文件的方式基本上都是ln命令,ln的参数-s指定创建的是软链接文件而不是硬链接。软链接和硬链接的主要区别个人归纳为:

  • 目录必须用软链接
  • 软链接支持跨分区,硬链接不行
  • 硬链接创建的文件和原始文件大小一致

Read More

vagrant使用小记

vagrant是一个简单实用的适合本地开发使用的虚拟机管理工具。默认基于virtualbox,也可以切换为基于vmware的模式。基于Ruby的配置文件相对在命令行操作virtualbox更容易些,特别是配置多虚拟机的情况下。以下主要是个人在使用时记录的一些点。

安装

ubuntu可以直接用apt-get安装。不过12.04版本的ubuntu对应的vagrant配对的是ruby 1.8,这可能不是你想要的。这时你可以从vagrant官网上下载deb,用dpkg -i方式安装。
因为我之前就装过virtualbox和ruby 1.9,所以不清楚如果这两个没有的时候dpkg -i安装时是否有问题。virtualbox和ruby实际也是用apt-get安装的。

下载base box

因为vagrant实际是操作virtualbox的,所以实际需要一个类似vbox的文件,或者说是安装了指定系统的虚拟硬盘,又称base box。如果你没有base box的话,就需要自己加载对应操作系统镜像逐步安装。
vagrant给的方法是执行

后面的URL实际就是vagrant提供的一个base box。执行这条命令时,vagrant会下载这个base box然后加入box列表中。有兴趣的人可以执行

查看所有安装的box。

Read More

无聊之作:简单模拟电梯程序[Java]

记得刚开始学Java时用的是《Java大学教程》,这本书每章都在介绍一点电梯程序的样子,加上上班天天都要坐电梯,突发奇想想要做一个模拟电梯程序。

一开始没想清楚电梯程序的运行方式,但是知道几个关键表现。

  • 电梯有静止的时候
  • 电梯往往停在最后请求的楼层,也有最后静止在底层(1楼)的,这相当于电梯在没有请求时自己按了一下1
  • 电梯存在插队现象,即电梯在1楼,A在8楼先按,B在4楼后按,如果电梯没到4楼的话,后按的人先进

其实还有一个关键点,一般电梯都是有向上向下提示的,电梯上行时,A在8楼按下,B在4楼按下的话,B是不会插队的。不过如果把这个也考虑在内的话问题会复杂很多,因为操作电梯会有两步:指示方向和指出具体楼层。为了简化问题,我实际考虑每个楼层只有一个按钮,不指示方向,电梯内仍旧有具体到达楼层的按钮。这样的电梯可能有点怪,但也可以用。

Read More

看似简单的一个问题:请求速率限制问题

最近遇到一个场景,在每分钟错误计数达到250时发送消息。这里的每分钟并不是说整点的几分,有可能是现在16:16:16到16:17:16。
我了解到周围有人是用分钟的定时器来近似实现的,首先这样就限制了是整点的分秒,其次只限于对时间不敏感的场景,第三不能精确到秒,比如要求1次每秒的限制,因为定时器中任务执行很可能超过1s,而且还有并发的副作用。
那么直接在每次错误后向前扫描数量的笨方法呢?明显效率太低。

个人对于这个问题进一步分析,认为这个属于请求速率限制问题,并且找到的合适的关键字rate limit之后去google。发现stackoverflow有关于这类问题的讨论。在阅读了诸多资料之后,自己了解到两种专门针对请求速率限制的算法:Leaky Bucket和Token Bucket。下面简单介绍一下两种算法。
Read More

postgresql小试

作为一个只用过mysql,外加在公司用oracle的苦逼程序员,今天趁着感冒差不多好的当口,学学之前就碰到过,但是始终没自己动手试过的postgresql。

首先说明一下,我是在vagrant做的虚拟机中搭建的postgresql。postgresql的具体安装方法是

安装好之后你可以通过下面的方式测试

如果列出一些数据库的话,那就代表成功。基本上apt-get install方式安装的不会失败的,除非你有别的程序占据了5432端口(postgresql默认端口)之类的。
为了方便,你需要建立一个数据库自己用。
Read More

[Java]排列和组合算法

下午花了点时间,把排列和组合算法搞出来了。网上一堆资料看了不靠谱,要么是不明所以的变量名,要么直接帖代码。

排列

实现要点:交换和顺序处理。考虑对[1, 2, 3, 4]排列。实际是排列

[1], [2, 3, 4]
[2], [1, 3, 4]
[3], [2, 1, 4]
[4], [2, 3, 1]

排列[1], [2, 3, 4]时,实际是排列

[1, 2], [3, 4]
[1, 3], [2, 4]
[1, 4], [3, 2]

从上面的分解可以看出,代码中实际要做的是交换当前的数字和右边数字中的某一个,具体来说,第一步是分别交换第一个和第一个,第一个和第二个,第一个和第三个,第一个和第四个。第二步是交换第二个和第二个,第二个和第三个,第二个和第四个。依次类推。递归的停止条件是右边的数组仅有一个元素,比如[1, 2, 3], [4]。具体代码如下,注意参数比较多的permutation方法。
start和end分别是第二个数组的起始位置和结束位置,当两者相等时,右边的数组只有一个元素,这时就可以直接输出排列的数组。
一般情况下,交换当前元素和右边数字中的一个,递归排列,在结束时交换回来(这步是必须的)。

Read More

手贱的后果

事情发生在上周三,准确的说是上周三中午。
那天中午在和别人讨论问题的时候突然觉得眼睛里进了东西,于是习惯性的揉了揉。
碰巧大冬天开着暖气的办公室异常的干燥,最近经常眼干,于是我又揉了两揉。
但是异物感犹在,于是我揉了三揉。
……
Read More

哈希表二次探测

最近重新看哈希表的东西,发现自己大致能看懂了。以下是自己从书中了解的几个重点。
二次探测是一个根据哈希函数散列到同一个位置即碰撞时重新查找的方式,具体来说,假如i是哈希函数得到的位置,如果i有值了,那么尝试查找i + 1×1,i + 2×2,i + 3×3…i + NxN。
其次和二次探测相关的是在哈希表的大小为一个质数,并且使用量在一半以下时出现碰撞或者聚类的机率很小。
下面写一下实现哈希表二次探测个人认为主要的两个点,剩下的就是一些具体实现的细节问题了。

查找下一个质数

在容量超过一半时重新散列。需要找到比当前表大小大一些的质数。个人实现如下(Java):

二次探测

二次散列每次增加的偏移都是平方数,实际计算时可以不用乘法,而是根据两个偏移的差。比如i + NxN和i + (N + 1)x(N + 1),差为2N + 1,这样计算就方便多了。示例程序如下(Ruby):