知乎上有网友问"为什么很多看起来不是很复杂的网站,比如 Facebook 需要大量顶尖高手来开发?",这个问题在知乎上引发了激烈的讨论,同时知乎大神们也贡献了很多有价值的问答,小编将这些价值的回答分享给大家,希望对大家有所帮助。

知乎网友@子柳 的回答得到了4778个赞同。

@子柳:

就拿淘宝来说说,当作给新人一些科普。

先说你看到的页面上,最重要的几个:

【搜索商品】——这个功能,如果你有几千条商品,完全可以用select * from tableXX where title like %XX%这样的操作来搞定。但是——当你有10000000000(一百亿)条商品的时候,任何一个数据库都无法存放了,请问你怎么搜索?这里需要用到分布式的数据存储方案,另外这个搜索也不可能直接从数据库里来取数据,必然要用到搜索引擎(简单来说搜索引擎更快)。好,能搜出商品了,是否大功告成可以啵一个了呢?早着呢,谁家的商品出现在第一页?这里需要用到巨复杂的排序算法。要是再根据你的购买行为做一些个性化的推荐——这够一帮牛叉的算法工程师奋斗终生了。

【商品详情】——就是搜索完毕,看到你感兴趣的,点击查看商品的页面,这个页面有商品的属性、详细描述、评价、卖家信息等等,这个页面的每天展示次数在30亿以上,同样的道理,如果你做一个网站每天有10个人访问,你丝毫感觉不到服务器的压力,但是30亿,要解决的问题就多了去了。首先,这些请求不能直接压到数据库上,任何单机或分布式的数据库,承受30亿每天的压力,都将崩溃到完全没有幸福感,这种情况下要用到的技术就是大规模的分布式缓存,所有的卖家信息、评价信息、商品描述都是从缓存里面来取到的,甚至更加极致的一点“商品的浏览量”这个信息,每打开页面一次都要刷新,你猜能够从缓存里面来取吗?淘宝做到了,整个商品的详情都在缓存里面。

【商品图片】——一个商品有5个图片,商品描述里面有更多图片,你猜淘宝有多少张图片要存储?100亿以上。这么多图片要是在你的硬盘里面,你怎么去查找其中的一张?要是你的同学想拷贝你的图片,你需要他准备多少块硬盘?你需要配置多少大的带宽?你们的网卡是否能够承受?你需要多长时间拷贝给他?这样的规模,很不幸市面上已经没有任何商业的解决方案,最终我们必须自己来开发一套存储系统,如果你听说过google的GFS,我们跟他类似,叫TFS。顺便说一下,腾讯也有这样的一套,也叫TFS。

【广告系统】——淘宝上有很多广告,什么,你不知道?那说明我们的广告做的还不错,居然很多人不认为它是广告,卖家怎么出价去买淘宝的广告位?广告怎么展示?怎么查看广告效果?这又是一套算法精奇的系统。

【BOSS系统】——淘宝的工作人员怎么去管理这么庞大的一个系统,例如某时刻突然宣布某位作家的作品全部从淘宝消失,从数据库到搜索引擎到广告系统,里面的相关数据在几分钟内全部消失,这又需要一个牛叉的后台支撑系统。

【运维体系】——支持这么庞大的一个网站,你猜需要多少台服务器?几千台?那是零头。这么多服务器,上面部署什么操作系统,操作系统的内核能否优化?Java虚拟机能否优化?通信模块有没有榨取性能的空间?软件怎么部署上去?出了问题怎么回滚?你装过操作系统吧,优化过吧,被360坑过没,崩溃过没?这里面又有很多门道。

不再多写了,除了上面提到的这些,还有很多很多需要做的技术,当然并不是这些东西有多么高不可攀,任何复杂的庞大的东西都是从小到大做起来的,里面需要牛叉到不行的大犇,也需要充满好奇心的菜鸟,最后这一句,你当我是别有用心好了。

知乎网友@蔡正海 得到了941个赞同。

@蔡正海 :

