2月 03

猴子们的问题

【2012 张子萌】
其实此问题比较容易,在网上也有很多版本。为了学习我自己做了一下,在CeotOS5.4系统编译调试通过。

猴子分桃子:有5只猴子在海边发现一堆桃子,决定第二天来平分.第二天清晨,第一只猴子最早来到,它左分右分分不开,就朝海里扔了一只,恰好可以分成5份,它拿上自己的一份走了.第2,3,4,5只猴子也遇到同样的问题,采用了同样的方法,都是扔掉一只后,恰好可以分成5份.问这堆桃子至少有多少只.

#include

main ()
{
int monkeys,peach=0,all_peach;
do
{
peach=peach+1;
all_peach=peach;
for (monkeys=5;monkeys>0;monkeys–)
{
all_peach=all_peach*5+1;
}
}while (((all_peach-1)/2)==0);
printf(“==>%dn”,all_peach);
}

结果如下:
# ./test
==>3906

猴子吃桃子:猴子第一天摘下N个桃子,当时就吃了总数的一半,还不过瘾,
就又吃了一个。第二天又将剩下的桃子吃掉一半,又多吃了一个。
以后每天都吃前一天剩下的一半零一个。
到第9天在想吃的时候就剩一个桃子了,求第一天共摘下来多少个桃子?

#include

main ()
{
int days,peach=1;
for(days=9;days>0;days–)
{
peach=(peach+1)*2;
}
printf(“==>%d”,peach);
}

结果如下:
# ./test
==>1534

猴子选大王:n只猴子围坐成一个圈,按顺时针方向从1到n编号。
然后从1号猴子开始沿顺时针方向从1开始报数,报到m的猴子出局,
再从刚出局猴子的下一个位置重新开始报数,如此重复,直至剩下一个猴子,
它就是大王。

#include

