小子 发布的文章

实时网站在线人数显示

javascript部分

使用的ajax长轮询 ajax long poll,为了便于使用,我将它封装成了一个jquery插件

(function($){
	$.fn.extend({
		visitors: function(options){
			var defaults = {
				script : "visitors/online.php",
				timeout : 50000,
			};
			var options = $.extend(defaults, options);
			return this.each(function(){
				var holder = $(this);
				refresh = function(sleep) {
					var sleep = sleep ? sleep : 1000;
					setTimeout('update()', sleep);
				}
				update = function() {
					$.ajax({
						url : options.script,
						type : 'get',
						dataType : 'json',
						async : true,
						cache : false,
						timeout : options.timeout,
						beforeSend : function() {
						},
						success : function(data) {
							holder.html(data.num);
							refresh(1000);
						},
						error : function() {
							refresh(15000);
						}
					});
				}
				update();
			});
		}
	});
})(jQuery);

php部分

待续...

位运算

基本概念

  • 左移 <<
    右边空位补0,其值相当于x2。
  • 右移 >>
    如果为正数左边空位补0,如果为负数则可能补0或补1(取决于所使用的计算机系统)。
  • 按位与 &
    两个都为1则为1
  • 按位或 |
    其中一个为1则为1
  • 按位异或 ^
    “半加”,不同的为1,相同的为0
  • 取反 ~
    ~1 = 0, ~0 = 1 涉及补码的算法:
    1. 正数的补码与原码相同
    2. 负数的补码是对其原码逐位取反,但符号位(第一位)除外;然后整个数加1。

常用算法

判断奇偶性

lambda x : x & 1

取二进制数的第k位

lambda x, k : x >> k & 1

二进制数k位清0

lambda x : x & ~ (1 << k)

二进制数k位置1

lambda x : x | (1 << k)

求平均值

lambda x, y : (x & y) + ((x ^ y) >> 1)

判断是否为2的幂

lambda x : ((x & (x-1)) == 0) && (x != 0)

交换两整数

a, b = 3, 4
a = a ^ b
b = b ^ a
a = a ^ b
print(a, b) #4 3

uploadify的使用

html

Upload photos

Uploading…
Empty the list

javascript

$(function() {
	var fileRemoved = false;
	function reset() {
		$("#fileInputQueue, #upload-tools").hide();
		$("#status").empty().hide();
		$("#doc-loading").hide();
	}
	$('#fileInput').uploadify({
		uploader: 'static/js/uploadify/uploadify.swf',
		script: 'uploadify.php',
		buttonImg: 'static/image/button.png',
		// rollover: true,
		width: 100,
		height: 30,
		cancelImg: 'static/image/cancel.png',
		// auto: false,
		multi: true,
		// method: 'POST',
		fileDesc: 'Photo(*.jpg; *.jpeg; *.gif; *.png)',
		fileExt: '*.jpg; *.jpeg; *.gif; *.png',
		sizeLimit: 31457280,
		// displayData: 'percentage',
		scriptAccess: 'always',
		scriptData: {
		},
		onSelect: function(event, queueID, fileObj) {
			if (parseInt(fileObj.size) > parseInt(31457280)) {
				size_limit = Math.round(31457280 / 1048576 * 100000) / 100000;
				//上传文件大小超出限制
				fileRemoved = true;
				return false;
			}
			$("#fileInputQueue, #upload-tools").fadeIn();
			if (!fileRemoved) {
				//成功选择文件
			} else {
				//...
			}
		},
		onCancel: function() {
			if ($('.uploadifyQueueItem').size() === 1) {
				reset();
			}
		},
		onClearQueue: function() {
			reset();
		},
		onComplete: function(evt, queueID, fileObj, response, data) {
			//console.log(eval('(' + response + ')').pid);
			//$.parseJSON
			$("#fileInput" + queueID + " .uploadifyProgressBar").css("background", "#6AE16A");
			$("#fileInput" + queueID + " .cancel").hide();
			return false;
		},
		onAllComplete: function(evt, queueID, fileObj, response, data) {
			//全部上传成功
			$("#upload-tools, #doc-loading").hide();
		}
	});
	$('#upload-button').click(function() {
		$('#fileInput').uploadifyUpload();
		$('#upload-tools').hide();
		$("#fileInputQueue").before($("#doc-loading").show());
	});
});

css