刚看了一篇很有意思的文章,讲的很清楚——《你刚才在淘宝上买了一件东西》

  你发现快要过年了,于是想给你的女朋友买一件毛衣,你打开了http://www.taobao.com。这时你的浏览器首先查询DNS服务器,将http://www.taobao.com转换成ip地址。不过首先你会发现,你在不同的地区或者不同的网络(电信、联通、移动)的情况下,转换后的IP地址很可能是 不一样的,这首先涉及到负载均衡的第一步,通过DNS解析域名时将你的访问分配到不同的入口,同时尽可能保证你所访问的入口是所有入口中可能较快的一个 (这和后文的CDN不一样)。

  你通过这个入口成功的访问了http://www.taobao.com的实际的入口IP地址。这时你产生了一个PV,即Page View,页面访问。每日每个网站的总PV量是形容一个网站规模的重要指标。淘宝网全网在平日(非促销期间)的PV大概是16-25亿之间。同时作为一个独立的用户,你这次访问淘宝网的所有页面,均算作一个UV(Unique Visitor用户访问)。最近臭名昭著的http://12306.cn的日PV量最高峰在10亿左右,而UV量却远小于淘宝网十余倍,这其中的原因我相信大家都会知道。

  因为同一时刻访问http://www.taobao.com的人数过于巨大,所以即便是生成淘宝首页页面的服务器,也不可能仅有一台。仅用于生成http://www.taobao.com首页的服务器就可能有成百上千台,那么你的一次访问时生成页面给你看的任务便会被分配给其中一台服务器完成。这个过程要保证公正、公平、平均(暨这成百上千台服务器每台负担的用户数要差不多),这一很复杂的过程是由几个系统配合完成,其中最关键的便是LVS(Linux Virtual Server),世界上最流行的负载均衡系统之一,正是由目前在淘宝网供职的章文嵩博士开发的。

  经过一系列复杂的逻辑运算和数据处理,用于这次给你看的淘宝网首页的HTML内容便生成成功了。对web前端稍微有点常识的童鞋都应该知道,下一步浏览器会去加载页面中用到的css、js、图片、脚本和资源文件。但是可能相对较少的同学才会知道,你的浏览器在同一个域名下并发加载的资源数量是有限制的,例如IE6-7是两个,IE8是6个,Chrome各版本不大一样,一般是4-6个。我刚刚看了一下,我访问淘宝网首页需要加载126个资源,那么如此小的并发连接数自然会加载很久。所以前端开发人员往往会将上述这些资源文件分布在好多个域名下,变相的绕过浏览器的这个限制,同时也为下文的CDN工作做准备。

  据不可靠消息,在双十一当天高峰,淘宝的访问流量最巅峰达到871GB/S。这个数字意味着需要178万个4Mb带宽的家庭宽带才能负担的起,也完全有能力拖垮一个中小城市的全部互联网带宽。那么显然,这些访问流量不可能集中在一起。并且大家都知道,不同地区不同网络(电信、联通等)之间互访会非常缓慢,但是你却发现很少发现淘宝网访问缓慢。这便是CDN(Content Delivery Network),即内容分发网络的作用。淘宝在全国各地建立了数十上百个CDN节点,利用一些手段保证你访问的(这里主要指js、css、图片等)地方是离你最近的CDN节点,这样便保证了大流量分散在各地访问的加速节点上。

  这便出现了一个问题,那就是假若一个卖家发布了一个新的宝贝,上传了几张新的宝贝图片,那么淘宝网如何保证全国各地的CDN节点中都会同步的存在这几张图 片供用户使用呢?这里边就涉及到了大量的内容分发与同步的相关技术。淘宝开发了分布式文件系统TFS(Taobao File System)来处理这类问题。

  好了,这时你终于加载完了淘宝首页,那么你习惯性的在首页搜索框中输入了'毛衣'二字并敲回车,这时你又产生了一个PV,然后,淘宝网的主搜索系统便开始为你服务了。它首先对你输入的内容基于一个分词库进行分词操作。众所周知,英文是以词为单位的,词和词之间是靠空格隔开,而中文是以字为单位,句子中所有的字连起来才能描述一个意思。例如,英文句子I am a student,用中文则为:“我是一个学生”。计算机可以很简单通过空格知道student是一个单词,但是不能很容易明白“学”、“生”两个字合起来才表示一个词。把中文的汉字序列切分成有意义的词,就是中文分词,有些人也称为切词。我是一个学生,分词的结果是:我 是 一个 学生。

  进行分词之后,还需要根据你输入的搜索词进行你的购物意图分析。用户进行搜索时常常有如下几类意图:(1)浏览型:没有明确的购物对象和意图,边看边买,用户比较随意和感性。Query例如:”2010年10大香水排行”,”2010年流行毛衣”, “zippo有多少种类?”;(2)查询型:有一定的购物意图,体现在对属性的要求上。Query例如:”适合老人用的手机”,”500元 手表”;(3)对比型:已经缩小了购物意图,具体到了某几个产品。Query例如:”诺基亚E71 E63″,”akg k450 px200″;(4)确定型:已经做了基本决定,重点考察某个对象。Query例如:”诺基亚N97″,”IBM T60″。通过对你的购物意图的分析,主搜索会呈现出完全不同的结果来。

  之后的数个步骤后,主搜索系统便根据上述以及更多复杂的条件列出了搜索结果,这一切是由一千多台搜索服务器完成。然后你开始逐一点击浏览搜索出的宝贝。你开始查看宝贝详情页面。经常网购的亲们会发现,当你买过了一个宝贝之后,即便是商家多次修改了宝贝详情页,你仍然能够通过‘已买到的宝贝’查看当时的快照。这是为了防止商家对在商品详情中承诺过的东西赖账不认。那么显然,对于每年数十上百亿比交易的商品详情快照进行保存和快速调用不是一个简单的事情。这 其中又涉及到数套系统的共同协作,其中较为重要的是Tair,淘宝自行研发的分布式KV存储方案。

  然后无论你是否真正进行了交易,你的这些访问行为便忠实的被系统记录下来,用于后续的业务逻辑和数据分析。这些记录中访问日志记录便是最重要的记录之一, 但是前边我们得知,这些访问是分布在各个地区很多不同的服务器上的,并且由于用户众多,这些日志记录都非常庞大,达到TB级别非常正常。那么为了快速及时 传输同步这些日志数据,淘宝研发了TimeTunnel,用于进行实时的数据传输,交给后端系统进行计算报表等操作。

  你的浏览数据、交易数据以及其它很多很多的数据记录均会被保留下来。使得淘宝存储的历史数据轻而易举的便达到了十数甚至更多个 PB(1PB=1024TB=1048576GB)。如此巨大的数据量经过淘宝系统1:120的极限压缩存储在淘宝的数据仓库中。并且通过一个叫做云梯的,由2000多台服务器组成的超大规模数据系统不断的进行分析和挖掘。

  从这些数据中淘宝能够知道小到你是谁,你喜欢什么,你的孩子几岁了,你是否在谈恋爱,喜欢玩魔兽世界的人喜欢什么样的饮料等,大到各行各业的零售情况、各类商品的兴衰消亡等等海量的信息。

  说了这么多,其实也只是叙述了淘宝上正在运行的成千上万个系统中的寥寥几个。即便是你仅仅访问一次淘宝的首页,所涉及到的技术和系统规模都是你完全无法想 象的,是淘宝2000多名顶级的工程师们的心血结晶,其中甚至包括长江学者、国家科学技术最高奖得主等众多大牛。同样,百度、腾讯等的业务系统也绝不比淘宝简单。你需要知道的是,你每天使用的互联网产品,看似简单易用,背后却凝聚着难以想象的智慧与劳动。