main ()
{
int monkeys,num;
int loops,kings;
int i,j=-1;
printf(“pleas input monkey amonut:”);
scanf(“%d”,&monkeys);
printf(“pleas input num:”);
scanf(“%d”,&num);
int m_k[num];
for (i=0;i {
m_k[i]=1;
}
kings=monkeys;
//start choose king
do
{
loops=num;
while(loops>0)
{
j=j+1;
if (j>monkeys-1) j=0;
if (m_k[j]==1)
loops=loops-1;
}
m_k[j]=0;
kings=kings-1;
}while(kings>1);
for (i=0;i {
printf(“%d “,m_k[i]);
}
}

结果如下:
# ./test
pleas input monkey amonut:6
pleas input num:2
0 0 0 0 1 0

10月 22

php python node.js 简单循环累加计算速度测试

【张子萌 www.simonzhang.net 2012-4-1】

之前简单做了一下node.js和python的“hello ***”的页面测试,也做了循环的测试,本次主要是增加了java的语言,go语言。主要是想看一下主流四种脚本的速度java、python、php、c语言。均使用for循环进行简单的累加测试。个人技能有限所以只做了简单测试做参考。

实验环境使用linux 64位服务器,操作系统为contos 5.4,php版本5.1.6,python版本为2.6.6,node.js版本为0.4.12,java版本为1.6.0_03,gcc 版本 4.1.2 2008070,go语言为1.0.2。
一、脚本编写
php脚本
# cat test.php

python脚本
# cat test.py

#!/bin/env python
#-*- coding:utf-8 -*-
def main():
    j = 0;
    for i in xrange(10000000):
        j=j+i
    print j

if __name__=="__main__":
    main()

node.js脚本
# cat test.js

var j=0;
for (i = 0; i < 10000000; i++ ) {
   j=j+i
}
    console.log(j);

Java代码:
# cat Test.java

public class Test {
public static void main(String[] args) {
          long n = 0;
          for (int i = 0; i < 10000; i++) {
               n=n+i;
          }
          System.out.println(n);
     }
}

C语言,使用gcc编译,编译两种结果,一种是直接编译的,一种是优化编译的。

#include 
#include 
main()
{
    long i,j=0;
    for (i=0 ; i<10000000 ; i++)
       j=j+i;
    printf("%ld\n",j);
}

go语言代码

package main

import "fmt"

func main() {
    var sum,i int64
    sum=0
    for i=0;i<10000000;i++{
        sum+=i
    }
    fmt.Printf("%d",sum)
}

二、运行结果
使用time命令对程序运行时间进行统计

以下是循环一千万次的累加测试结果。

参数 C语言直接编译 C语言优化编译 go Node.js Python PHP Java
Real 0.024s 0.001s 0.011s 0.420s 1.055s 1.429s 0.087
User 0.023s 0.000s 0.011s 0.401s 1.046s 1.423s 0.067
sys 0.001s 0.001s 0.000s 0.019s 0.009s 0.007s 0.015

以下是循环一万次的累加测试结果

参数 C语言直接编译 C语言优化编译 go Node.js Python PHP Java
Real 0.001s 0.001s 0.004s 0.090s 0.027s 0.014s 0.087
User 0.000s 0.001s 0.003s 0.080s 0.022s 0.007s 0.041
sys 0.001s 0.000s 0.002s 0.010s 0.006s 0.007s 0.017

三、结论
从简单的测试来看,c语言不是一般的快,大数据计算情况下node.js速度最快,java次之,python和php比慢。但是如果是少量计算时php效果还是很不错。但是实际应用中,还需要调用各种函数和各方面的资源,并不能以一个空框架下的for来判断。每种语言都会有自己擅长的一方面,速度快与慢,还与编写的技巧性有关。学好每一步,认认真真踏实的做就好了。

10月 11

突发想法:python 随机产生双色球投注

【2011-10-11 张子萌】
今天用python做redis的测试,主要测试随机读redis的效率。突发想法这个产生双色球的结果挺方便的。33选6 ,呵呵呵呵呵。

#!/bin/env python
# -*- coding:utf-8 -*-
import random
list = [“01″,”02″,”03″,”04″,”05″,”06″,”07″,”08″,”09″,”10″,”11”,
“11”,”12″,”13″,”14″,”15″,”16″,”17″,”18″,”19″,”20″,”21″,
“21”,”22″,”23″,”24″,”25″,”26″,”27″,”28″,”29″,”30″,”31″,
“32”,”33″]
get_array = random.sample(list,6)
print “%s”%get_array

10月 11

Reids的安装、配置和初级管理

【2011-10-11 整理编辑 simon-zzm@163.com】

一、 获取和部署

# wget http://redis.googlecode.com/files/redis-2.2.12.tar.gz

# tar zxvf redis-2.2.12.tar.gz

# cd redis-2.2.12

# make

src目录下会生成可执行文件,可以使用make install 进行安装,默认安装后放在/usr/local/bin中。也可以制定存放目录make PREFIX=/some/other/directory。可执行文件的作用

redis-server 服务器的daemon启动程序

redis-check-aof 数据修复

redis-check-dump 检查导出工具

redis-cli 命令行操作工具

redis-benchmark 性能测试工具,测试Redis在你的系统及你的配置下的读写性能

直接执行redis-server,使用默认配置控制台打印。再redis-2.2.12中有redis.conf配置文件的模板,可以将配置文件放到认可位置,建议放到/etc下,使用配置文件启动redis命令如下。修改系统内核参数

# echo vm.overcommit_memory=1 >> /etc/sysctl.conf

# sysctl vm.overcommit_memory=1

使用数字含义:

0,表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

1,表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

2,表示内核允许分配超过所有物理内存和交换空间总和的内存

启动

# redis-server /etc/redis.conf

二、配置说明

配置文件主要参数说明如下(多个#为系统默认注释的配置):

daemonize no

#默认不以守护进程的方式启动,生产环境下建议改为yes

pidfile /var/run/redis.pid

#pid文件位置

port 6379

#监听端口

bind 127.0.0.1

#监听IP地址,可用于监听指定IP

unixsocket /tmp/redis.sock

#sock文件位置

timeout 60

#超时断开时间

loglevel verbose

#日志级别debugnoticeverbosewarning

logfile stdout

#日志保存位置,默认是输出到/dev/nul,既不记录日志。

# syslog-enabled no

# 开启系统日志,默认关闭

###### syslog-ident redis

######syslog-facility local0

# 日志级别从LOCAL0-LOCAL7

databases 16

#数据库个数,登陆数据库默认dbid0,可以使用select 设置。

save 900 1

save 300 10

save 60 10000

# 持久化保持 save *(秒数)*(修改次数)保存到硬盘上。全部注释掉,则不进行持久化。

rdbcompression yes

# 持快照是否要压缩

dbfilename dump.rdb

# 快照文件名称

dir ./

#快照保存位置

######slaveof

# 如果为从库需要配置主库的IP和端口,需要注意,从机如果做数据修改是不能同步到主机的

######masterauth

# 如果主数据库有密码需要在从库上设置主库的密码

###### requirepass foobared

< p>#主数据库的密码设置,如果加密了客户端连接为./redis-cli?-a foobared

slave-serve-stale-data yes

# 当主库宕机时,备机接替主库工作

######requirepass foobared

# 设置客户端登陆访问密码

maxclients 1024

# 默认客户端链接数,如果为0 则是不限制

######maxmemory 2048000000

# 使用内存大小,如果不设置为使用所有。单位为bytes

######maxmemory-policy volatile-lru

#内存用满的清理策略(lru为最近最少使用算法):

# volatile-lru:删除过期和lru key(默认值)

# allkeys-lru : 删除lru算法的key

# volatile-random:随机删除即将过期key

# allkeys->random:随机删除

# volatile-ttl : 删除即将过期的

# noeviction : 永不过期,返回错误

######maxmemory-samples 3

# 可以用ttl这只key的生存时间,此配置为用lru检查ttl时间。个人认为应该是对ttl的排序

appendonly no

# 开启操作记录日志,每此操作都会写日志,效率比较低。但是服务器宕机重启后,服务会加载日志,提高安全性。

#### appendfilename appendonly.aof

# 日志名称

appendfsync everysec

# 写日志的规则 always 时时写,everysec美秒写一次,no为不写

no-appendfsync-on-rewrite no

#没有太懂,个人理解是因为I/O效率问题,所以使用的一种类似的增量写入的方式。

slowlog-log-slower-than 10000

slowlog-max-len 1024

#像系统日志一样,记录命令的执行时间。记录周期为毫秒级(1000000毫秒=1秒)负值表示禁用,0表示记录所有命令。记录能保存的最大行数。

vm-enabled no

#虚拟内存开关

vm-swap-file /tmp/redis.swap

# 虚拟内存swap文件的位置。不同的redis服务不能共用内存文件。不推荐使用tmp目录。

vm-max-memory 0

#虚拟内存的大小,0为不限制。

vm-page-size 32

#缓存中每页的大小,默认是32个字节

vm-pages 134217728

# 虚拟内存中可以最大的页数,虚拟文件大小为vm-page-size * vm-pages。如果是32字节的页,用134217728页,会有4G大的swap文件

vm-max-threads 4

#使用虚拟内存的最大线程数

hash-max-zipmap-entries 512

hash-max-zipmap-value 64

list-max-ziplist-entries 512

list-max-ziplist-value 64

set-max-intset-entries 512

activerehashing yes

#为一种高级的哈希算法。原理没有明白,也不做修改了。

#以下为可以引入其它位置的配置文件。

# include /path/to/local.conf

# include /path/to/other.conf

三、基本管理

  Redis的命令共分为十个部分,其中主要的六个部分(KeyStringHashListSetSortedSet)的翻译可以到http://redis.readthedocs.org/en/latest/中查看。本问只是记录部分管理命令。

1Select

切换库,select后直接跟阿拉伯数字的dbid

举例:

redis 127.0.0.1:6379> select 1


OK

2Dbsize

统计库中key的数量

举例:

redis 127.0.0.1:6379> dbsize

(integer) 1

3Flushdb

Redis还支持对某个DB数据进行清除(当然清空所有数据的操作也是支持的)

redis 127.0.0.1:6379> dbsize

(integer) 1

redis 127.0.0.1:6379> flushdb

OK

redis 127.0.0.1:6379> dbsize

(integer) 0

4slaveof

同步命令,在从端参输入主机的IP和端口,进行数据同步。在复制的开始阶段处于阻塞状态(sync_readline)服务无法对外提供服务。

5Slowlog

获得slowlog日志中最近的2条记录

redis 127.0.0.1:6379> slowlog get 2

1) 1) (integer) 6

2) (integer) 1318257654

