向好之心

原文地址:http://www.cbnweek.com/yuedu/ydpage/?raid=1469

  我在看日系少女杂志的采访记录的时候,《恋物志》发行人有一句话打动了我,他说他们可不简单地是在卖什么杂志,他们是把美好卖给读者。我喜欢这种对自己的工作和事业的理解,为此我特意找来一本看,嗯,我相信他所言不虚。

  以前《连线》杂志的创始主编凯文·凯利来我们这里做客的时候,他说,《连线》不是一本技术杂志,而是一本生活方式杂志。他相信技术控们关注的不仅仅是技术发展,而是一种生活态度和生活方式。

  同样,当有读者批评我们IT报道过多时,我也试图用这种方式去辩解:至少在目前,IT业还是最有创造力、创新能力最强的一个行业,哪怕是一个看起来不起眼的小公司,它可能也怀抱着颠覆和改变世界的梦想—所以,我们不仅仅是报道IT,我们更关注创造力,对那些发挥出创造力的公司充满敬意,对任何扼杀创造力的行为深恶痛绝。

  杂志不简单是新闻、信息的组合,读者对杂志的认同还包括完整的价值观。而对于《第一财经周刊》来说,我们相信商业带来的民主化,相信商业创新是推动这个社会不断进步的最有效的手段。我们通过杂志把这些呈现给读者,这是我们觉得自己的价值所在。出满200期的时候,我们在网站上把所有的杂志封面摆出来—这本杂志的进步,缘于我们对商业创新和民主化越来越多的专注和坚定。

  不管是优秀的杂志,还是优秀的公司,如果有什么共同点的话,就是大家都有足够的“向好之心”。这个“向好”,既有提供美好、使世界更好的理想,也有做得更加精致、把一切推向极致的完美主义理想。

  很难说从什么时候开始,完美主义变成了一个中性词,比如在好多声称崇拜史蒂夫·乔布斯的那些人那里,面对这个完美主义代言人—他有舞台实现了自己的完美主义,并且取得了商业上的极大成就,但即便如此,完美主义也没有成为这些粉丝所追求的目标,相反,这个神化了的偶像,被塑造成可望不可即的形象,让完美主义与偏执或者不近情理这样的定位纠结在一起。

  一个很小的例子:有一天我的一位朋友看到了Path,虽然他很少关注技术领域和互联网应用的变化,却立刻为设计美感所折服,成为了这个产品的用户—我觉得这就是完美主义的价值,Path跟苹果的许多产品一样,不是一个完全创新的产品,它用完美主义的态度和方式来做一件事。即使是快餐,如麦当劳,它也是用一种完美主义的操作流程来给它的顾客提供标准化服务。这种标准化更是完美主义的一部分。

  “向好之心”还能让自己更强大。哈佛商学院教授理查德·泰德洛曾讲过,若好莱坞不当自己是电影业,而是娱乐业,那么在电视普及大潮席卷娱乐业时,就不会死抱着电影不放。更早的19世纪末的马车制造业者也不应给自己定位成马车生产商,而应把自己看作交通运输业的一部分。当别人都在说传统平面媒体业没落的时候,你会知道你不简单是一个“做杂志的”,你可以更深入思考你在整个市场中的定位。

  我们生来就是让世界变得更美好的,哪怕这变化只是一点点,但我们也就因之而有了伟大的基础。这样想来,我们仿佛就有了更多能量,就能更强大;这样想起来,就好像,这世界正在变得好起来。

 

转载:Ring Buffer 和 Memory Poll

原文链接:http://blog.ddup.us/?p=241
—————————————————————————-
那天看到微博上看到讨论如何设计网络程序Buffer(链接)。其中@简悦风云 给出个使用Ring Buffer的思路同时也顺带着嘲讽了一下C++和STL(链接),结果引出混战。本文不关心事件,纯粹讨论其中的两个技术点——RingBuffer和Memory Poll。

两者都是内存管理中比较常用的技术。我们知道C语言中使用malloc/free库函数来申请/释放内存,C++中对应的是new/delete,终归也是调用malloc/free。有些程序会非常频繁的申请/释放内存,这就导致内存碎片的产生,进而引起性能下降甚至内存分配失败。像Memcached这种内存kv数据库为了解决这种问题都是在应用层自己又实现了一套内存管理模块。Redis早期版本直接使用malloc/free库函数,后来忍受不了其性能,在后续版本中使用freebsd中的内存管理算法jemalloc来代替。所以在高性能程序中,优良的内存管理算法至关重要。

Ring Buffer

Ring Buffer也叫Circular Buffer,是一种缓冲区数据结构,一般用于生产者-消费者模式的程序中,一个或多个生产者不停产生数据,同时一个或多个消费者使用数据,数据使用完这块缓冲区就可以释放了。简单的Ring Buffer其实就是基于连续内存地址的循环队列,稍有不同的是当队列满时,某些Ring Buffer应用场景可以直接覆盖掉队尾的数据。风云给出的socket连接例子(链接)就是这种情况。建立Ring Buffer首先就是先malloc出一大块连续内存空间,然后遵循先入先出FIFO原则申请释放内存,后续的内存操作都在这块实现开辟的内存区域完成,这也就省去了每来一条数据就申请一次内存的开销。可见不仅是从执行时间上还是从减少内存碎片角度看,这种方法都比原生的malloc要好。

但是这种方式的缺点也是显而易见的:1)只适用于数据是FIFO的这种情况,一旦数据不是按照先申请先释放原则进行,那内存碎片问题还是解决不了。2)需要预估缓冲区大小,因为缓冲区一次申请完毕,后续调整代价比较大,所以需要预估大小。3)队列管理,这其实是数据结构与算法的问题。不过一旦其中存放时的变长数据的话,解决起来要稍稍复杂一些。