来自:http://mp.weixin.qq.com/s?__biz=MjM5NDMwNjMzNA==&mid=204484065&idx=2&sn=5892f77d1a95718f28fd48089df97dc2#rd
背景:之前大学学习过c语言,后来上班后学习并以php工作了几年,近来对纯c语言感兴趣,于是学习并试着用c语言编写并编译一个简单的内存指针池小程序发现有warning,multipepollserver.cpp:648: warning: deprecated conversion from string constant to ‘char*’,于是查了下是这样解决的,作一下学习并备案。
原来是:
void saveUpedFilePartInfo2Mem(upFilePart* filePart,const char* guid,unsigned int partIndex,char* httpHeader,char* httpBody,unsigned int httpBodyLen,char* uploadTime)
修改为:
void saveUpedFilePartInfo2Mem(upFilePart* filePart,const char* guid,unsigned int partIndex,const char* httpHeader,const char* httpBody,unsigned int httpBodyLen,const char* uploadTime);//存一个分片>信息到内存池里去                                                                                                                                                                      
阅读全文
背景:今天开了一个Edraw也就是艺图软件,没想到一直在桌面上显示启动画面,且最前面,用任务管理器结束进程还结束不了,还最前面挡住其它软件了,于是,只有强制杀死这个进程了。
有两种方法杀死,一种是进程名,一种是进程ID。
一)Windows 下根据进程名称强制杀死进程命令:
-运行:  taskkill -f -im processname
实践成功如下:
C:\Users\admin> taskkill -f -im Edraw.exe
成功: 已终止进程 "Edraw.exe",其 PID 为 7116。

二) windows下根据进程ID强制杀死进程:
[windows 进程ID PID]
NTSD命令详解
1. ntsd -c q -p PID
2. ntsd -c q -pn ImageName 比如:ntsd -c q -pn qq.exe

-c是表示执行debug命令
q表示执行结束后退出(quit)

-p 表示后面紧跟着是你要结束的进程对应的PID

-pn 表示后面紧跟着是你要结束的进程名(process_name.exe 比如:QQ.exe,explorer.exe 等等,值得注意的是后缀名.exe是不可省略的,否则系统会告诉你“不支持此接口”)

只有System、SMSS.EXE和CSRSS.EXE不能杀。前两个是纯内核态的,最后那个是Win32子系统,ntsd本身需要它。ntsd从 2000开始就是系统自带的用户态调试工具。被调试器附着(attach)的进程会随调试器一起退出,所以可以用来在命令行下终止进程。使用ntsd自动 就获得了debug权限,从而能杀掉大部分的进程。

另外说明一点,一般在windows下可以通过任务管理器得到要操作的进程的ID,或者通过在命令行下执行netstat -ano来得到当前本地已经占用端口的进程信息。

实践如下:
C:\Users\admin>ntsd -c q -p 7080
'ntsd' 不是内部或外部命令,也不是可运行的程序
或批处理文件。



ntsd从Windows 2000开始就是系统自带的进程调试工具,在system32目录下。NTSD的功能非常的强大,用法也比较复杂,但如果只用来结束一些进程,那就比较简单了。WIN7下没有NTSD的你怎么办?
win7 下可以用的 ntsd.exe:
http://download.csdn.net/download/kj863257/2802035