.uploadifyQueue{border:1px solid #CCC;display:none;max-height:300px;margin:16px 0 24px 0;overflow:auto;zoom:1;}
.uploadifyQueueItem{border-bottom:1px solid #E2E2E2;font-weight:bold;padding:8px;}.uploadifyQueueItem .cancel{float:right;}
.uploadifyQueueItem:last-child{border-bottom:0;}
.uploadifyError{background-color:#eeacac !important;color:#cc0000 !important;}
.uploadifyProgress{background:#EEE;height:6px;margin-top:8px;overflow:hidden;width:100%;zoom:1;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:inset 0 0 1px rgba(0, 0, 0, 0.05);-webkit-box-shadow:inset 0 0 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 0 1px rgba(0, 0, 0, 0.05);}
.uploadifyProgressBar{background:#333;height:6px;margin-left:-1px;width:1px;}
a.delete-item{background:url('static/images/icons/delete.png') center left no-repeat;padding-left:18px;line-height:18px;}

google地图overlay

就是添加一个自定义的层,使用方法(初始化一个):
new FastMarker();

function FastMarker(latlng, options) {
	this.latlng = latlng;
	this.options = options || {};
}
FastMarker.prototype = new google.maps.OverlayView();
FastMarker.prototype.onAdd = function(map) {
	var div = document.createElement('div');
	if (this.options.className) div.className = this.options.className;
	if (this.options.html) div.innerHTML = this.options.html;
	if (this.options.dom) div.appendChild(this.options.dom);
	if (this.options.id) div.id = this.options.id;
	div.style.position = 'absolute';
	this.map = map;
	this.div = div;
	var events = ['click', 'dblclick', 'contextmenu', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousewheel', 'DOMMouseScroll'];
	for (var i = 0; i < events.length; i++)
	 google.maps.event.addDomListener(div, events[i], this.stop, false);
	var panes = this.getPanes();
	panes.overlayLayer.appendChild(div);
};
FastMarker.prototype.draw = function(force) {
	var point = this.getProjection().fromLatLngToDivPixel(this.latlng);
	this.div.style.top = (point.y) + 'px';
	this.div.style.left = (point.x) + 'px';
};
FastMarker.prototype.onRemove = function() {
	google.maps.event.clearInstanceListeners(this.div);
	this.div.parentNode.removeChild(this.div);
	this.div = null;
};
FastMarker.prototype.getPosition = function() {
	return this.latlng;
};
FastMarker.prototype.stop = function(e) {
	if (navigator.userAgent.toLowerCase().indexOf('msie') != -1 && document.all) {
		window.event.cancelBubble = true;
		window.event.returnValue = false;
	} else {
		e.stopPropagation();
	}
};

重置mysql root密码

这里要说的是忘记root密码之后怎么去改密码。

killall -TERM mysqld #关闭mysql进程
/usr/local/mysql/bin/mysqld_safe --skip-grant-tables  --skip-networking & #安全模式启动mysql
mysql #直接mysql命令进去

注意该模式下进去是没有grant权限的,我们只能直接对表进行操作,下面是sql语句

USE mysql;
UPDATE user set password=password('new password') WHERE user='root';
FLUSH PRIVILEGES; #刷新权限

但是遇到徐老师这样的草泥马,把表清空了,N多的字段啊,果断从本地mysql的表里面搞出sql语句,插进去:

USE mysql;
INSERT INTO `user` VALUES ('%', 'root', PASSWORD('your password'), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', 0, 0, 0, 0);
INSERT INTO `user` VALUES ('localhost', 'root', PASSWORD('your password'), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', 0, 0, 0, 0);
FLUSH PRIVILEGES; #刷新权限

svn杂记

chmod +x hooks/pre-commit

svn强制要求填写注释

./hooks/pre-commit

REPOS="$1"
TXN="$2"

SVNLOOK=/usr/bin/svnlook

LOGMSG=`$SVNLOOK log -t $TXN $REPOS | wc -m`
if [ "$LOGMSG" -lt 48 ]
then
	echo "\n至少输入4个汉字" >&2
	exit 1
fi
exit 0

svn自动加版本号

enable-auto-props = yes
[auto-props]
*.php = svn:keywords=Date Author Id Revision HeadURL
*.css = svn:keywords=Date Author Id Revision HeadURL
*.html = svn:keywords=Date Author Id Revision HeadURL
*.js = svn:keywords=Date Author Id Revision HeadURL

svn同步到web目录

svn co file:///var/www/svn/sandbox /var/www/html/
#./hooks/pre-commit
svn up /var/www/html/

javascript判断数据类型

js的一切皆对象,constructor(构造函数)

alert([].constructor == Array);
alert({}.constructor == Object);
alert("string".constructor == String);
alert((123).constructor == Number);
alert(true.constructor == Boolean);

python多线程读取文件

网上只有多进程,有木有?理解和书写代码花了一天的时间,有木有?

多线程分块读取

# -*- coding: utf-8 -*-
import os,time
import threading

rlock = threading.RLock()
curPosition = 0

class Reader(threading.Thread):
    def __init__(self, res):
        self.res = res
        super(Reader, self).__init__()
    def run(self):
        global curPosition
        fstream = open(self.res.fileName, 'r')
        while True:
            #锁定共享资源
            rlock.acquire()
            startPosition = curPosition
            curPosition = endPosition = (startPosition + self.res.blockSize) if (startPosition + self.res.blockSize) < self.res.fileSize else self.res.fileSize
            #释放共享资源
            rlock.release()
            if startPosition == self.res.fileSize:
                break
            elif startPosition != 0:
                fstream.seek(startPosition)
                fstream.readline()
            pos = fstream.tell()
            while pos < endPosition:
                line = fstream.readline()
                #处理line
                #print(line.strip())
                pos = fstream.tell()
        fstream.close()

class Resource(object):
    def __init__(self, fileName):
        self.fileName = fileName
        #分块大小
        self.blockSize = 100000000
        self.getFileSize()
    #计算文件大小
    def getFileSize(self):
        fstream = open(self.fileName, 'r')
        fstream.seek(0, os.SEEK_END)
        self.fileSize = fstream.tell()
        fstream.close()

if __name__ == '__main__':
    starttime = time.clock()
    #线程数
    threadNum = 4
    #文件
    fileName = 'IPData.txt';
    res = Resource(fileName)
    threads = []
    #初始化线程
    for i in range(threadNum):
        rdr = Reader(res)
        threads.append(rdr)
    #开始线程
    for i in range(threadNum):
        threads[i].start()
    #结束线程
    for i in range(threadNum):
        threads[i].join()

    print(time.clock() - starttime)

多线程按行读取

#在上面的代码中使用open(file, 'r')产生的句柄每次在线程锁里面pop()就好了。

python之排序算法

快速排序

取一个元素,剩余元素与这个元素比较,小的放左边,大的放右边,依此循环嵌套,以下是实现的代码:

lis = [18,2,4,54,64,56,77]
def quicksort(lis):
	return [] if lis == [] else quicksort([x for x in lis[1:] if x < lis[0]]) + [lis[0]] + quicksort([x for x in lis[1:] if x >= lis[0]])
print(quicksort(lis))

Oracle sql杂记

一些注意点

-- || 连接字符串和字段
-- 所有数据区分大小写
-- IN 语句的范围内存在NULL对结果无影响
-- NOT IN 语句中范围内存在NULL,则不返回任何数据
-- NULL计算后的值还是NULL
-- 日期 - 数字 = 日期
-- 日期 - 日期 = 数字

一些函数

DECODE(a, 1, '男', 2, '女') -- 你懂的
NVL(a, 0) -- 字段为NULL的值
MONTHS_BETWEEN(a, b) -- a,b两个日期之间相差的月数
ADD_MONTHS(sysdate, 2) -- 在日期上加上指定的月数
NEXT_DAY(sysdate, '星期一') -- 下一个星期一
LAST_DAY(sysdate) -- 一个月的最后一天
WITH sql1 as (SELECT * FROM test) SELECT * FROM sql1 WHERE  -- with语句

select lpad('tech', 2) from dual -- te
select lpad('tech', 8, '0') from dual -- 0000tech

TRUNC(TO_DATE('24-Nov-1999 08:00 pm', 'dd-mon-yyyy hh:mi am')) -- '24-Nov-1999 12:00:00 am' 
TRUNC(TO_DATE('24-Nov-1999 08:37 pm', 'dd-mon-yyyy hh:mi am','hh')) -- '24-Nov-1999 08:00:00 am'

TRUNC(89.985, 2) -- 89.98
TRUNC(89.985) -- 89
TRUNC(89.985, -1) -- 80

select t.Name, case t.id when 1 then 'zhao' when 2 then 'qian' when 3 then 'sun' else 'li' end "fname" from T t

WMSYS.WM_CONCAT -- 行转列

一些常见的报错

未明确定义列

这一般只有在有子查询的sql语句中才会出现的错误,以为子查询的结果中有同名的列。如:

select to_char(dateline, 'yyyy-mm-dd') as dateline from test_table

这样的sql语句作为子句的时候,ORACLE会认为有两个同名的dateline列。解决办法就是将as后面的dateline改为其他的,如:fdateline

php杂记

逻辑运算

对于整个表达式来说:

或(|| or)两个同时为真则为真
与(&& and)有一个为真则为真
#这里可以用三目运算实现,这里只是为了说明逻辑关系。
$data = array(
    array('a'=>'a','b'=>''),
    array('a'=>'','b'=>'b'),
    array('a'=>'a','b'=>'b')
);
while(list(,$item) = each($data)) {
    ($item['a'] and $item['b']) and ($result = $item['a'] . $item['b']) or ($item['a'] and ($result = $item['a'])) or ($item['b'] and ($result = $item['b']));
    var_dump($result);
}
// string(1) "a"
// string(1) "b"
// string(2) "ab"

位运算

位的偏移运算,2进制

//   1
// 100 化成十进制 2的平方 = 4
echo 1<<2;

类型自动转换

可悲啊,在公司的群里面,发了下面的一道,居然没有一个人去尝试执行结果。

var_dump(0 == 'string'); // true
var_dump(true == 'string'); // true
var_dump(0 == false); //true

都是true?相信后两个的执行结果都能理解,为什么第一个也是true呢?
intval('string'); //0 看到木有,当字符串跟数字比较的时候,php会自动转换字符串为数字,啊哈。再来看看这个 intval('2string'); //2

创建多级目录

mkdir('/test1/test2', 0777, true); //最后一个参数设为true就可以了

正则杂记

验证手机号码

中国移动号段 1340-1348 135 136 137 138 139 150 151 152 157 158 159 187 188 147
中国联通号段 130 131 132 155 156 185 186 145
中国电信号段 133 1349 153 180 189
其他 181 182 183 184
^(13[0-9]|15[0-9]|14[0-9]|18[0-9])\d{8}$
^(1[3-5][0-9]|18[0-9])\d{8}$
^(1[3-58])\d{9}$

验证邮箱

^\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,4}$

验证日期

^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$

验证时间

格式:时:分:秒

^([01]?\d|2[0-3]):[0-5]?\d:[0-5]?\d$

验证url

^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|net|org|biz|info|name|museum|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$

环视

以前一直没明白正则的环视的使用环境,网上的那些例子不用环视也能写出来,而且更容易理解。其实,在需要匹配的字符串有长度限制的时候,而且有其他的特殊要求的时候,用环视能很好的解决问题。这样说,还太抽象了,下面看例子:

#有待更新

一些注册表单会用到的正则

用户名(允许字母、数字、下划线、减号、中文)

^[A-Za-z0-9_\-\u4e00-\u9fa5]+$
^[A-Za-z0-9_\-\x{4e00}-\x{9fa5}]+$

真实姓名(允许字母、中文)

^[A-Za-z\u4e00-\u9fa5]+$    // js
^[A-Za-z\x{4e00}-\x{9fa5}]+$    // php

http及https的url

^http[s]?:\/\/([\w-]+\.)+[\w-]+([\w-./?%&=]*)?$

IP v4,下面把四个展开写是为了看起来比较直观,其实可以写的更短一点。

^(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)$

验证子网掩码

^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$

flush这个函数

这个函数呢,在每个浏览器下的作用结果是不一样的:

  • IE下,接受到256个字节之后才开始显示
  • Chrome下,接受到2048个字节之后才开始显示

$my_string_var = 'test...';
echo '';
for($i = 1, $i <7, $i++) {
	echo str_pad($my_string_var, 2048, ' ');
	@ob_flush();
	flush();
	sleep(1);
}

file_get_contents这个函数

当要获取的URL资源不存在的时候,这个函数在linux和windows下返回的结果是不一样的。

在windows下,当访问的页面返回404的时候,file_get_contents不会去获取response的body的值,会返回false

而在linux下他会去获取404的HTML页面的内容。

上述情况和网络环境有关。

所以去判断一个远程文件是否存在的时候,不能使用file_get_contents($url,0,null,0,1),而应当去获取response的头状态。