摘一段Wikipedia上的简单Ring Buffer代码:

/* Circular buffer example, keeps one slot open */
#include
#include

/* Opaque buffer element type. This would be defined by the application. */
typedef struct{int value;} ElemType;

/* Circular buffer object */
typedefstruct{
int size; /* maximum number of elements */
int start; /* index of oldest element */
int end; /* index at which to write new element */
ElemType *elems; /* vector of elements */
} CircularBuffer;

void cbInit(CircularBuffer *cb,int size){
cb->size = size +1;/* include empty elem */
cb->start =0;
cb->end =0;
cb->elems =(ElemType *)calloc(cb->size,sizeof(ElemType));
}

void cbFree(CircularBuffer *cb){
free(cb->elems);/* OK if null */
}

int cbIsFull(CircularBuffer *cb){
return(cb->end +1)% cb->size == cb->start;
}

int cbIsEmpty(CircularBuffer *cb){
return cb->end == cb->start;
}

/* Write an element, overwriting oldest element if buffer is full. App can
choose to avoid the overwrite by checking cbIsFull(). */
void cbWrite(CircularBuffer *cb, ElemType *elem){
cb->elems[cb->end]=*elem;
cb->end =(cb->end +1)% cb->size;
if(cb->end == cb->start)
cb->start =(cb->start +1)% cb->size;/* full, overwrite */
}

/* Read oldest element. App must ensure !cbIsEmpty() first. */
void cbRead(CircularBuffer *cb, ElemType *elem){
*elem = cb->elems[cb->start];
cb->start =(cb->start +1)% cb->size;
}

int main(int argc,char**argv){
CircularBuffer cb;
ElemType elem ={0};

int testBufferSize =10;/* arbitrary size */
cbInit(&cb, testBufferSize);

/* Fill buffer with test elements 3 times */
for(elem.value=0; elem.value<3* testBufferSize;++ elem.value) cbWrite(&cb,&elem); /* Remove and print all elements */ while(!cbIsEmpty(&cb)){ cbRead(&cb,&elem); printf("%d\n", elem.value); } cbFree(&cb); return0; }

Memory Poll

内存池技术更是由来已久,以至于基本上遇到内存管理一般人首先想到的就是这个。的确不管是在操作系统内核中还是在应用层程序中,内存池技术广泛的应用。之前说的memcached就是自己在应用层实现了一套内存池。另外SGI版本的STL中为了应对频繁申请/释放小内存块产生的内存碎片问题,同样用到了内存池技术。

SGI版本的STL中默认的内存分配是通过std::alloc完成的,其中将内存分配划分为两级:小于等于128B的在第一级中分配;大于128B的在第二级中分配。第二级内存分配就是简单的调用operator new完成。第一级实际是一个内存池:其中有11个slot,每个slot对应一个同样大小空闲块链表。块从8B开始,按照8B的倍数递增直到128。这样在分配小内存时,显示将请求的容量向上按8的倍数取整,然后从空闲链表中拿一个空闲区块出来。回收的时候采用类似的方法,将空闲块归还到空闲链表中。这样就能有效避免频繁分配释放小内存块。

可见内存池技术相对于上边的Ringbuffer的优点是:不用关心内存申请释放的顺序。缺点是:1)数据结构更复杂;2)按照固定大小的块划分存在内存浪费。这种浪费是不能避免的,但是可以通过合理的选择块的大小,尽量减少浪费。Memcached提供了可以根据用户自定义的递增因子设置间隔slot中块的增长量。这样就可以针对特定业务做特定优化。

参考

http://en.wikipedia.org/wiki/Circular_buffer

http://blog.codingnow.com/2012/02/ring_buffer.html

《STL源码详解》

 

转载:一次真正的WEB2.0渗透全过程

作者:RAyh4c
原文地址:http://hi.baidu.com/rayh4c/blog/item/87421230ef74db82a9018e82.html

目标是一个大型在线论坛,论坛程序是某著名BBS程序二次开发版,需要得到目标服务器webshell,针对论坛的主站进行各种测试,未发现明显漏洞。

于是开始DNS FUZZ,发现有个子域名指向的另外的服务器存在一套WEB MAIL程序,通过社工的方式GOOGLE搜索到了该邮箱的多个账号,针对账号进行弱口令猜解,获得一个账号登陆了这套WEB MAIL程序,发现此WEB MAIL程序是一套非常老的开源程序,存在目录遍历和文件上传漏洞,得到该服务器的webshell。

从WEB MAIL程序数据库,获得了论坛管理员的一些密码,尝试一些管理员密码登陆主站论坛却需要密码提示问题,无果而返。

发现BBS程序登陆认证的SET COOKIE方式是主域名和子域名通用,于是通过之前得到的webshell上传一个记录HTTP头和IP的PHP探针,将此PHP探针的链接用于贴图发帖,放到个人签名里,到论坛上专门找管理员发过的贴回帖,最后获得了管理员的COOKIE。

使用管理员COOKIE访问论坛发现并没有在登陆状态,怀疑论坛程序对IP做了判断,于是使用Fiddler将所有的请求强制加入X-Forwarded-For头伪造为管理员的IP,这才登陆成功,获得了论坛前台的管理权限。

由于管理员前台发帖有HTML权限,将管理员最新发的几个帖子都修改并加入一个javascript脚本,脚本的作用是绑定网页的点击事件为伪造登陆窗口的函数,在伪造的登陆窗口内记录管理员输入的密码和密码提示问题,静默发送到远程的脚本。

最终得到管理员的密码提示问题,登陆论坛后台,利用论坛的模板功能获取WEBSHELL,整个渗透完成。