Win7下载后放到path路径下,即可杀死,实践OK:
C:\Users\admin>ntsd -c q -p 7080
C:\Users\admin>





实践来源:http://blog.itpub.net/26994026/viewspace-731483/
http://blog.chinaunix.net/uid-15028-id-2779793.html
背景:今天开了一个Edraw也就是艺图软件,没想到一直在桌面上显示启动画面,且最前面,用任务管理器结束进程还结束不了,于是,只有强制啥死这个进程了。

一)Windows 下根据进程名称强制杀死进程命令:
-运行:  taskkill -f -im processname
实践成功如下:
C:\Users\admin> taskkill -f -im Edraw.exe
成功: 已终止进程 "Edraw.exe",其 PID 为 7116。

二) windows下根据进程ID强制杀死进程:
[windows 进程ID PID]
NTSD命令详解

1. ntsd -c q -p PID
2. ntsd -c q -pn ImageName 比如:ntsd -c q -pn qq.exe

-c是表示执行debug命令
q表示执行结束后退出(quit)

-p 表示后面紧跟着是你要结束的进程对应的PID

-pn 表示后面紧跟着是你要结束的进程名(process_name.exe 比如:QQ.exe,explorer.exe 等等,值得注意的是后缀名.exe是不可省略的,否则系统会告诉你“不支持此接口”)

只有System、SMSS.EXE和CSRSS.EXE不能杀。前两个是纯内核态的,最后那个是Win32子系统,ntsd本身需要它。ntsd从 2000开始就是系统自带的用户态调试工具。被调试器附着(attach)的进程会随调试器一起退出,所以可以用来在命令行下终止进程。使用ntsd自动 就获得了debug权限,从而能杀掉大部分的进程。

另外说明一点,一般在windows下可以通过任务管理器得到要操作的进程的ID,或者通过在命令行下执行netstat -ano来得到当前本地已经占用端口的进程信息。

实践如下:
C:\Users\admin>ntsd -c q -p 7080
'ntsd' 不是内部或外部命令,也不是可运行的程序
或批处理文件。



ntsd从Windows 2000开始就是系统自带的进程调试工具,在system32目录下。NTSD的功能非常的强大,用法也比较复杂,但如果只用来结束一些进程,那就比较简单了。WIN7下没有NTSD的你怎么办?
win7 下可以用的 ntsd.exe:
http://download.csdn.net/download/kj863257/2802035


Win7下载后放到path路径下,即可杀死,实践OK:
C:\Users\admin>ntsd -c q -p 7080
C:\Users\admin>





实践来源:http://blog.itpub.net/26994026/viewspace-731483/
http://blog.chinaunix.net/uid-15028-id-2779793.html
背景:有人在群里问,打扰下,请教一个问题,mac下设置svn关键词自动替换,为啥不生效那?配置如下:


哪位大神遇到类似问题,麻烦指点下
A:
修改的svn配置文件为:~/.subversion/config

____________________________________

在SVN中实现$Id$的自动替换

一直知道SVN有个叫Id关键字可以自动替换成$Id: common.php 34 2012-04-01 08:35:01Z yubing $ 这样的形式.

操作步骤如下:
     修改svn的config, 但这个不同的操作系统,放置的位置不一样

    C:\Documents and Settings\{Windows 用户名}\Application Data\Subversion\config (WindosXP)
    C:\Users\{Windows 用户名}\AppData\Roaming\Subversion\config (Windows7)
    ~/.subversion/config (*uix)

去掉config文件,中的下面一行注释
   enable-auto-props = yes

然后再加上下面这行就好了
  *.php = svn:keywords=Id
  *.js = svn:keywords=Id

以后包含在SVN里的文件,都会自动加上svn:keywords Id这个属性了.


以前已经提交到svn的文件, 自动添加该属性需要执行下面的操作
  svn propset svn:keywords Id <filename>

摘自:http://blog.sina.com.cn/s/blog_467eb8ca01011vtx.html
转自http://www.cnblogs.com/pulas/archive/2012/06/18/2553239.html
在使用MindManager 2012时,若基于其内置的模板创建一个Map时,则会出现如下的错误,导致软件崩溃,自动结束。
Microsoft Visual C++ Runtime Library
Runtime Error!
R6025 -pure virtual function call
解决方法:http://forum.us.mindjet.com/viewtopic.php?f=45&t=8154
1.Find the Templates Path.(My OS is WIN7,C:\Users\UserName\AppData\Local\Mindjet\MindManager\10\Library\ENU\Templates),Other system you should search for it.
2.Use The MindManager to Open the Template.(..\Management\Balanced Scorecard.mmat)
3.Remove the tip item then save
4.Now Create new by the Template named Balanced Scorecard.mmat, it will be ok
5.Remove and save the others.
最核心的一步就是,要删除模板中的Tip项,这样模板就能正常使用了。