3) (integer) 19244

4) 1) “rpush”

2) “b”

3) “z”

2) 1) (integer) 5

2) (integer) 1318256413

3) (integer) 42203

4) 1) “keys”

2) “10*”

6Save Bgsave

将所有数据遍历一遍,然后存到一个扩展名为rdb的数据文件中。Bgsave为后台运行保存

redis 127.0.0.1:6379> SAVE

OK

7CONFIG RESETSTAT

充值redis服务器的统计信息,将被重置的内容如下:

Keyspace hits

Keyspace misses

Number of commands processed

Number of connections received

Number of expired keys

8Info

查看服务当前状态和版本信息。主要关心的空间使用信息used_memory_human使用内存量,vm使用率和swap使用。

举例:

redis 127.0.0.1:6379[1]> info

redis_version:2.2.12

redis_git_sha1:00000000

redis_git_dirty:0

arch_bits:64

multiplexing_api:epoll

process_id:27525

uptime_in_seconds:3085418

uptime_in_days:35

lru_clock:1807857

used_cpu_sys:79.22

used_cpu_user:186.33

used_cpu_sys_children:8.48

used_cpu_user_children:1.53

connected_clients:1

connected_slaves:0

client_longest_output_list:0

client_biggest_input_buf:0

blocked_clients:0

