[原]使用结巴分词提供分词服务

    在之前的文章《关于“啊哦”这个图片分享的小站》有提到过,那里面实现了一个提取用户输入关键词的服务,用来作为分享的tag。

    之前没有这个功能的时候,tag必须要手动输入。我觉得这样没意思,不好玩。就在github上找到了结巴分词这样一个工具,原作者是用python实现的,现在也有许多其他版本的实现,比如java,C++。

    最开始我想选用C++版本的,因为这个版本提供了http服务,可以直接用PHP调用,但是后来读他的说明和联系作者,发现只提供了分词的服务,而没有提取关键词的服务。(虽然作者后来帮忙加上了提取关键词的http服务)。所以只能自己动手丰衣足食了。

    结巴分词的关键词提取功能相对简陋,不过感谢作者。提取关键词的时候会先分词,然后 使用 TF/IDF排序方式 来计算这些词的排名。最近有在考虑用完成以下结巴分词PHP版,先不论PHP性能对比其他的怎么样。至少自己能学到很多。

    最原始python实现的代码没有对外提供服务,所以对于这种我自己玩的小应用随便实现一个常驻进程提供服务就可以啦。应该是很容易的。于是我找到了能让python提供http服务的框架 tornado。只要几行代码,就可以成功启动服务,简直酷炫。    

Continue reading

Code | wwpeng | | (0) |

关于“啊哦”这个图片分享的小站

    想做一个个人的站点,来实现莫名其妙蹦出来的各种奇怪的想法,这是一年前想做的东西,啊哦 (我不怎么会起名字,就选了个象声词来代表了) 已经运行了将近一年了,虽然没什么用户,也没什么流量,这不重要,这里有点像是一个私人的试验田,时不时的改动和新想法在实现。

    网站的整体UI都是我一个搞后端的人自己搞的。尽情的吐槽吧,一年前设计成这样,就不想大改了,那时候还没有用过bootstrap等等类似的框架,完全手写的UI。打开PS的那个时候。。我觉得我跟这个软件格格不入。

  啊O – 简单图片分享

    这LOGO看着眼熟嘛?你猜对了。。当时刚刚热映完的泰囧的那个囧字。。被我弄来了~~~

    这个站的目前也实现了点有点意思的功能,比如现在已经实现了的自动提取关键词的服务等,用户分享图片后数据的一段话,如果用户没有输入关键词的话,可以程序调用服务自动获取服务来提炼这一段话的关键词。

    图片的来源我会写一些python的爬虫去别的网站抓取,然后在过滤。。

    还做过一些验证图片唯一性之类的时间。。有时间在博客里面一一聊聊。

    我还有好长的TODO list 没有完成。比如,badwords屏蔽,人脸识别,等等这样的有趣的功能我都想尝试下。come on~

    服务器是阿里云的乞丐版,满足个人的需求是问题不大的。    

    关于这个小东西,欢迎大家留言,意见也好,吐槽也好,觉得这玩意好像没啥用都好。。。欢迎留言,我会认真考虑大家的意见

Code | wwpeng | | (0) |

[原]使用算法放大用户点击坐标数据的粒度

    最近在公司昨做了一个关于用户点击行为的各种统计,其中包括最直观的 点击热点图。   样貌如下: 

    

    我是做后端的,前端肯定直接用写好的库,其中用到的生成热点图的类库是 heatmap,详情参看 github。在此感谢作者。

    关于这个heatmap 还是有一些坑的,之后我在写一个关于heatmap的文章。下面介绍另外的一个问题,就是数据量的问题。一个网站的页面用户的点击量是很大的,即使只有一天。因为用户的每一次点击都会被记录下来。这些数据不论存储在关系数据库里面 还是 nosql里面 都是不小的。效率问题很严重。

    如果这个页面被点击了100W次,再除去坐标重复,因为存储的时候会有一个坐标计数,也就是同一个坐标被点击多次,只有一个记录,但是即使这样,数据量依旧很大,将近100W条记录。这在程序里面直接读出来然后交给JS再画到canvas画布上,服务器内存再大也是吃不消的,

    举个栗子:如果PHP被开的memory limit 内存限制是8G的话,也就能取出10-20W条记录,就爆掉了。而且没有大数据字段,字段数据量都不大。

    比如我们当时的记录是 url:xxxx , x_y:100,200 , count 10 , time:xxxxxx 。就是这样一些简单的字段。

    所以解决方案有两种:

Continue reading

Code | wwpeng | | (1) |

[原]Bash3的key-value数组使用

    平常工作中会遇到很多需要打很多命令的操作,最方便的时写成一个shell脚本让他帮你完成。会懒的程序员才是好程序猿。

    这次我是在写一个需要同步fork库与主库的代码的时候遇到的,首先我需要同步很多个fork库,其次,每次主库都有一个URL,不可能都背下来,每次同步都要运行五六个命名,时间久了以后,自然非常烦。如果在其他语言中,很明显,一个key-value的数组/map之类的就可以直接对应库和url之间的关系了。但是查到bash3的时候居然没有,只能使用数字索引的一维数组。(bash4已经有了),没办法,既然没有自定义key,只能把key放在value里面,自己去解析了。

    上菜。