来自有兄弟把上面这些模板都去了的下载包:
http://dl.dbank.com/c0yz8a66av
了解一下:
Url:http://blog.csdn.net/zhangxinrun/article/details/6721495


______________golang中tcp socket粘包问题和处理_______________
粘包产生原因
关于粘包的产生原因网上有很多相关的说明,主要原因就是tcp数据传递模式是流模式,在保持长连接的时候可以进行多次的收和发。如果要深入了解可以看看tcp协议方面的内容。这里推荐下鸟哥的私房菜,讲的非常通俗易懂。
粘包解决办法
主要有两种方法:
1、客户端发送一次就断开连接,需要发送数据的时候再次连接,典型如http。下面用golang演示一下这个过程,确实不会出现粘包问题。
2、包头+数据的格式,根据包头信息读取到需要分析的数据。

http://www.01happy.com/golang-tcp-socket-adhere/
背景:C语言不如PHP语言在字符串处理上有较大的灵活性,如取一个字符串的前N个可以有strncpy,但是如果想取从第N位的后M个字符怎么办?得自己写。
其实有strstr结合memncpy来做这个事情,c指针字符串指针查到某个串后指向哪儿并找到一个位置后,如何拷贝此时指针位置前面的字符串,链接在:http://jackxiang.com/post/7933/

你上传的文件是二进制的,而strstr是字符串处理函数,遇到\0就不会往后继续查找了。strlen也是字符串处理函数。这种情况,拷贝使用memcpy,程序记住拷贝的len,查找需要自己用指针移动实现。
昨天不是说过了么,二进制数据不能使用字符串处理函数
罗毅峰拷贝一个上传具有二进制的包体的相关字符串不用用的拷贝方法:


recvlen就是总长度吧,p = strstr(szTmpBuf,headerSepFlag);//p指向这个\r\n\r\n 的这儿:
后,用p-szTmpBuf 也就是这个http的header长度。
再用recvLen 就是总长度,recvLen-(p-szTmpBuf) 这就是body的长度,
后再用: memcpy(httpBody,p+4,recvLen-(p-szTmpBuf));  就能拷贝进去?
罗毅峰新  10:49:45
yes
szTmpBuf也是指针,指针减指针,得到的是距离长度。szTmpBuf和p都是char *类型
——————————————————————————————————


[root@iZ25dcp92ckZ multepoolserver]# gcc strstr.c  -o strstr
[root@iZ25dcp92ckZ multepoolserver]# ./strstr
p=lobal View
content = bal View

————————————————————————————————————————————————————————————————



[root@iZ25dcp92ckZ multepoolserver]# ./strstr
httpHeader=Golden G
p=lobal View
content = bal View

——————————————————————————————————————————————————————————————

这里学习到获得字符串标识位后面的几位:
加密日志
这篇日志被加密了。请输入密码后查看。
密码
问题:service memcached31211 start 有输出,加上 2>&1就没有输出了,
combine stderr and stdout into the stdout stream,2>&1的意思是将错误输出和标准输出都放前面文件里面:
Starting memcached31211 ...                                [  OK  ]
[ init.d]# vi memcached31211

参考自:https://www.cnblogs.com/happySmily/p/6439959.html

启动文件/etc/init.d/memcached31211下载:


背景:memcache线上环境出现端口还在,但是执行命令就一直柱塞的情况,怎么办?只有打开日志了。运维觉得是:像是进程死了,技术觉得是读写多了,无证据只能是大胆的猜测,得找证据,从下次崩溃的日志里找,呵呵。
memcache在linux上安装时并不支持显示地配置服务日志,我们如果想要把memcache服务日志保存到日志文件中,则需要在启动参数中进行配置。
安装好memcache后,我们可以通过-h命令查看memcached支持的参数:
/usr/local/bin/memcached -h
-v            verbose (print errors/warnings while in event loop)
-vv           very verbose (also print client commands/reponses)

建议在启动memcached时加上日志,
出问题时候从日志上找到蛛丝马迹,
出问题后立即ps看其进程处啥状态:
-vv >> /tmp/memcached.log 2>&1  


加个日志吧,日志注意下到时间清理下:
/usr/local/bin/memcached -d -m 5120  -u root -l  10.70.62.*** -p 11211 -c 2048 -u root -vv >> /tmp/memcached.log 2>&1  
-v            verbose (print errors/warnings while in event loop)
-vv           very verbose (also print client commands/reponses)

从上面可以看到,启动memcached时有3个参数是和日志信息相关的:
其中-v代表打印普通的错误或者警告类型的日志信息
-vv比-v打印的日志更详细,包含了客户端命令和server端的响应信息
-vvv则是最详尽的,甚至包含了内部的状态信息打印

你可以根据你的实际需要来选择对应的参数,我这里使用-vv就OK了。
由于我们需要把日志信息保存在文件中,而不是在控制台输出,而-vv等参数只能把日志信息输出在控制台。所以我们需要对-vv参数的输出进行数据流重定向,关于重定向的知识在这里就不细述了,有兴趣的可以查下资料了解一下。
综上,启动memcached的命令如下:

Shell代码  收藏代码
/usr/local/memcached/bin/memcached -d -m 2048 -p $1 -u root -vv >> /tmp/memcached.log 2>&1  
重点在最后的:-vv >> /tmp/memcached.log 2>&1

-vv >> /tmp/memcached.log:代表把-vv的输出重定向到/tmp/memcached.log 文件中
2>&1的意思是把错误日志也一起写入到该文件中

启动成功后我们可以测试一下,首先起两个terminal,terminal1用来查看日志信息,terminal2进行client操作
terminal1:启动memcached后默认的日志信息如下
Shell代码  收藏代码
[chenzhou@localhost ~]$ tail -f /tmp/memcached.log  
<31 send buffer was 110592, now 268435456  
<30 server listening (udp)  
<31 server listening (udp)  
<30 server listening (udp)  
<31 server listening (udp)  
<30 server listening (udp)  
<30 server listening (udp)  
<31 server listening (udp)  
<31 server listening (udp)  
<32 new auto-negotiating client connection  
terminal2:往memcached里存入一个数据
Shell代码  收藏代码
[root@localhost bin]# telnet localhost 11211  
Trying 127.0.0.1...  
Connected to localhost.localdomain (127.0.0.1).  
Escape character is '^]'.  
set name 0 60 5 chenzhou  
如上所示:使用set命令存入key为name value为chenzhou
terminal1日志记录:
Shell代码  收藏代码
32: Client using the ascii protocol  
<32 set name 0 60 5 chenzhou  
这样,我们的配置就生效了。

摘自:http://chenzhou123520.iteye.com/blog/1925209


关闭memcached的方法:
停止Memcache进程:


ps -ef|grep memcached


干死拉倒,反正就是放内存,不像redis 还搞个bgsave刷盘:


背景:有人对vim+ctag有意见,于是有人就说这个玩意好了。

YouCompleteMe的特别之处
基于语义补全

  总所周知,Vim是一款文本编辑器。也就是说,其最基础的工作就是编辑文本,而不管该文本的内容是什么。在Vim被程序员所使用后,其慢慢的被肩负了与IDE一样的工作,文本自动补全(ie.acp,omnicppcompleter),代码检查(Syntastic)等等工作。

  针对文本自动补全这个功能来说,主要有两种实现方式。

    基于文本

  我们常用的omnicppcompleter,acp,vim自带的c-x, c-n的实现方式就是基于文本。更通俗的说法,其实就是一个字:


  其通过文本进行一些正则表达式的匹配,再根据生成的tags(利用ctags生成)来实现自动补全的效果。

    基于语义

  顾名思义,其是通过分析源文件,经过语法分析以后进行补全。由于对源文件进行分析,基于语义的补全可以做到很精确。但是这显然是vim所不可能支持的。而且经过这么多年发展,由于语法分析有很高的难度,也一直没有合适的工具出现。直到,由apple支持的clang/llvm横空出世。YouCompleteMe也正是在clang/llvm的基础上进行构建的。
整合实现了多种插件

    clang_complete
    AutoComplPop
    Supertab
    neocomplcache
    Syntastic(类似功能,仅仅针对c/c++/obj-c代码)

支持语言

    c
    c++
    obj-c
    c#
    python

  对于其他的语言,会调用vim设置的omnifunc来匹配,因此同样支持php,ruby等语言。

http://jishu.zol.com.cn/228882.html
背景:QQ上一用户拍了一张图片,想把文字粘贴的Word里,得有图片识别软件才行。
汉王OCR图片文字识别:
http://xiazai.zol.com.cn/detail/34/335364.shtml
捷速ocr文字识别软件,这个也还成,识别效果还不错,使用简单,但唯一问题是容易崩溃,可能是内存控制不好吧。
背景:解析Http的get请求时会对\r\n啥的作解析,得对这个get Post作分析。
响应格式:

  下面是通过firebug获取的响应头数据信息:

  响应头信息 原始头信息

  响应格式主要有响应行,响应头,响应体组成 。

  响应行 : 标识服务器端对客户端请求的处理结果,主要由响应状态信息,响应状态码,服务器协议HTTP协议:参考请求头当中对协议的描述。

  响应头: 类似于请求头的key:value形式。如下:

  Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.4; JBoss-4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)/Tomcat-5.5
Content-Type: application/json;charset=GBK
Content-Length: 338
Date: Wed, 12 Sep 2012 07:30:22 GMT

  1. Content-Encoding 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。

  2. Content-Length 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。

  3. Content-Type 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。

  4. Date 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。

  5. Expires 应该在什么时候认为文档已经过期,从而不再缓存它。

  6. Last-Modified 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。

  7. Location 表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。

  8. Refresh 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。

  注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。