used_memory:83717864

used_memory_human:79.84M

used_memory_rss:127311872

mem_fragmentation_ratio:1.52

use_tcmalloc:0

loading:0

aof_enabled:0

changes_since_last_save:0

bgsave_in_progress:0

last_save_time:1318258998

bgrewriteaof_in_progress:0

total_connections_received:132983

total_commands_processed:5728570

expired_keys:0

evicted_keys:0

keyspace_hits:3588043

keyspace_misses:2140445

hash_max_zipmap_entries:512

hash_max_zipmap_value:64

pubsub_channels:0

pubsub_patterns:0

vm_enabled:0

role:master

db0:keys=664042,expires=0

db1:keys=1,expires=0

9月 28

pyinotify监控文件和文件夹变化

【2011-9-28 张子萌】

之前写了脚本,死循环调用inotifywait监控文件夹,如果文件有变动,则启动

rsync进行同步。但是当前需求有点变化,文件要按照日期建文件夹进行存储,

且文件变化很快,如果直接监控最顶级目录系统资源将消耗很大,所以考虑还是自

写一下好,如果系统资源量变化大,且不用时时同步时可以根据文件变动对变动

对文件进行记录,可以按照优先规则进行同步。

官方网站 : http://trac.dbzteam.org/pyinotify

系统要求:Linux kernel with inotify 2.6.13

Python 2.4

直接使用easy_install安装非常简单

# sudo easy_install pyinotify

如果不能联网,则需要直接下载压缩包,进行编译安装。

首先测试下是否可用:

使用以下命令监控/tmp文件夹,

# python -m pyinotify /tmp

/tmp文件夹下新建1.txt,并随后进行删除。看到显示的记录如下:

效果不错,继续向下进行。只要有创建、删除和关闭写就打印出变化的文件或目录,代码如下:

import re

import pyinotify

wm = pyinotify.WatchManager()

mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE | pyinotify.IN_CLOSE_WRITE

class EventHandler(pyinotify.ProcessEvent):

def process_IN_CREATE(self, event):

self.rebuild(event)

def process_IN_DELETE(self, event):

self.rebuild(event)

def process_IN_CLOSE_WRITE(self, event):

self.rebuild(event)

def rebuild(self, event):

chang_name=re.compile(“.+.swp$|.+.swx$|.+.swpx$”)

if not chang_name.match(event.pathname):

print event.pathname

handler = EventHandler()

notifier = pyinotify.Notifier(wm, handler)

wdd = wm.add_watch(‘/tmp’, mask, rec=True,auto_add=True )

notifier.loop()

代码里使用正则表达式过滤因为使用vim打开文件产生的缓存文件。也可以用exclude_filter方法

在官方文档中例子如下,但是我测试多次没有成功,所以直接用正则过滤。

# Exclude patterns from list

excl_lst = [‘^/etc/apache[2]?/’,

‘^/etc/rc.*’,

‘^/etc/hostname’,

&nb
sp;
‘^/etc/hosts’,

‘^/etc/(fs|m)tab’,

‘^/etc/cron..*’]

excl = pyinotify.ExcludeFilter(excl_lst)

# Add watches

res = wm.add_watch([‘/etc/hostname’, ‘/etc/cups’, ‘/etc/rc0.d’],

pyinotify.ALL_EVENTS, rec=True, exclude_filter=excl)

如果监控文件太多,需要对系统做一下修改sysctl -n -w fs.inotify.max_user_watches=16384