hgReg=(
	"key1_:_value1" 
	"key2_:_value2" 
	"key3_:_value3"
)
#数组使用 _:_ 这个符号组合来分割,如果有冲突可以替换成别的,前半部分为key,后半部分为value
function process_array() {
	declare -a hash=("${!1}")
	key="${2}"
	for k in "${hash[@]}"; do
		if [ $key = ${k%%_:_*} ];then
			echo ${k##*_:_}
		fi
 	done
}
#调用方式 结果是:value1
echo $(process_array hgReg[@] "key1")

 

Code | wwpeng | | (0) |

[原]子站点不可控的情况下iframe跨域自动适应高度

    关于iframe如何自动适应内部网站的高度,这个 在网上搜出来的千篇一律,都是用js获取内部内容的高度然后重新设置iframe的高度。但是这个方式在非跨域的情况下完全没有问题。只是跨域的时候,js是不能获得内部内容的高度的,什么都获取不到。

    很多的跨域解决方案都需要内部子站点做出动作,主动发起通知父站点的iframe。但是还有一种很棘手的情况,就是你对于子站点完全没有权限,或者,也不想为了这个事情,再去做一个通知这样的功能。

    所以,就只能自己动手满足自己的需求了。

    这里的方案的主要思路是:把跨域的转换成非跨域的

    我再本地项目中做一个页面专门用来对url对应网站的内容进行转发。

    a.php?url=www.baidu.com

<?php
echo file_get_contents('http://'.$_GET['url']);
?>

     这样的话,只需要将当前站点的 a.php?url=www.baidu.com 放在iframe当中就可以了,内部的css,js,图片等资源还是用的原来的远程地址,但是加载这些东西不会存在跨域问题,最重要的是这样我们就可以随意的用js去获取内部内容的高度了,然后再设置外部iframe的高度。

    唯一的弊端是:如果这个网站中又大量ajax加载的内容的话,就不适用这个方案,当然,jsonp的话是没关系的。

    因为如果页面中得内容是ajax加载进来的话,因为把页面转发到了本地网站,所以ajax会存在跨域请求不成功的问题,内容自然也就加载不出来了。

    所以,都是有缺点的,所以根据具体情况具体确定方案吧。

    

PS:我找过CSS的解决方案,但是没找到,不好使。有没有前端大神。知道可行的CSS解决方案???

Code | wwpeng | | (0) |

[原]关于高并发下限流用户访问

    在高并发大流量下总是有一些意想不到或者考虑不周全的事情发生。而一个网站首先是保证能够提供服务,哪怕分流或者降低速度(不得已情况下)。这就需要有一套限流的方案,在不得已的情况下启用,防止服务器停止服务。就好比小米商城抢小米时候的排队,其实就是类似的。这里我们向讨论一些简单的方案思路。

   方案1:

    直接按照用户访问数量的百分比进行限制。比如要举行大的促销。预计并发访问量是 15W,集群服务器平均打到每台机器上的并发访问量是 500,而单台机器的最大承受并发400,这时候只要限制20%的流量就可以了。(这些数据都是粗糙的举例,不要较真啊。)

    但是这种方案明显有一个弊端就是你判断不出来,当前的访问量是否需要启用限流,以为这样的限流都是针对某次大规模请求,有预估,促销之前,代码启用,促销之后,流量下降,代码就要下线。很是麻烦和不好评估统计。

   方案2:

    首先我们可以确定,一台机器的承受能力一般是固定的,可以测试出来的。如果我们能涉及一种计数机制,当QPS达到机器极限的时候限制,就可可以了。

    另外设计这种计数机制不能同步进行,也就是不能加锁,因为同步计数的话,会导致另外的进程等待。。这明显不符合初衷。比如说,我试过用memcache计数,但是很明显,链接memcache然后计数是一个同步过程,最后计数倒是一个都不差,但是很慢。但是不加锁并发惊醒的话就会导致有误差,也就是说多个进程取到同一个值,这个其实我们可以在测试过程中获得一个这种情况出现的概率。然后只要概率在接收范围之内就可以了。所以宗上,PHP的无锁共享内存就是一个可以考虑的方式。

    这里先说一下结果。

    在我自己的机器上,PHP5.4+nginx 四核 i5 nginx进程数4 模拟并发请求 200 限制用户数 100,超过计数的用户会跳转到一个等待页面。

    在这种情况下,实际数据是 进入的用户回进入 100-110左右。也就是说 会上浮 5%-10% (不过我觉得线上服务器CPU多达20多个核心,进程数也多很多,所以误差可能会更大一些

    下面看说一下实现方式:

    在共享内存当中存两个字段,一个字段用来计数,另一个字段用来计时,每一秒中,计数器从0开始重新计,如果超过预设值,就 跳出,否则进入。

    注意:PHP共享内存有两种方式,一种是 shmop系列,还有一种是 shm_attach 系列,这两种都可以完成共享内存的操作,具体区别。。请自行补脑。。我这里使用的是 shmop。 Continue reading

Code Server | wwpeng | | (0) |

[原]等概率随机函数

    最近面试呀,肯定又接触了不少以前没接触过的东西。这不,又遇上一个,整理了一段时间,就准备发上来啦。

    关于等概率随机函数,以前都是用随机数生成函数 直接给定范围,生成随机数。没有多想。

    这个的主要意思其实就是  用一个已知的等概率随机函数去完成另一个函数。

eg:已知函数 f5() 该函数的作用是生成一个 1-5 的随机数。请用该函数实现另一个函数 f7() 产生 1-7 的随机数。

ps:看上去好像实际过程中这玩意其实没什么用。1-7 rand 一下不就有了么。。其实这里面 比较重要的还是 了解 数学思想在实际中的应用。数学用的熟练了,就能写出比这有用多的东西啦。

    1. 使用一个算数式 扩展 f5() 产生的随机数。

    例如 : ( f5()-1 ) + f5()

    OK,这样一计算我们就发现,这个结果已经被扩展到了  1-9。但是!有的朋友应该注意到了,1-9并不是等概率产生的。我们来看产生的数字表格。

    

1 2 3 4 5
0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9

    这样的话 最低概率 是 1 出现的概率是 1/25 最高是 5出现的概率 5/25。

Continue reading

Code | wwpeng | | (14) |