注意Refresh的意义是“N秒之后刷新本页面或访问指定页面”,而不是“每隔N秒刷新本页面或访问指定页面”。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV="Refresh" ...>。
注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。
Server 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。
Set-Cookie 设置和页面关联的Cookie。Servlet不应使用response.setHeader("Set-Cookie", ...),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。
WWW-Authenticate 客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。
注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问

  //根据父节点查出子节点 function loadByParentCode(kongjian) { // alert("onchange"+kongjian.name); var kongjianName=""+(parseInt(kongjian.name.charAt(0))+1)+"Catalog"; var url = "/s.do obj=catalogDaoImpl"; var where={}; where["level"]=parseInt(kongjian.name.charAt(0))+1; where["code"]=kongjian.value; sendJsonrpcRequest(url, "POST", "getListBy", {where:where} , null,function(data) { //清除原来的option for(var j=parseInt(kongjian.name.charAt(0))+1;j<=5;j++) { $("#"+j+"Catalog option").remove(); $("#"+j+"Catalog").append("<option value=''$amp;>amp;$lt;/option$amp;>quot;$); } //添加新的option if(kongjian.value != "") bindHtmlSelect("#"+kongjianName,data,"title","code",null); }, null); }

  根据上面的ajax代码:请求的url是:;charset=utf-8&jsonrpcContent=%257B%2522id%2522%253A1%252C%2522method%2522%253A%2522getListBy%2522%252C%2522params%2522%253A%257B%2522where%2522%253A%257B%2522level%2522%253A2%252C%2522code%2522%253A%2522840%2522%257D%257D%252C%2522jsonrpc%2522%253A%25222.0%2522%257D&rnd=0.7714995991861088

  其中:

  obj :catalogDaoImpl 是post的非json参数,在firebug中捕获到的结果是:

  参数:
obj  
  catalogDaoImpl

  而下面是通过URLDecoder编码后的ajax的post参数,在firebug中的捕获到的数据格式如下:

  参数         application/x-www-form-urlencoded
charset   utf-8
jsonrpcContent   %7B%22id%22%3A1%2C%22method%22%3A%22getListBy%22%2C%22params%22%3A%7B%22where%22%3A%7B%22level%22%3A2 %2C%22code%22%3A%22840%22%7D%7D%2C%22jsonrpc%22%3A%222.0%22%7D
rnd   0.7714995991861088

  其组成url请求的源代码是:

  charset=utf-8&jsonrpcContent=%257B%2522id%2522%253A1%252C%2522method%2522%253A%2522getListBy%2522%252C %2522params%2522%253A%257B%2522where%2522%253A%257B%2522level%2522%253A2%252C%2522code%2522%253A%2522840 %2522%257D%257D%252C%2522jsonrpc%2522%253A%25222.0%2522%257D&rnd=0.7714995991861088

  响应请求后的数据包:

  {"id":1,"jsonrpc":"2.0","result":[{"id":521,"title":"kangze111","code":"840596","parentId":0,"parentPath" :"840","sortNumber":0,"level":2,"createTime":1347008939000,"reservedInt":0,"status":0,"comment":"kangze .sl","creator":"kangze.sl","lastUpdateTime":1347008939000,"lastOperator":"kangze.sl","reservedField" :null,"reservedString":null}]}

  二:http请求分析:

  请求头信息的格式(firebug中抓取):

  Host: risk:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:15.0) Gecko/20100101 Firefox/15.0.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer:
Content-Length: 289
Cookie: ArkAppAuthen=Authen|YMVwbcTly2N0KJbDcaGVrn3WYWguBTPkgMZhjPQakiCvFoalWKrYrhLUmNGMJtT1b9/EB2kfvCDecWNBKxSzFPjf+bdYg8oIXg7og8qk78kFspRVQ5+XIKBWrhzYjV5WiJwzBh6QtGm37e8fBNI2kGtqW1TRJPfksgwIFwaSu4Z8u1+NLgLH0vJriGCw8M5oYqe15s/7n9Ifl1k+gVc3oJZqvXU0cL9KZFkebGaL/ZFNgU/QocW85f2P2zrcQ8WEBUyNsqrlqih+AmHzt5lvcTQWI0HuVWu98tBETrdpoH54wTbalb38+tbOLQ4GN/b6tHOcxTcwbma1vOhYLe5yop/RW0S5/hQheNuVRsHC9VD3T3Ra3fbAmy028pHePqUB/IS+/AlnQefqPaGXxO/dN3oFlYSGquVcLBtKfxp8UJBF+gpOYD0/EZzAR89ZeS9kHHT24hxwMsfDz1qNTSTqeA||&Scid|NWZjZTQxYTYtZWRhMy00OTI5LTg1MWYtMjE1MzAwMTJkZjAz&Code|||AM; auth=114966948%3Ayumo.lck%3A*%3A1346064696%3A13a2ec50e821c247f95ef34ac34e899e; JSESSIONID=161252CDF4DE354D0B723C8614106F44
Pragma: no-cache
Cache-Control: no-cache

  一个非常重要的空行分开了请求头与实体,它标志着实体内容的开始。

  一个浏览器中输入url地址。

  2. 网页中的超链接。

  3. 后台代码中通过response.redirect("form表单形式提交

  前三种方式都是以Get方式发起请求。第四种方式可以以Get方式发起请求,也可以以Post方式发起请求,只需要设置<form action="" method="Get/Post"$amp;>amp;$lt;/form>的method属性即可,默认该属性值为Get.
   当客户端发起一个Http请求到服务端时,会传输一个Http请求消息给服务端,标准的Http请求消息格式如下:

  请求行(request-line)——请求行的格式为:请求方式_资源路径_x HTTP/1.1)。

  消息头(headers)——说明服务器要使用的附加信息(ContentType:application/json Content_Length:18 等等其他头信息)。
 回车换行(CRLF)——表明头部信息结束。
 主体数据(request-body)——需要传输到服务端的数据内容,以Post方式请求时才会有该项数据。(username=tom&age=21)
  回车换行(CRLF)——表明主体数据信息结束。
  需要说明的是:
    1.当一个Http请求时Get方式的请求时,请求消息中只有前三项,而没有主体数据。当以Post方式请求时,会包含上述五项信息。
    2.无论是Get请求还是Post请求,请求行中的资源路径必须是application/x-www-form-urlencoded方式编码。Get请求时,浏览器会自动对其进行UrlEncode。Post请求时,浏览器不会自动进行UrlEncode,所有需要手动对资源路径进行UrlEncode。

