|
十 20
|
在某大东北吃饭完毕,开了张机打发票,刮出50元,谨记于此。
|
|
在某大东北吃饭完毕,开了张机打发票,刮出50元,谨记于此。
0400开头的电话是一种网络电话,是使用网络电话拨号时电信局端虚拟的号码,并不是某些人所说的更改拨打人的发送号码。这种电话一旦回拨则是空号,最好不要接听,因为大多是推销保险之类的,耽误时间,还恶心。今天我的手机显示04008808363这个号码打来电话,静音后被我扔在了一旁…
新浪微博使用Redis,究竟它有什么好处呢?今天第一次尝试一下。写一个“关注”的功能的雏形,“我”的ID为1,fun1是我的粉丝集合,follow1则使所有follow我的用户集合 sInter是求交集的方法,自然而然就获得了所有与我“互粉”的用户 <?php var_dump($r); 输出: array(2) {
去年7月份,买了一个一美元一个月的空间,空间提供商的名字就叫1dollar-webhosting。从美国其他主机访问速度还行,但从国内访问的速度巨慢无比。好在我这博客日常访问量也不大,慢点就慢点无所谓。 前些天又买了一个VPS,http://123systems.net/,买的是10刀每年的,太便宜了!!!但是配置很差,只有128MB内存,买完了想起来装apache+php+mysql得多吃力啊。头一开始刚装了个mysql就80多M内存没了。后来用网上找到的办法,用nginx+php-cgi+mysql最小化配置,都跑起来还有80MB free。至于国内访问速度,完全无法恭维了,还不如那个1dollor-webhosting。登录上去wget另一个美国的服务器上的文件,速度有8M/s,感觉在美国国内访问速度应该还不错。 但总之一点,便宜没好货,下次还是别VPS了,为了一个SSH帐号,弄得内存吃紧,不爽啊不爽。搞一个共享主机就得了。
1.跳槽 跳槽,从新浪到360,应该是人生的起点吧,这半年来,对职业前途思考增加了许多,当然也是各有优劣的。其实以后我也不一定要终身IT为业,但是现在在360学习到的做事方法,应该是终身有用的。 2.迁徙 每次迁徙,自然是从找房子开始,有和各种房东打交道,有和各种黑中介打交道。最后忽然进入现在这间屋的时候,眼前一亮,当即就决定了。小胖开车两趟帮我从燕北园搬到百子湾,累计快够到天津的了。 3.3Q大战 我并不是主要战线,但也能够主动向朋友解释整个过程,相对来说,我感觉我的立场还是比较客观的,能够得到朋友们的认同。很多我不认识的同事,在那段时间牺牲了休息时间。我不知道腾讯向员工提出怎样的要求,但是至少到目前,在腾讯的朋友都不肯理我,不知道为什么。校内上的一个好友就是QQ好友管家团队的,在战斗中也精疲力竭。我想,大家在工作上是各为其主,影响到私人关系就不好了嘛。 4.相亲 感情的事儿,年年提,年年无疾而终。我也不太相信相亲这个事儿了。如果相亲的两个人没有互相产生好感,浅尝辄止或许是最好的结局。今年正式相亲一次,参加相亲大会一次,基本相当于无疾而终。 5.旅游 很高兴自己能做出突破,只身离开京津这两个城市,飞去深圳旅游一圈。感谢小鱼的各种接待和陪同。之前我可是从来没有自己离开过京津。深港四日游之后,便深深的爱上了旅游。恐怕剩下不给力的就是什么时候才能有个合适的假期了。 6.脊椎 年初脊椎病得很严重,在Aurora的指点下,去北京按摩医院进行治疗,效果很好。 7.洗牙 经过几次曲折,终于去洗了牙。因为洗牙,被大夫要求补牙。大夫又指出有一颗牙因为歪了,没法补,可能因为两边有智齿。拍X光片才发现,有三颗智齿未长出来。还没有下决心去拔掉它们。 8.网购 虽然也不是刚开始网购,但是今年网购的东西比往年多,淘宝京东新蛋当当亚马逊等等,很多时候比实体店便宜,甚至巧克力比超市都便宜。itouch也是淘宝网购的水货。 9.ipod touch 4 虽然我不是果粉,但是很赞同苹果卖的是工业设计,确实做工很棒。我也是在iphone4和itouch4之间犹豫很久,在知道自己无法以无预存形式获得ip4时,第二天就决定了去下单买了it4。的确是改变生活的一个产品,至少能小小的改变一些。 10.to be continued 许多需要继续的,希望明年总结时,我可以补充这一段,让它完美。
PHP的CURL组件是非常常用的HTTP请求模拟器。 通常要发送post数据时,我已经习惯于这样写: 尝试发送到一个仅有<?php print_r($_SERVER);?>的网页上,可以看到使用数组发送POST数据时,收到的CONTENT_TYPE如下: 可见,当CURLOPT_POSTFIELDS被设置为数组时,HTTP头会发送Content_type: application/x-www-form-urlencoded。这个是正常的网页<form>提交表单时,浏览器发送的头部。而multipart/form-data我们知道这是用于上传文件的表单。包括了boundary分界符,会多出很多字节。 手册上提到:
使用数组提供post数据时,CURL组件大概是为了兼容@filename这种上传文件的写法,默认把content_type设为了multipart/form-data。虽然对于大多数web服务器并没有影响,但是还是有少部分服务器不兼容。 本文得出的结论是,在没有需要上传文件的情况下,尽量对post提交的数据进行http_build_query,然后发送出去,能实现更好的兼容性,更小的请求数据包。
用FD的时候解出过天津05年的动感地带,07年的神州行,08、09年的北京联通各一张,都在8小时内完成。唯独这张卡太难解了,FD1.5全码扫描,然后强解8个攻击组都无效,累计耗时超过40小时。上次解码大概还是一年前了,最近几周又来了兴趣,打算是算不出来就去营业厅补一张,上网一搜,2010年补的卡全成了自爆卡,只能死马当活马医了。重新用FD全码扫描+8个攻击组,SimonScan也尝试过全部扫描,未果。 在放弃之前找到了SimMaster这个软件,几个小时后寻得第7组KI。填入FD1.5 下推KI,约半个小时,就把所有KI计算出来了。写卡后提心吊胆的开了机,选取门号,顺利注册,至此,破解工作完成。 在网上搜到的一些资料是SimMaster虽然是免费的,但是下推全部KI的资料没有打开。只能找出两组来,不过还好有FD。现在看来,工欲善其事,必先利其器,找到个优秀的解码软件很重要,但是也不能过度依赖某一个软件。还有一点,卡易解与难解是个统计事件,我遇到有的卡运气好,十几分钟就全解开了。在网上看,普遍反映大唐卡比较难解,我这张北京动感地带果然是大唐的。
1、sys_getloadavg() 这个函数返回当前系统的负载均值信息(当然 Windows 下不适用),详细文档可以翻阅 PHP 的相关文档。文档中有段示例代码,基本上也就能看出它的用途了。 <?php
$load = sys_getloadavg();
if ($load[0] > 80) {
header('HTTP/1.1 503 Too busy, try again later');
die('Server too busy. Please try again later.');
}
PS,如果“很不幸”得你的 PHP 环境中没有这个函数,可以考虑使用下面这段代码 via if (!function_exists('sys_getloadavg')) {
function sys_getloadavg()
{
$loadavg_file = '/proc/loadavg';
if (file_exists($loadavg_file)) {
return explode(chr(32),file_get_contents($loadavg_file));
}
return array(0,0,0);
}
}
这一特性如果使用得当,能减轻服务器部分压力。 2、pack() pack 对应的还有个函数为 unpack,用于压缩二进制串,文中的作者的示例非常清楚 $pass_hash = pack("H*", md5("my-password"));
如果你使用 PHP5,那么可以直接这样子 $pass_hash = md5("my-password", true); // PHP 5+
这样做的好处之一是能减少串存储空间(能节省多少呢?可能又会是另篇文章了)。 这里还有个示例代码可以 pack 数组 via <?php
function pack_array($v,$a) {
return call_user_func_array(pack,array_merge(array($v),(array)$a));
}
3、cal_days_in_month() 该函数可以直接返回指定月份中的天数,例如 $days = cal_days_in_month(CAL_GREGORIAN, date("m"), date("Y")); // 31
我敢保证,你自己实现过类似功能的函数 :^) 4、_() 呃,这的确也是个 PHP 函数(也有可能是最短的 PHP 内置函数)。_() 是它的“小名”,它的大名是 gettext()。 写过 WordPress 皮肤的朋友会了解 __() 以及 _e() 这些函数,其实 PHP 早已经自带了相关的功能。 // Set language to German
setlocale(LC_ALL, 'de_DE');
// Specify location of translation tables
bindtextdomain("myPHPApp", "./locale");
// Choose domain
textdomain("myPHPApp");
echo _("Have a nice day");
利用 gettext 可以编写多语言的应用,现在您感兴趣的可能就是如何编写 locale 文件,这但已经不是此文涉及的重点,更多信息可以移步到这里。 5、get_browser() 坦白讲,见到这个函数我当时就彻底泪奔。有了这个函数,再也不用自己去分析 $_SERVER['HTTP_USER_AGENT'] 这个字符串了。 更多的信息可以参考这里。在使用此函数前,你可能需要个 browscap.ini 配置文件,相信你可以搞定的。 6、debug_print_backtrace() 以前查看函数调用堆栈,我会使用 xdebug 等的扩展,其实 PHP5 版本以后已经内置了相关的函数。 顺便再分享个“蛋疼”的小技巧,如果你记不住这个函数的名字,可以用这段代码同样能达到目的(看起来还是记住那个函数靠谱): <?php
$e = new Exception();
print_r(str_replace('/path/to/code/', '', $e->getTraceAsString()));
7、natsort() 这个函数用于自然排序,这个大家可能都要用到。贴下相关的文档链接以及示例代码 $items = array("100 apples", "5 apples", "110 apples", "55 apples");
// normal sorting:
sort($items);
print_r($items);
# Outputs:
# Array
# (
# [0] => 100 apples
# [1] => 110 apples
# [2] => 5 apples
# [3] => 55 apples
# )
natsort($items);
print_r($items);
# Outputs:
# Array
# (
# [2] => 5 apples
# [3] => 55 apples
# [0] => 100 apples
# [1] => 110 apples
# )
有关自然排序的算法规则,可以参考这里的文档。 8、glob() 这个函数的功能同样让人感到泪奔,先不说功能直接上示例代码 foreach (glob("*.php") as $file) {
echo "$file\n";
}
相比你已经了解该函数的用途了,那么我们就可以有更多的“玩法”,例如就显示目录(via): $dirs = array_filter(glob($path.'*'), 'is_dir'); 当然,文件递归你也可以考虑使用下 SPL 扩展。 9、PHP Filter 如果你还在正则验证字符串,那么就真的“Out”了。自 PHP5.2 版本以后,内置了 PHP Fliter 模块用于专门验证 电子邮件、URL 等是否合法,示例代码: var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL));
由于是新生的模块,因此还有很多的陷阱,例如 filter_var('abc', FILTER_VALIDATE_BOOLEAN); // bool(false)
filter_var('0', FILTER_VALIDATE_BOOLEAN); // bool(false)
但这不影响我们去尝试。有关 PHP Filter 的更多信息,相信能拎出来另外写篇文章了。 -- Split -- 最后,感叹 PHP 其实是个历久弥新的工具,不小心我们就会悲剧性得重复造了只轮子。因此,时常看看 PHP 文档每次都会有新的收获。
1. php函数的任意数目的参数 你可能知道PHP允许你定义一个默认参数的函数。但你可能并不知道PHP还允许你定义一个完全任意的参数的函数 下面是一个示例向你展示了默认参数的函数: // 两个默认参数的函数 // 两个默认参数的函数 function foo($arg1 = ”, $arg2 = ”) { echo “arg1: $arg1\n”; echo “arg2: $arg2\n”; } foo(‘hello’,'world’); /* 输出: arg1: hello arg2: world */ foo(); /* 输出: arg1: arg2: */ 现在我们来看一看一个不定参数的函数,其使用到了?func_get_args()方法: // 是的,形参列表为空 function foo() { // 取得所有的传入参数的数组 $args = func_get_args(); foreach ($args as $k => $v) { echo “arg”.($k+1).”: $v\n”; } } foo(); /* 什么也不会输出 */ foo(‘hello’); /* 输出 arg1: hello */ foo(‘hello’, ‘world’, ‘again’); /* 输出 arg1: hello arg2: world arg3: again */ 2. php中使用 Glob() 查找文件 很多PHP的函数都有一个比较长的自解释的函数名,但是,当你看到?glob() 的时候,你可能并不知道这个函数是用来干什么的,除非你对它已经很熟悉了。 你可以认为这个函数就好?scandir() 一样,其可以用来查找文件。 // 取得所有的后缀为PHP的文件 $files = glob(‘*.php’); print_r($files); /* 输出: Array ( [0] => phptest.php [1] => pi.php [2] => post_output.php [3] => test.php ) */ 你还可以查找多种后缀名 // 取PHP文件和TXT文件 $files = glob(‘*.{php,txt}’, GLOB_BRACE); print_r($files); /* 输出: Array ( [0] => phptest.php [1] => pi.php [2] => post_output.php [3] => test.php [4] => log.txt [5] => test.txt ) */ 你还可以加上路径: $files = glob(‘../images/a*.jpg’); print_r($files); /* 输出: Array ( [0] => ../images/apple.jpg [1] => ../images/art.jpg ) */ 如果你想得到绝对路径,你可以调用?realpath() 函数: $files = glob(‘../images/a*.jpg’); // applies the function to each array element $files = array_map(‘realpath’,$files); print_r($files); /* output looks like: Array ( [0] => C:\wamp\www\images\apple.jpg [1] => C:\wamp\www\images\art.jpg ) */ 3. php查看内存使用信息 观察你程序的内存使用能够让你更好的优化你的代码。 PHP 是有垃圾回收机制的,而且有一套很复杂的内存管理机制。你可以知道你的脚本所使用的内存情况。要知道当前内存使用情况,你可以使 用?memory_get_usage() 函数,如果你想知道使用内存的峰值,你可以调用memory_get_peak_usage() 函数。 echo “Initial: “.memory_get_usage().” bytes \n”; /* 输出Initial: 361400 bytes*/ // 使用内存 for ($i = 0; $i < 100000; $i++) { $array []= md5($i); } // 删除一半的内存 for ($i = 0; $i < 100000; $i++) { unset($array[$i]); } echo “Final: “.memory_get_usage().” bytes \n”; /* printsFinal: 885912 bytes*/ echo “Peak: “.memory_get_peak_usage().” bytes \n”; /* 输出峰值Peak: 13687072 bytes*/ 4. php查看CPU使用信息 使用?getrusage() 函数可以让你知道CPU的使用情况。注意,这个功能在Windows下不可用。 echo “Initial: “.memory_get_usage().” bytes \n”; /* 输出 Initial: 361400 bytes */ // 使用内存 for ($i = 0; $i < 100000; $i++) { $array []= md5($i); } // 删除一半的内存 for ($i = 0; $i < 100000; $i++) { unset($array[$i]); } echo “Final: “.memory_get_usage().” bytes \n”; /* prints Final: 885912 bytes */ echo “Peak: “.memory_get_peak_usage().” bytes \n”; /* 输出峰值 Peak: 13687072 bytes */ 这个结构看上出很晦涩,除非你对CPU很了解。下面一些解释: ru_oublock: 块输出操作 ru_inblock: 块输入操作 ru_msgsnd: 发送的message ru_msgrcv: 收到的message ru_maxrss: 最大驻留集大小 ru_ixrss: 全部共享内存大小 ru_idrss:全部非共享内存大小 ru_minflt: 页回收 ru_majflt: 页失效 ru_nsignals: 收到的信号 ru_nvcsw: 主动上下文切换 ru_nivcsw: 被动上下文切换 ru_nswap: 交换区 ru_utime.tv_usec: 用户态时间 (microseconds) ru_utime.tv_sec: 用户态时间(seconds) ru_stime.tv_usec: 系统内核时间 (microseconds) ru_stime.tv_sec: 系统内核时间?(seconds) 要看到你的脚本消耗了多少CPU,我们需要看看“用户态的时间”和“系统内核时间”的值。秒和微秒部分是分别提供的,您可以把微秒值除以100万,并把它添加到秒的值后,可以得到有小数部分的秒数。 // sleep for 3 seconds (non-busy) sleep(3); $data = getrusage(); echo “User time: “. ($data['ru_utime.tv_sec'] + $data['ru_utime.tv_usec'] / 1000000); echo “System time: “. ($data['ru_stime.tv_sec'] + $data['ru_stime.tv_usec'] / 1000000); /* 输出 User time: 0.011552 System time: 0 */ sleep是不占用系统时间的,我们可以来看下面的一个例子: // loop 10 million times (busy) for($i=0;$i<10000000;$i++) { } $data = getrusage(); echo “User time: “. ($data['ru_utime.tv_sec'] + $data['ru_utime.tv_usec'] / 1000000); echo “System time: “. ($data['ru_stime.tv_sec'] + $data['ru_stime.tv_usec'] / 1000000); /* 输出 User time: 1.424592 System time: 0.004204 */ 这花了大约14秒的CPU时间,几乎所有的都是用户的时间,因为没有系统调用。 系统时间是CPU花费在系统调用上的上执行内核指令的时间。下面是一个例子: $start = microtime(true); // keep calling microtime for about 3 seconds while(microtime(true) – $start < 3) { } $data = getrusage(); echo “User time: “. ($data['ru_utime.tv_sec'] + $data['ru_utime.tv_usec'] / 1000000); echo “System time: “. ($data['ru_stime.tv_sec'] + $data['ru_stime.tv_usec'] / 1000000); /* prints User time: 1.088171 System time: 1.675315 */ 我们可以看到上面这个例子更耗CPU。 5. php中的系统常量 PHP 提供非常有用的系统常量 可以让你得到当前的行号 (__LINE__),文件 (__FILE__),目录 (__DIR__),函数名 (__FUNCTION__),类名(__CLASS__),方法名(__METHOD__) 和名字空间 (__NAMESPACE__),很像C语言。 我们可以以为这些东西主要是用于调试,当也不一定,比如我们可以在include其它文件的时候使用?__FILE__ (当然,你也可以在 PHP 5.3以后使用 __DIR__ ),下面是一个例子。 // this is relative to the loaded script’s path // it may cause problems when running scripts from different directories require_once(‘config/database.php’); // this is always relative to this file’s path // no matter where it was included from require_once(dirname(__FILE__) . ‘/config/database.php’); 下面是使用 __LINE__ 来输出一些debug的信息,这样有助于你调试程序: // some code // … my_debug(“some debug message”, __LINE__); /* 输出 Line 4: some debug message */ // some more code // … my_debug(“another debug message”, __LINE__); /* 输出 Line 11: another debug message */ function my_debug($msg, $line) { echo “Line $line: $msg\n”; } 6.php生成唯一的ID 有很多人使用 md5() 来生成一个唯一的ID,如下所示: // generate unique string echo md5(time() . mt_rand(1,1000000)); 其实,PHP中有一个叫?uniqid() 的函数是专门用来干这个的: // generate unique string echo uniqid(); /* 输出 4bd67c947233e */ // generate another unique string echo uniqid(); /* 输出 4bd67c9472340 */ 可能你会注意到生成出来的ID前几位是一样的,这是因为生成器依赖于系统的时间,这其实是一个非常不错的功能,因为你是很容易为你的这些ID排序的。这点MD5是做不到的。 你还可以加上前缀避免重名: // 前缀 echo uniqid(‘foo_’); /* 输出 foo_4bd67d6cd8b8f */ // 有更多的熵 echo uniqid(”,true); /* 输出 4bd67d6cd8b926.12135106 */ // 都有 echo uniqid(‘bar_’,true); /* 输出 bar_4bd67da367b650.43684647 */ 而且,生成出来的ID会比MD5生成的要短,这会让你节省很多空间。 7. php对数据进行序列化 你是否会把一个比较复杂的数据结构存到数据库或是文件中?你并不需要自己去写自己的算法。PHP早已为你做好了,其提供了两个函数:?serialize() 和 unserialize(): // 一个复杂的数组 $myvar = array( ‘hello’, 42, array(1,’two’), ‘apple’ ); // 序列化 $string = serialize($myvar); echo $string; /* 输出 a:4:{i:0;s:5:”hello”;i:1;i:42;i:2;a:2:{i:0;i:1;i:1;s:3:”two”;}i:3;s:5:”apple”;} */ // 反序例化 $newvar = unserialize($string); print_r($newvar); /* 输出 Array ( [0] => hello [1] => 42 [2] => Array ( [0] => 1 [1] => two ) [3] => apple ) */ 这是PHP的原生函数,然而在今天JSON越来越流行,所以在PHP5.2以后,PHP开始支持JSON,你可以使用 json_encode() 和 json_decode() 函数 // a complex array $myvar = array( ‘hello’, 42, array(1,’two’), ‘apple’ ); // convert to a string $string = json_encode($myvar); echo $string; /* prints ["hello",42,[1,"two"],”apple”] */ // you can reproduce the original variable $newvar = json_decode($string); print_r($newvar); /* prints Array ( [0] => hello [1] => 42 [2] => Array ( [0] => 1 [1] => two ) [3] => apple ) */ 这看起来更为紧凑一些了,而且还兼容于Javascript和其它语言。但是对于一些非常复杂的数据结构,可能会造成数据丢失。 8. php对字符串进行压缩 当我们说到压缩,我们可能会想到文件压缩,其实,字符串也是可以压缩的。PHP提供了?gzcompress() 和gzuncompress() 函数: $string = “Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ut elit id mi ultricies adipiscing. Nulla facilisi. Praesent pulvinar, sapien vel feugiat vestibulum, nulla dui pretium orci, non ultricies elit lacus quis ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam pretium ullamcorper urna quis iaculis. Etiam ac massa sed turpis tempor luctus. Curabitur sed nibh eu elit mollis congue. Praesent ipsum diam, consectetur vitae ornare a, aliquam a nunc. In id magna pellentesque tellus posuere adipiscing. Sed non mi metus, at lacinia augue. Sed magna nisi, ornare in mollis in, mollis sed nunc. Etiam at justo in leo congue mollis. Nullam in neque eget metus hendrerit scelerisque eu non enim. Ut malesuada lacus eu nulla bibendum id euismod urna sodales. “; $compressed = gzcompress($string); echo “Original size: “. strlen($string).”\n”; /* 输出原始大小 Original size: 800 */ echo “Compressed size: “. strlen($compressed).”\n”; /* 输出压缩后的大小 Compressed size: 418 */ // 解压缩 $original = gzuncompress($compressed); 几乎有50% 压缩比率。同时,你还可以使用?gzencode() 和 gzdecode() 函数来压缩,只不用其用了不同的压缩算法。 9. php注册停止函数 有一个函数叫做?register_shutdown_function(),可以让你在整个脚本停时前运行代码。让我们看下面的一个示例: // capture the start time $start_time = microtime(true); // do some stuff // … // display how long the script took echo “execution took: “. (microtime(true) – $start_time). ” seconds.”; 上面这个示例只不过是用来计算某个函数运行的时间。然后,如果你在函数中间调用?exit() 函数,那么你的最后的代码将不会被运行到。并且,如果该脚本在浏览器终止(用户按停止按钮),其也无法被运行。 而当我们使用了register_shutdown_function()后,你的程序就算是在脚本被停止后也会被运行: $start_time = microtime(true); register_shutdown_function(‘my_shutdown’); // do some stuff // … function my_shutdown() { global $start_time; echo “execution took: “. (microtime(true) – $start_time). ” seconds.”; }
一篇老文章了,对其他语言来说也一样… 你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚。但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起 。 —– Arthur J.Riel (1)所有数据都应该隐藏在所在的类的内部。 (2)类的使用者必须依赖类的共有接口,但类不能依赖它的使用者。 (3)尽量减少类的协议中的消息。 (4)实现所有类都理解的最基本公有接口[例如,拷贝操作(深拷贝和浅拷贝)、相等性判断、正确输出内容、从ASCII描述解析等等]。 (5)不要把实现细节(例如放置共用代码的私有函数)放到类的公有接口中。 如果类的两个方法有一段公共代码,那么就可以创建一个防止这些公共代码的私有函数。 (6)不要以用户无法使用或不感兴趣的东西扰乱类的公有接口。 (7)类之间应该零耦合,或者只有导出耦合关系。也即,一个类要么同另一个类毫无关系,要么只使用另一个类的公有接口中的操作。 (8)类应该只表示一个关键抽象。 包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包影响,则将对包中的所有类产生影响,而对其他的包不造成任何影响。 (9)把相关的数据和行为集中放置。 设计者应当留意那些通过get之类操作从别的对象中获取数据的对象。这种类型的行为暗示着这条经验原则被违反了。 (10)把不相关的信息放在另一个类中(也即:互不沟通的行为)。 朝着稳定的方向进行依赖. (11)确保你为之建模的抽象概念是类,而不只是对象扮演的角色。 (12)在水平方向上尽可能统一地分布系统功能,也即:按照设计,顶层类应当统一地共享工作。 (13)在你的系统中不要创建全能类/对象。对名字包含Driver、Manager、System、Susystem的类要特别多加小心。 规划一个接口而不是实现一个接口。 (14)对公共接口中定义了大量访问方法的类多加小心。大量访问方法意味着相关数据和行为没有集中存放。 (15)对包含太多互不沟通的行为的类多加小心。 这个问题的另一表现是在你的应用程序中的类的公有接口中创建了很多的get和set函数。 (16)在由同用户界面交互的面向对象模型构成的应用程序中,模型不应该依赖于界面,界面则应当依赖于模型。 (17)尽可能地按照现实世界建模(我们常常为了遵守系统功能分布原则、避免全能类原则以及集中放置相关数据和行为的原则而违背 这条原则) 。 (18)从你的设计中去除不需要的类。 一般来说,我们会把这个类降级成一个属性。 (19)去除系统外的类。 系统外的类的特点是,抽象地看它们只往系统领域发送消息但并不接受系统领域内其他类发出的消息。 (20)不要把操作变成类。质疑任何名字是动词或者派生自动词的类,特别是只有一个有意义行为的类。考虑一下那个有意义的行为是 否应当迁移到已经存在或者尚未发现的某个类中。 (21)我们在创建应用程序的分析模型时常常引入代理类。在设计阶段,我们常会发现很多代理没有用的,应当去除。 (22)尽量减少类的协作者的数量。 一个类用到的其他类的数目应当尽量少。 (23)尽量减少类和协作者之间传递的消息的数量。 (24)尽量减少类和协作者之间的协作量,也即:减少类和协作者之间传递的不同消息的数量。 (25)尽量减少类的扇出,也即:减少类定义的消息数和发送的消息数的乘积。 (26)如果类包含另一个类的对象,那么包含类应当给被包含的对象发送消息。也即:包含关系总是意味着使用关系。 (27)类中定义的大多数方法都应当在大多数时间里使用大多数数据成员。 (28)类包含的对象数目不应当超过开发者短期记忆的容量。这个数目常常是6。 当类包含多于6个数据成员时,可以把逻辑相关的数据成员划分为一组,然后用一个新的包含类去包含这一组成员。 (29)让系统功能在窄而深的继承体系中垂直分布。 (30)在实现语义约束时,最好根据类定义来实现。这常常会导致类泛滥成灾,在这种情况下,约束应当在类的行为中实现,通常是在构造函数中实现,但不是必须如此。 (31)在类的构造函数中实现语义约束时,把约束测试放在构造函数领域所允许的尽量深的包含层次中。 (32)约束所依赖的语义信息如果经常改变,那么最好放在一个集中式的第3方对象中。 (33)约束所依赖的语义信息如果很少改变,那么最好分布在约束所涉及的各个类中。 (34)类必须知道它包含什么,但是不能知道谁包含它。 (35)共享字面范围(也就是被同一个类所包含)的对象相互之间不应当有使用关系。 (36)继承只应被用来为特化层次结构建模。 (37)派生类必须知道基类,基类不应该知道关于它们的派生类的任何信息。 (38)基类中的所有数据都应当是私有的,不要使用保护数据。 类的设计者永远都不应该把类的使用者不需要的东西放在公有接口中。 (39)在理论上,继承层次体系应当深一点,越深越好。 (40)在实践中,继承层次体系的深度不应当超出一个普通人的短期记忆能力。一个广为接受的深度值是6。 (41)所有的抽象类都应当是基类。 (42)所有的基类都应当是抽象类。 (43)把数据、行为和/或接口的共性尽可能地放到继承层次体系的高端。 (44)如果两个或更多个类共享公共数据(但没有公共行为),那么应当把公共数据放在一个类中,每个共享这个数据的类都包含这个类。 (45)如果两个或更多个类有共同的数据和行为(就是方法),那么这些类的每一个都应当从一个表示了这些数据和方法的公共基类继承。 (46)如果两个或更多个类共享公共接口(指的是消息,而不是方法),那么只有他们需要被多态地使用时,他们才应当从一个公共基类继承。 (47)对对象类型的显示的分情况分析一般是错误的。在大多数这样的情况下,设计者应当使用多态。 (48)对属性值的显示的分情况分析常常是错误的。类应当解耦合成一个继承层次结构,每个属性值都被变换成一个派生类。 (49)不要通过继承关系来为类的动态语义建模。试图用静态语义关系来为动态语义建模会导致在运行时切换类型。 (50)不要把类的对象变成派生类。对任何只有一个实例的派生类都要多加小心。 (51)如果你觉得需要在运行时刻创建新的类,那么退后一步以认清你要创建的是对象。现在,把这些对象概括成一个类。 (52)在派生类中用空方法(也就是什么也不做的方法)来覆写基类中的方法应当是非法的。 (53)不要把可选包含同对继承的需要相混淆。把可选包含建模成继承会带来泛滥成灾的类。 (54)在创建继承层次时,试着创建可复用的框架,而不是可复用的组件。 (55)如果你在设计中使用了多重继承,先假设你犯了错误。如果没犯错误,你需要设法证明。 (56)只要在面向对象设计中用到了继承,问自己两个问题:(1)派生类是否是它继承的那个东西的一个特殊类型?(2)基类是不是派生类的一部分? (57)如果你在一个面向对象设计中发现了多重继承关系,确保没有哪个基类实际上是另一个基类的派生类。 (58)在面向对象设计中如果你需要在包含关系和关联关系间作出选择,请选择包含关系。 (59)不要把全局数据或全局函数用于类的对象的薄记工作。应当使用类变量或类方法。 (60)面向对象设计者不应当让物理设计准则来破坏他们的逻辑设计。但是,在对逻辑设计作出决策的过程中我们经常用到物理设计准则。 (61)不要绕开公共接口去修改对象的状态。
如果某脚本要跑30分钟, 可以在crontab里把脚本间隔设为至少一小时来避免冲突。而比较糟的情况可能该脚本在执行周期内没完成,接着第二个脚本又开始跑了。如何确保只有一个脚本实例运行?一个好用的方法是利用lockf(freebsd下为lockf,linux下为flock),在脚本执行前需要检测能否获取某个文件锁,防止脚本运行冲突。 lockf 的参数如下: * -k: 一直等待获取文件锁 for example: 以下脚本执行前,需获取临时文件create.lock 的文件锁 */10 * * * * ( lockf -s -t 0 /tmp/create.lock /usr/bin/python /home/project/cron/create_tab.py >> /home/project/logs/create.log 2>&1) 若第一个实例在10分钟内没有跑完,第2个实例不会运行。
这首歌前面录了好多人说的我没时间做这个没时间做那个。听了深有感触,我也是有很多想做的事情没有做,我想去旅游,我想学摄影,我想找媳妇,我想。。。。 至于为什么要来北京,现在想想,除了能多赚点钱,也没什么更多的理由,天津是个安逸的城市,小富即安那种,甚至当当吃海货不算不会过,有时候真想回去算了。可是人的冲劲,真是会被大学磨灭掉的,会舍不得现在的薪水,会舍不得这种旱涝保收的铁饭碗。。。 算了,不想那么多了,三十岁时,也许真该回家了。
主要是和nginx配置有关的
星期三晚上疑似在公司食堂吃坏肚子,回家拉稀。周四早晨头略疼,坚持上班半日,下午实在坚持不了,请假回家洗澡睡觉。一觉从三点睡到晚上八点多,起来下楼在一个小馆子要了一盘热腾腾的青椒土豆丝,吃得胃肠很舒服。断断续续睡到第二天早晨9点,累计睡了不少于15个小时。其间发烧,各种出汗。 星期五又请了一天假,早晨下楼吃了个油饼,喝了碗豆腐脑。中午吃了碗朝鲜冷面,比较败笔。。晚上要了一盘青椒肉丝,一块钱的米饭上了一大盆,吃得我大汗淋漓,好久没有吃这么爽了。 小灶虽然原材料可能不卫生,油也是地沟油,但是我觉着它唯一的好处是可以真正做熟,掌勺的大概也怕出吃坏肚子的事儿,也相信高温可以杀毒,而且小灶出来的卖相也会比食堂的大锅饭好很多。 毕业这些年,除了在家里的时候,基本都是吃小灶,就没再吃过任何食堂。现在猛然间恢复吃食堂,还真是有些不适应。
Memcache在我们的项目中经常会用到,最近为了做IDGEN,我进行了多次测试,得到一些与failover有关的结论。客户端都使用php的memcache对象,服务器就是memcached服务
一、客户端对Memcached服务器的检测
分两种情况
1.如果是服务器断网或死机,php的Memcache对象会等待超时,超时判断该服务器为失效,这个时间默认是1秒。由php.ini的memcache.default_timeout_ms决定,默认是1000ms
2.如果服务器仍然存活,只是返回错误或者类似Connection Refused这种低层的错误,则立即判断该服务器为失效
二、php.ini中failover的开启情况
1.memcache.allow_failover=1
这是默认值,假设addServer了多台服务器。当检测到有服务器失效后,则立即转移到其他服务器上进行读写(当然读是读不到了,但是其后都能读写都到了另一台服务器上)
转移的时候有几种算法,由php.ini中的memcache.hash_strategy决定 ,有标准、一致性哈希等等。一致性哈希是个比较好的算法,一台服务器挂掉以后,上面的key可以比较均匀地分散到其他memcache服务器上,不会突然全部转移到某台服务器上。
2.memcache.allow_failover=0
检测到服务器失效后,不进行转移,读不到就是读不到,写不进去就是写不进去
三、失效状态
由于没有进程间通信的机制,一个进程检测到某台Memcached服务器失效,不会通知其他进程。因此,假设一台Memcached服务器失效,则每个进程都需要检测一下。
我们注意到,addServer的第六个参数$retry_interval,它是用于再次检测服务器是否失效的时间间隔,-1则不再检测。它的默认时间是写在php的memcache扩展源代码中,15秒
在同一个进程中,如果第一次检测到memcached服务器挂掉,则15秒内不会再进行通信。15秒后,重新尝试请求一下,如果失败还会继续等待15秒。
通常,一台webserver会fork50个进程,每个进程都可以处理一个http请求,并在连接结束后继续处理另一个http请求,这时候,进程没有结束,15秒时间仍然有效,下一个http请求中的memcache就得知了某服务器已经失效这件事情,根本不会发送数据包给挂掉的memcached服务器,直到距离上次检测达到15秒的时间。我们很高兴看到这一点,至少不会每次执行php时都检测(检测超时是个很费时间的活儿)
因为工作变更,准备在以四惠桥为中心在附近找一处居所租住,陆续看了若干房子,写一点感受吧。 以看过的房子质量排序 百子湾那的易构空间应该是最好的,都是新楼,大大的落地窗,直接可以看到新公司,公交车两站地,走路过去上班都很轻松。看的几间房全都是精装修,除了贵没有缺点。大开间3000起,二室要4200起,很有家的感觉。合租也在2000上下,今天看了一个厅打的隔断,如果没打隔断我估计这个厅得有40多平米。这个隔断间大约28平米要1800,在这个地点应该是很便宜的,不过我觉得不能接受隔间,更重要的是女房东还要产子,我对和有小孩的家庭合租有阴影。 八通线双桥站,朝阳旺角。这个小区也是新楼,看了一个大开间,2000。缺点是离双桥地铁还有大约1km,房东建议骑车去双桥,存起来再坐八通线。这1km路边还在埋管道,民工很多,感觉治安也不会很好。三轮摩托业和黑出租很发达。这里离四惠桥有8km,我想如果加班到地铁停了之后,半夜在郊区骑车这么远可能差点儿。 还是双桥站,北岸1292。这个小区大概是刚入住,很多房间还在装修。商住两用,公寓式的,一个长长的走廊,17平米的一间租金1600,两天后降到1500,有一个卫生间和一间屋子,本来房东打算是在这里办公的,后来因为公司规模扩张,就打算卖掉或者出租,17㎡售价27万。缺点是水电是按照商用收费,比家用要贵很多。离地铁站也不是很近,要走10分钟。 电力公司的内部房子,在四惠桥东北,没看到一居室,两居室要3000,勉强算中等装修吧。一居室2800,在这个地段还是很贵。好处是也低头也可以看见新公司。 大望路地铁站西北口,一出来看到一个不知道什么小区,看上去应该是六七十年代的房子吧,没兴趣看,在一层沿街看到一个中介,问了一下,就是能用于出租的最差的一室也要2400,两室要3000以上,中介说你也知道这个地点,是吧,我smilence。到了西大望路路口往北走,八王坟北,又看见一个比较好一点的高层,估计是九十年代的,楼下有个中介,进去问了一下,比刚才那个破楼要贵500。 红领巾桥西北,有几个高层,一朋友住在里面。我等朋友的时候跟楼下遛弯的大爷搭讪,问了问情况,一居室1500可能能租到,1800应该比较容易租,大爷建议我在楼道口贴小广告,说很多房子都闲置,空着,从来不亮灯。房屋情况一般,也是勉强算中等装修吧。 方家村没有去看,都是自建房,号称25平米1200元,精装修。咱不敢住。 我就是希望绕开中介,自己直接和房东联系,宁愿把中介费那么多钱给房东,还讨个好呢是不是。最近干的比较多的就是在赶集网上刷刷刷页面。58同城基本已经被中介占领了。之前买的个3G无线上网卡派上用场了,在任何地方都可以上网太方便了,公车上,马路边,各种小区里。。。 说了这么多,希望能够找到一个称心如意的房子吧。其实没打算真花3000去租一个月,2000应该是我能接受的上限了。一居室的话在红领巾桥那个附近还可以,百子湾可以租到三居中的一间,四惠桥西北电力那个小区可以租到二居中的主卧。 我觉得人的极限是一天在三个小区看。上次在中关村周围找也是,一天去三个小区看房人就已经疲惫不堪了,精神上和体力上都很累,回家洗完澡就想躺着,什么也不想干,所有的衣服已经全扔给洗衣机了。每天在地铁里穿过大半个城市,在西北四环到东四环之间来回,我想等正式过去上班时候必然受不了这样的往返。 为了直接和房东打交道,累点儿是必须的。不通过中介直接找到的房东都很nice,因为中介费都向承租人收取,中介就抓住很多房东怕麻烦的心理,拿到这些房源。这些不怕烦的房东都是非常好的人,他们的电话也不断地在被中介骚扰。我继续支持他们并在鄙视中介的道路上前进!
早晨八点一刻醒来,发现下雨。有精神动力支撑着迅速地爬起了床。 颈椎牵引加到11公斤,中频继续用比较大的功率。 今天大夫比较忙,手头病人挺多。周日是算加班,跟他聊了聊,工资水平比我还略高,一二月的淡季大概是高峰的2/3。 腰部和颈部感觉越来越好,坚持做完这几次再说吧。
一晃两星期没有去了。今天再去,颈椎牵引选择还是10公斤的力度,中频跟上次的量差不多。先接受实习生按摩,感觉他的手法轻了很多,后来听主治大夫跟他说要注意力量,以前有人反应力度太大。我感觉他的力度确实轻了。最后主治大夫按摩之后,我感觉不像上次那么疼,说是确有好转。 另得知一消息,腰部按摩和颈部按摩涨价了,由原来的25元/次*部位变成45元/次*部位,Aurora赶在涨价前又买了10次的,我就没这么幸运了,不过幸好公司报销90%,自己承担这10%还是可以承担得起的。
3月27日 星期六 晴 这是第五次去了,先由实习大夫为我按摩。实习生毕竟不如有工作经验的,不过也还可以。他说以相同的力度,上次我疼的哇哇叫,这次没什么事儿了。经大夫检验确实是这样的,这说明已经好了很多了。最后做了一个动作,看起来是要达到把颈椎间拉开的动作。我中午11点左右到的,按摩结束已经12点了。于是就在西四北大街转悠转悠,直到一点半回去做理疗。 中频电疗又增加了强度。颈椎牵引增加到10公斤,结束后略微感觉头晕,不知是因为吃了东西血液在胃部比较多还是整个人就犯困,下午一直晕乎乎的,坐车回家路上都快睡着了。 来此地的年轻人们啊,男的多数是IT行业,女的多数是四大行业,可有意思了。第一,看这种病,周末,如果不单身的话,肯定不会自己去;第二,这是个专科医院,大部分都是工作强度高而患有颈椎病腰椎病,也算有一点点共同话题;第三,舍得花钱来看的,工作也不会太差;第四,春天来了。。。
3月24日 星期三 晴 下午风风火火地跑去看大夫,因为去的有点晚了,快3点才到,按摩的人排队很多。我先去做了理疗,颈椎牵引已经加到了9公斤,并没有任何不适的感觉。中频电疗也略微增加了强度,做完之后麻麻的非常舒服。按摩时有很久的队要排,最后回到公司都6点了。 我还有问题是可能因为姿势不正确吧,肩部的肌肉处于一种非常紧张的状态,大夫指出需要好好热敷处理一下。另外有轻度腰肌劳损,这个没有办法了。 |
|
近期评论