来自:http://www.educity.cn/wenda/142454.html
背景:主要是遇到编译时要函数返回一个void *,否则会提示:warning: no return statement in function returning non-void,如果去掉这个线程函数的void *里的星号会报错: invalid conversion from ‘void (*)(void*)’ to ‘void* (*)(void*)’ 。

pthread注意事项

注意,pthread_create第三个参数,也就是线程回调函数格式为:
void* fnThreadFun(void* param)
{
  return NULL;//或return ((void *)0);
}
其返回值为void*型指针,如果写成void fnThreadFun(void* param)形式,那么编译会报告:
error: invalid conversion from ‘void (*)(void*)’ to ‘void* (*)(void*)’ [-fpermissive]
错误。
写成:
err = pthread_create(&ntid,NULL,(void*)&fnThreadFun,NULL);
样式似乎也不行,gcc编译时不会出错,但是用g++就会有问题(也会报告上面错误。),究其原因就是C语言编译器允许隐含性的将一个通用指针转换为任意类型的指针,而C++不允许

From:http://www.metsky.com/archives/550.html
一)进程ID:
pid_t 是那一种数据类型:
是Linux下的进程号类型,也就是Process ID _ Type 的缩写。 其实是宏定义的unsigned int类型,
warning: format ‘%u’ expects type ‘unsigned int’, but argument 2 has type ‘pthread_t’:
使用%lu打印pthread_t不会出现警告。

二)线程ID:
编译时如果使用%x打印pthread_t会出现警告信息:
thread-pool.c:77: warning: format ‘%x’ expects type ‘unsigned int’, but argument 3 has type ‘pthread_t’

如果使用%lu打印pthread_t不会出现警告。



如:
问题一,对宏定义的返回数据类型作出一个定义,如下面是对进程数作定义:


问题二:对pid_t进程号用printf打印出现警告:
pid_t p;
pthread_t t;
printf("\nthread id is %lu,procees id is %lu,waiting for into while...\n",t,p);
format ‘%lu’ expects type ‘long unsigned int’, but argument 3 has type ‘pid_t’  
这PID pthread_t打印用啥格式?
: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘pthread_t’
: warning: format ‘%ld’ expects type ‘long int’, but argument 3 has type ‘pid_t’
: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘pthread_t’
如果打印pid_t这种类型,你知道它是整数,但是不知道具体类型,而且在不同平台也可能不同

一般做法是强转下:"%lld", (long long)xxx
或者"%llu", (unsigned long long)xxx
因为C的整数最大就是long long

实践Ok代码如下:



背景:如果nginx代理这个80到swoole(用swoole做webserver,其实就是做个转发和html解析。),这个代理是个什么概念,那这个socket的fd是不是就没法长连接了呢??被反向80端口代理的swoole还能长连接?用:nginx_tcp_proxy_module才行 ,否则肯定不行啊,即使http的keep-alive,https://github.com/yaoweibin/nginx_tcp_proxy_module 也就是说nginx的http代理长连接不行,得走tcp这一层才行,用haproxy。

使用Nginx实现TCP反向代理:https://www.hi-linux.com/posts/65232.html
Nginx 配置TCP代理:https://www.cnyunwei.cc/archives/1315

nginx属于七层架构,支持的是http协议,本身对tcp协议没有支持。所以不能代理mysql等实现负载均衡。但是lvs这个东西不熟悉,主要是公司的的负载均衡都是nginx所以决定研究一下nginx的这个功能实现,下面简单介绍一下实现方法:
阅读全文
分页: 59/339 第一页 上页 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 下页 最后页 [ 显示模式: 摘要 | 列表 ]