近期接了个 网格区域管理 的需求, 具体实现为: 首先建立几个百度地图的坐标点, 其次可以在百度地图上画一个多边形,把需要的坐标点圈在多边形里面。 本文将介绍使用mysql判断点是否在指定多边形区域内的方法,提供完整流程。

创建测试表

1
2
3
4
5
CREATE TABLE `zone` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`polygongeo` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8;

注意:空间索引只能在存储引擎为MYISAM的表中创建(MySQL5.7版本以上可以用Innodb引擎)

插入多边形数据

1
insert into zone(polygongeo) values('POLYGON((1 1,1 5,5 5,5 1,1 1))');

注意:polygongeo包含的点必须是个闭环(第一个点 和 最后一个点必须一致)

判断点是否在多边形区域

测试 POINT(3, 4)

where 查询可以用 MBRWithin 或者 MBRCONTAINS(参数位置交换)

1
select AsText(polygongeo) from zone where MBRWithin(POLYGONFROMTEXT('POINT(3 4)'), GEOMFROMTEXT(polygongeo));

输出: POLYGON((1 1,1 5,5 5,5 1,1 1))
表示点 POINT(3, 4) 在多边形区域内

测试 POINT(6, 1)

1
select AsText(polygongeo) from zone where MBRWithin(POLYGONFROMTEXT('POINT(6 1)'),  GEOMFROMTEXT(polygongeo));

输出: 空
表示点 POINT(6, 1) 在多边形区域外

参考资料

总结:mysql空间查询并不很适合地图坐标,因此查询地图坐标可以使用mongodb实现,参考:《mongodb 判断坐标是否在指定多边形区域内的方法》

高中时语文老师推荐读余秋雨的书,自此欲罢不能,然随着年龄的增长,工作压力和生活琐事日益增多,竟渐渐迷失自己,生活工作的一塌糊涂。 今日又读到此文,心有所悟,特整理到博客,以此自勉。 惟愿有生之年早日达到此高度。

正文

成熟是一种明亮而不刺眼的光辉,一种圆润而不腻耳的音响,一种不再需要对别人察言观色的从容,一种终于停止向周围申诉求告的大气,一种不理会哄闹的微笑,一种洗刷了偏激的淡漠,一种无须声张的厚实,一种能够看得很远却又并不陡峭的高度。

我一直认为,某个时期,某个社会,即使所有的青年人和老年人都中魔了,只要中年人不荒唐,事情就坏不到哪里去。

在中年,青涩的生命之果变得如此丰满,喧闹的青春冲撞沉淀成了雍容华贵,连繁重的社会责任也有可能溶解为日常的生活情态。

到了该自立的年岁还不知道精神上的自立,这是中国很多中年人的共同悲剧。

天天期待着上级的指示、群众的意见、家人的说法,然后才能跨出每一步——这是尚未精神断奶的标志。

最可怕的是,谁也没有断奶,而社会上又没有那么多上好的乳汁,因此开始了对各种伪劣饮料的集体吮吸。在一片响亮而整齐的吮吸声上面,是那些爬满皱纹却还未苍老的脸。

中年人最容易犯的毛病,是把一切希望都寄托于自己的老年。

如今天天节衣缩食、不苟言笑、忍气吞声,都是在争取着一个有尊严、有资财、有自由的老人。

但是,我们无数次看到了,一个窝囊的中年抵达不到一个欢快的老年。这正像江河,一个浑浊的上段不可能带来一个清澈的下段。

习惯了郁闷的,只能继续郁闷;习惯了卑琐的,只能保持卑琐。而且,由于暮色苍茫间的体力不支、友朋散失,郁闷只能更加郁闷,卑琐只能更加卑琐。

只有在中年树起独立的桅杆,扬起高高的白帆唱出响亮的歌声,才会有好风为你鼓劲,群鸥为你引路,找到一个个都在欢迎你的安静港湾,供你细细选择。

中年人的坚守,应该从观点上升到人格,而人格难以言表。在中年人眼前,大批的对峙消解了,早年的对手失踪了,昨天的敌人无恨了,更多的是把老老少少各色人等照顾在自己身边。

请不要小看这“照顾”二字,中年人的魅力至少有一半与此相关。

中年人失去方寸的主要特征是忘记了自己的年龄,一会儿要别人像对待青年那样关爱自己,一会儿又要别人像对待老人那样尊敬自己,明明一个大男人却不能对任何稍稍大一点的问题作出决定,频频找领导倾诉衷肠,出了什么事情又逃得远远的,不敢负一点责任。在家里,他们训斥孩子就像顽童吵架,没有一点身为人父的慈爱和庄重;对妻子,他们也会轻易地倾泻出自己的精神垃圾来酿造痛苦,全然忘却自己是这座好不容易建造起来的情感楼宇的顶梁柱;甚至对年迈的父母,他们也会任性赌气,极不公平地伤害着已经走向衰弱的身影。

西方一位哲人说,只有饱经沧桑的老人才会领悟真正的人生哲理,同样一句话,出自老人之口比出自青年之口厚重百倍。对此,我不能全然苟同。

哲理产生在两种相反力量的周旋之中,因此它更垂青于中年。世上一切杰出的哲学家都在中年完成了他们的思想体系,便是证据。

人生就是这样,年轻时,怨恨自己年轻,年迈时,怨恨自己年迈,这倒常常促使中年处于一种相对冷静的疏离状态和评判状态,然后一边慰抚年幼者,一边慰抚年老者。我想,中年在人生意义上的魅力,就在于这双向疏离和双向慰抚吧。

因双向疏离,他们变得洒脱和沉静;因双向慰抚,他们变得亲切和有力。但是,也正因为此,他们有时又会感到烦心和惆怅,他们还余留着告别天真岁月的伤感,又迟早会产生暮岁将至的预感。他们置身于人生凯旋的中心点,环视四周,思前想后,不能不感慨万千。

老年是如诗的年岁。这种说法不是为了奉承长辈。

中年太实际、太繁忙,在整体上算不得诗。青年时代常常被诗化,但青年时代的诗太多激情而缺少意境,按我的标准,缺少意境就算不得好诗。
只有到了老年,沉重的使命已经卸除,生活的甘苦也已了然,万丈红尘已移到远处,静下来的周际环境和放慢了的生命节奏加在一起,构成了一种总结性、归纳性的轻微和声,诗的意境出现了。

除了极少数命苦的老人,老年岁月总是比较悠闲。老年人可能不会写诗或已经不再写诗,但他们却以诗的方式生存着。看街市忙碌,看后辈来去,看庭花凋零,看春草又绿,而思绪则时断时续、时喜时悲、时真时幻。

当然会产生越来越多的生理障碍,但即便障碍也构成一种让人仰视的形态,就像我们面对枝干斑驳的老树,老树上的枯藤残叶,也会感到诗的存在。
中青年的世界的强悍,也经常需要一些苍老的手来救助。平时不容易见到,一旦有事则及时伸出,救助过后又立即消失,神龙见首不见尾。这是一种早已退出社会主体的隐性文化和柔性文化,隐柔中沉积着岁月的硬度,能使后人一时启悟,如与天人对晤。老年的魅力,理应在这样的高位上偶尔显露。不要驱使,不要强求,不要哄抬,只让它们成为人生的写意笔墨,似淡似浓,似有似无。

长江的流程也像人的一生,在起始阶段总是充满着奇瑰和险峻,到了即将了结一生的晚年,怎么也得走向平缓和实在。

不要因为害怕被别人误会而等待理解。现代生活各自独立、万象共存。东家的柳树矮一点,不必向路人解释本来有长高的可能;西家的槐树高一点,也不必向邻居说明自己并没有独占风水的企图。

做一件新事,大家立即理解,那就不是新事;出一个高招,大家又立即理解,那也不是高招。没有争议的行为,肯定不是创造;没有争议的人物,肯定不是创造者。任何真正的创造都是对原有模式背离,对社会适应的突破,对民众习惯的挑战。如果眼巴巴地指望众人理解,创造的纯粹性必然会大大降低。平庸,正在前面招手。

回想一下,我们一生所做的比较像样的大事,连父母亲也未必能深刻理解。父母虽缔造了我们却理解不了我们,这便是进化。

人生不要光做加法。在人际交往上,经常减肥、排毒,才会轻轻松松地走以后的路。我们周围很多人,实在是被越积越厚的人际关系脂肪层堵塞住了,大家都能听到他们既满足又疲惫的喘息声。

向往峰巅,向往高度,结果峰巅只是一道刚能立足的狭地。不能横行,不能直走,只享一时俯视之乐,怎可长久驻足安坐?上已无路,下又艰难,我感到从未有过的孤独与惶恐。世间真正温煦的美色,都熨帖着大地,潜伏在深谷。君临万物的高度,到头来构成了自我嘲弄。我已看出了它的讥谑,于是急急地来试探下山的陡坡。人生真是艰难,不上高峰发现不了什么,上了高峰又抓住不了什么。看来,注定要不断地上坡下坡,上坡下坡。

你不努力,谁也给不了你想要的生活

近被朋友圈刷屏了,简单的两个聊天记录,拿2000工资与20000工资的有什么区别?不论做什么,走心最重要!

很多时候,我们失败都不是因为“硬件”不行,而是“软实力”欠佳。

若都是刚进公司的新人,大家能力是差不多的,随着时间的推移,情商高的往往都会比情商低的更容易得到赏识或提拔;所以,在技能相对稳定的情况下,我们一定要努力优化自己的处事方法。

机会是留给有准备的人的,要别人推一把你才走一步,那你跟猪又有什么区别。


如图所示:3张图揭示人与人之间的差别!

情景一

普通员工1
普通员工2

情景二

优秀员工

那么问题来了,

你能看出老员工和新员工之间的差别吗?

如果你是老板,你更愿意聘用哪一个?

优秀员工 VS 普通员工

关于刚入职

普通员工 优秀员工
看重工资的高低,在一无所长的前提下,没有想过学习丰富的工作经验和职业技能。 更看重宝贵的工作经验,踏踏实实的去学习业务技能,他相信只要有丰富的经验,以后无论到哪都能赢得高薪。

关于对待问题

普通员工 优秀员工
在工作中会发现各种各样的问题,对于问题他们往往以抱怨的态度去对待,而没有想方法去解决 在工作过程中,碰到问题会冷静的分析原因,并通过各种手段去解决,慢慢培养了一种解决问题的能力。

关于执行力

普通员工 优秀员工
对于上司交代的问题本着能做就做,不能做就慢慢磨,执行效果较差。 上司交代的事情积极去解决,遇到问题会积极与上司沟通请示,执行效果好。

关于个性

普通员工 优秀员工
个性张扬,以自我为中心,不善于处理自己与同事领导的关系,往往给人一种很浮躁的感觉。 为人谦虚低调,能协调好与领导同事的关系,人际关系非常好。

关于下班后

普通员工 优秀员工
下班后往往通过看电视、打打游戏等方式,度过一段休闲时光。 下班后会抽出时间回顾今天一天的工作内容,反思不足之处,并规划好第二天的工作内容。

关于工作重点

普通员工 优秀员工
工作杂乱无章,搞不清楚工作的核心内容,工作往往忙起来手足无措。 能很好的做好工作规划,找准核心工作内容,即使忙起来也能井然有序。

关于客户沟通

普通员工 优秀员工
和客户沟通仅局限于单纯的送货收款,没有考虑到客户的实际需求,往往工作很辛苦,但是成效却很低。 能很好的处理与客户的客情关系,准确的找到客户实际需求,并结合客户需求达成销售。往往事半功倍。

关于视界

普通员工 优秀员工
缺乏宏观思考,经常纠结于某个终端问题,有时为了应对单个终端问题不惜提高政策从而影响了整个市场价格体系。 从市场整体角度出发,能很好的协调好各个渠道之间的市场问题,对于违反市场规律的个别终端坚决予以治理。

关于批评

普通员工 优秀员工
对忠言逆耳理解的不透彻,总认为自己想的是对的,把上司或资深前辈的意见或建议不当一回事,我行我素。 能谦虚的接受批评,认识到自己所犯错误在哪,并积极改正!

关于职业规划

普通员工 优秀员工
没有职业规划,对自己想要什么没概念,能做多久算多久,风风光光是一辈子,窝窝囊囊也是一辈子,得过且过。 有自己的职业规划,知道自己想要什么,也知道如何去努力。

你不努力,谁也给不了你想要的生活

MySQL 使用SELECT … FOR UPDATE 做事务写入前的确认

以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEATABLE READ,在SELECT 的读取锁定主要分为两种方式:

SELECT ... LOCK IN SHARE MODESELECT ... FOR UPDATE

这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commit)后才会执行。而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同一个表单时很容易造成死锁 。

简单的说,如果SELECT 后面若要UPDATE 同一个表单,最好使用SELECT … UPDATE。

举个例子: 假设商品表单products 内有一个存放商品数量的quantity ,在订单成立之前必须先确定quantity 商品数量是否足够(quantity>0) ,然后才把数量更新为1。

不安全的做法:

1
SELECT quantity FROM products WHERE id=3;  
UPDATE products SET quantity = 1 WHERE id=3;

为什么不安全呢?

少量的状况下或许不会有问题,但是大量的数据存取「铁定」会出问题。

如果我们需要在quantity>0 的情况下才能扣库存,假设程序在第一行SELECT 读到的quantity 是2 ,看起来数字没有错,但是当MySQL 正准备要UPDATE 的时候,可能已经有人把库存扣成0 了,但是程序却浑然不知,将错就错的UPDATE 下去了。

因此必须透过的事务机制来确保读取及提交的数据都是正确的。

于是我们在MySQL 就可以这样测试: (注1)

1
SET AUTOCOMMIT=0;  
BEGIN WORK;  
SELECT quantity FROM products WHERE id=3 FOR UPDATE; //此时products 数据中id=3 的数据被锁住(注3),其它事务必须等待此次事务 提交后才能执行  
SELECT * FROM products WHERE id=3 FOR UPDATE;  //(注2) 如此可以确保quantity 在别的事务读到的数字是正确的。  
UPDATE products SET quantity = '1' WHERE id=3;  
COMMIT WORK;

提交(Commit)写入数据库,products 解锁。

注1: BEGIN/COMMIT 为事务的起始及结束点,可使用二个以上的MySQL Command 视窗来交互观察锁定的状况。
注2: 在事务进行当中,只有SELECT … FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT … 则不受此影响。
注3: 由于InnoDB 预设为Row-level Lock,数据列的锁定可参考这篇。
注4: InnoDB 表单尽量不要使用LOCK TABLES 指令,若情非得已要使用,请先看官方对于InnoDB 使用LOCK TABLES 的说明,以免造成系统经常发生死锁。

MySQL SELECT … FOR UPDATE 的Row Lock 与Table Lock

上面介绍过SELECT … FOR UPDATE 的用法,不过锁定(Lock)的数据是判别就得要注意一下了。由于InnoDB 预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。

举个例子:

假设有个表单products ,里面有id 跟name 二个栏位,id 是主键。

例1: (明确指定主键,并且有此数据,row lock)

1
SELECT * FROM products WHERE id='3' FOR UPDATE;

例2: (明确指定主键,若查无此数据,无lock)

1
SELECT * FROM products WHERE id='-1' FOR UPDATE;

例2: (无主键,table lock)

1
SELECT * FROM products WHERE name='Mouse' FOR UPDATE;

例3: (主键不明确,table lock)

1
SELECT * FROM products WHERE id<>'3' FOR UPDATE;

例4: (主键不明确,table lock)

1
SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

注1: FOR UPDATE 仅适用于InnoDB,且必须在事务区块(BEGIN/COMMIT)中才能生效。
注2: 要测试锁定的状况,可以利用MySQL 的Command Mode ,开二个视窗来做测试。

其他

转自 http://www.cnblogs.com/chenwenbiao/archive/2012/06/06/2537508.html

在周鱼的微博上看到他的一段话 你可以追剧追一晚,只要你可以按时交上论文。你可以有丰富的夜生活,只要第二天你还能精神饱满的做好本职工作。放纵究竟是不是错,取决于你能不能为你的放纵负责。还是那句话,没有自制力的人不足以谈人生。

简直一语戳中,微博底下留言的人,无一不在哀嚎:膝盖中箭。

自制力并不是什么新鲜词,说白了就是能够自觉控制自己的行动和情绪,集中注意力去达成自己原本的目标,而不受其他事情的干扰。

可是说起来容易,做起来真是太难了。

对大多数人来说,论文通常都是在deadline来临时,才匆匆忙忙拼凑完成的,而在这之前,是逍遥地看剧打游戏,约会逛街.

工作也是,今天做不完那就明天再做咯,反正工作永远也做不完,但聊天八卦要跟上、剁手购物不能错过秒杀,就连无效的朋友聚餐打着“社交”的旗号也不能不去……

每天冲击我们的信息太多,要做的事情也太多,我们的时间也被分割成碎片,然后被鸡零狗碎所侵占,自制力一点一点丧失。

我们每天好像做了很多事,但为什么最后又好像什么都没做?

每天好像忙得团团转,焦头烂额,但为什么最后还是顾此失彼?

我们立下一堆目标和计划,最后一个也没完成,我们急吼吼地说要多么努力,我们甚至还曾以为自己很努力,原来不过就是看上去很努力而已,最后的结果是,想要做的事,和本应该完成的事,都没有完成。

丧失自制力的后果是让我们对自己愤怒和质疑:我们有什么资格谈努力?

我一个朋友,她的出版资格考试报了三回,可一次也没去,是的,她连考场都没进。

最后她生生从考初级熬到了可以考中级资格(毕业五年可以直接考中级),她无所谓地说:“哎呀,大不了我直接考中级不就得了。”

其实在我看来,她这话无异于自欺欺人,没有个三五年,她中级一样考不下来。

还记得我们一起报名考初级的情景。

她特别豪言壮语地立下学习目标,用多长时间复习《著作权法》,用多长时间学习出版实操知识点……时间规划得特别详细,如实按照这个计划来,备考的时间完全充足,甚至还可以在一轮复习完了后,再进行重点知识二轮复习。

但我们相约一起复习的第一个周末她就缺席了。原因是,她们公司不久后要组织去某著名山庄泡温泉,开季度总结会,她想买一套新的泳衣,顺便去商场逛街,趁着打折买买换季的新衣服。

她打电话邀我作陪,“乔乔,这个礼拜你陪我逛街,下个礼拜我们再开始学习好不好?”

我回她一个微信:“你这个行为就像口口声声喊着要减肥,却大吃大喝一顿,还美其名曰‘没有吃饱怎么有力气减肥呢’?”

让我意外,其实也意料之中的是,第二个周末,第三个周末,她总是有事,最后我只好独自一个人把最初定下的学习计划执行下去。

起初,她还有些负罪感,但次数多了也就轻易地,自我放纵了。

时间好像还有很多,所以眼前的诱惑,相比很久以后的考试来说,总是更有吸引力一些,也更重要一些。甚至,还会偶尔劝诫自己“人生苦短,不如快活”。

到最后,临到考前一个月,她才开始急了,临时抱佛脚各种狂背,可是那些法律条款和实操的内容,真不是一时半会儿就能背下来的。

压力太大,她一焦虑,效率低下,就又没有学习的动力了。最后索性连考场也没去。

是的,自制力差的人,永远都有最后一道护身符:大不了重头再来咯。

第二年,她一个人报考,考前依旧信誓旦旦:“去年没完成的计划,今年誓死也要完成。”

然而,第二年依旧,乃至第三年。

没有自制力的人,往往容易拖延症爆发,总是觉得时间还有,偶尔开个小差做点别的并不影响大局,直到deadline逼近时才乱了阵脚,才意识到自己过高地估计了自己hold住场面的能力。

其实我们没有完成的那些事,并不如我们放弃的那么轻松,它们在我们看来其实很重要,没写完的论文,没做完的工作,没有看完的书,没有认真听的报告,没有背的单词,而我们在开小差的时候,也并不是心无旁骛地快乐,心好像被悬着,我们真的有负罪感,没法好好地玩耍。

真正地有自制力,是一种怎样的体验?
  
学生时期,我们身边都有这样的学霸,他好像从来不用做作业,上课也不是埋头苦做笔记,下了课更不会呆在座位上,他们可以跟学渣一起聊热门的电视剧,讨论流行的八卦,他们……好像真的没有认真地学习,但我们永远不知道的是: 他们在家专注地写作业和复习,一个小时的学习效率顶别人两三个小时。自制力强,所以效率高;自制力强,所以学得快,玩儿得也嗨。
  
毕业后,职场上我们身边也有这样的同事,他们好像上班也跟你一起聊天八卦,也偶尔偷偷淘宝刷微博,做PPT的时候也一样抱怨,赶不出方案时也一样抓狂,可是,和你不同的是,在最后他们好像总是被上天眷顾了一样,ppt做得比你好看,方案创意比你厉害,销售单子拿的比你多……你气不过,暗自嘟囔“他凭什么?”
  
是啊,你刷微博是在看娱乐八卦和搞笑图片,别人是在找创意灵感;你抱怨这不行那不行的时候是在发脾气,别人却是在寻找解决问题的办法;你跟别人闲聊是真的在撩骚,而别人是通过聊天找到对方的销售需求……
  
自制力强的人,永远分得清楚主次,拎得清什么是本职,什么是玩乐。Deadline在没有自制力的人那里,是压力;在有自制力的人那里,是动力。这就是本质的区别。

你是不是也有这样的经历:
  
家里书架上都摆满了你想看的书,可是一两个月前,你兴冲冲翻开的那本,现在还是停留在最初的几页;
  
你下载了背英语单词的App扇贝,你原本是踌躇满志地制订了背考研单词的计划,一天背100个单词,几十天就搞定,可是单词你背了又忘,忘了又背,中间断了N天。
  
你办了健身卡说是要去学游泳,可是别人的健身卡都要续费了,你的健身卡套餐却是在不用就要过期了……
  
为什么开始的开始,我们本来是兴冲冲要去做的事,到后来总是不了了之地烂尾?
  
或许,我们缺乏自制力的原因之一就是,其实你内心深处,就是不在意,不那么想做,所以才会动力缺缺,一直拖延,一旦有什么别的事情干扰,你的专注力就无法维持。
  
而什么是努力?吃喝玩乐睡,用不着努力,这些事是本能,是消遣。
  
称得上努力的事,都是反本能反人性的:为了完成一个课题,你会起早贪黑;为了做那份你最想做的工作,上下班路上四五个小时你也无所谓;为了看完你想看的书,你会放弃参加无效的社交聚会……
  
亦舒曾说过,爱得不够,才借口多多。简直真理,套用过来,你不想做一件事,才会给自己找这样那样的理由。
  
所以,当我们在谈努力的时候,请扪心自问一下,你到底有多想做那件事?到底有多想成功?为了做成那件事,你到底能做到怎样的付出和拼命?
  
因为没有自制力的人是没有资格谈努力的。

前记

如果要我选出大学最应该掌握的一项技能,毫无疑问,一定是做规划的能力。

为什么这么说呢?

我在之前的一篇文章里说过,不要以为进入了大学就可以放松了,大学只是另一条起跑线,而且,比高中要严峻得多。

原因很简单:不同于高中,大学里的一切,完全靠自己的主动性和驱动力。优秀的人,早在大一、大二,就已经清楚自己想要什么,开始集中精力往规划好的方向冲刺了。如果你等到大四才开始行动,其实就已经晚了。

举个栗子,有些朋友想进广告公司,但如果你等到毕业才去投简历,你会发现:广告公司根本不要没有经验的人,尤其是国际4A。那么,你不得不先到其他行业曲线救国,或者干脆放弃这个方向——你看,比起大二、大三就在4A里面实习,毕业后顺利成章留下来的,你比别人晚了多少?

再比如,有个朋友想进咨询行业(真事),结果到了临近毕业,才发现:优秀的咨询公司,不但对专业有着非常狭窄的要求(金融、计算机等),最低学历也是硕士,普通本科连面试的可能都没有,怎么办?如果早几年知道这件事,一早就可以转专业了,再不济,也可以提前准备考个研。

所以,为什么要做好规划?因为,我们人生当中的许多决策和选择,都要点满许多前置技能才会出现。如果你没有事先做好准备,你要么就只能花更多的时间去弥补,要么就只能像所有平庸的人一样,在那些门槛最低的选择中挑选和徘徊。

更进一步的是,很多时候,我们遇到的许多困境,乃至于使我们的人生变得平庸乏味的罪魁祸首,其实,都是因为我们活得太过随意。

比如,我经常收到这样的私信:

  • 「大学学了个不喜欢的专业,一直很抵触,毕业之后也不知道做什么,就这样晃荡了一年,好无奈……」

  • 「是不是我太眼高手低了?一年里换了好几份工作,每一份都待不久,现在很焦虑……」

  • 「我一点都不喜欢现在的工作,但是又没有能力跳出来,每天都很忙,觉得未来的日子好迷茫……」

其实,不满意现状并不可怕,可怕的是我们不知道该往什么方向改变。

这样的后果是什么?就像身在一个巨大的迷宫里,看不见周围的路线,日复一日地活在焦虑和迷茫之中,不断地往左往右试探着迈出步子,到头来却发现兜了一个巨大的圈子。就算能走出去,也是靠着运气,回过头看,更不知道走了多少冤枉路。

所以,每当遇到这种情况,我总会告诉他们,先尽最大的时间和精力,想清楚方向和规划。

在你没有一个清晰的——至少是初步的规划之前,一切的努力都是无意义的。它们只会成为大量的试错成本,成为在迷宫里一次次兜圈子的脚印,徒耗精力。

这篇文章,会结合项目管理的思维,谈谈如何做好人生里面,每一个阶段的规划。

一、愿景:我想成为什么样的人?

讲一个故事吧。

「我在店里吃早餐,看见有个女人跟店主起了争执。好像是店主少放了一颗蛋,她要求退钱,店主不肯。旁边有个女人,估计是她的朋友,一直在劝解。

吵着吵着,那个女人突然坐下,捂住脸,哭了出来。

她朋友吓了一跳,忙不迭地跟她说:不就一个蛋嘛,哭什么,咱们不要就是了。

她抽泣着说,我不是哭这个,我是伤心,为什么我都30多了,却还要为了一个蛋跟别人吵架?这不是我想要的生活。」

尽管作者的笔调多少带着一点促狭和调侃,但却给我留下了非常深刻的印象。

有多少人就像这样,曾对生活怀着各种各样的梦想和憧憬,却被现实一次又一次地迎头棒击,磨蚀锐气,最终成为自己以前最讨厌的那种人?

如果你不希望这样,如果你希望能够自己掌控自己的生活,那么,你可以先问自己这个问题:

10年以后,我想成为一个什么样的人?

你是想成为时尚前沿的焦点,出入时装周、酒会;还是想拥有自己的一间小店,一家工作室,享受充实而快节奏的事业;抑或是成为一名旅行美食撰稿人,天天飞往各地寻觅美食;又或者,是想安稳下来,拥有一间不大的房子,享受恬静的家庭生活?

无须进行过多的思考,相信自己的内心,捕捉住第一时间浮现出来的碎片——可能是一些形容词,一个场景,一种氛围,一些物质——将它们写在纸上,作为主干,然后,填充进必要的脉络、骨架,慢慢完善,直至将这种生活状态勾勒完整。

这个过程可能会花上几天,不要急,尽量遵从自己的内心。尽量写得更具体一些。

然后,准备一本空白的笔记本,打开第一页,将它写上去。

它将成为你往后一切努力的方向和根源。

二、门槛:我该满足什么样的条件?

第一步的结果,只是帮助我们梳理出了自己想达到的生活状态。需要将它明确下来,进行分解,才能落实到后续的行动之中。

请打开笔记本,在第二页尽可能地罗列出你所知道的、达成目标需要满足的条件。

以开一间咖啡店为例,你需要满足的条件,可能是这样的:(未必准确,只是一个参考)

  • 一笔至少30万元的启动资金(视城市和地段而定。包括租金、装修以及前几个月的必要开支等)。

  • 咖啡的相关知识。

  • 店铺运营、资金管理、会计等基本商业知识。

  • 市场营销及推广的基本知识。

  • 平面设计、空间设计的基本知识(店面、LOGO设计和店内布局)。

  • 有竞争优势的媒体资源和人脉关系。

  • 稳定可靠的供货渠道。

  • 大量的成熟案例参考资料。

  • ……

这样一来,你需要做什么,就非常清晰了。「能否在10年内开一家咖啡馆」,就变成「能否在10年内满足这些条件」。

不要急于求成,一开始你列出的条件,可能很不完整、不严谨,慢慢来。有疑问的地方,就去网上搜索资料,去知乎提问,或者请教对这方面比较熟悉的人,对这一页反复修改、增补,直到趋于完善为止。

三、路径:我该如何满足这些条件?

这是整个规划里面最重要的一步。

第二步列出的条件中,每一个问题,都有不同的解决方法。比如:

  • 会计和账目管理是一项非常繁琐的工作,你可以自己来,也可以跟朋友合伙、由他来负责这部分,也可以雇佣一位员工帮你分担;

  • 店面设计、LOGO设计,你可以请朋友帮忙,也可以委托给专业的设计公司;

  • 一开始的启动资金,你可以向家里人求助,可以向银行贷款,也可以自己一步步攒齐

诸如此类。

不同的解决方法,会有不同的要求,要根据你的实际情况来处理。

  • 如果你家境良好,没有太多资金方面的压力,那显然,你就可以挑选一份比较轻松的工作,把省下来的时间和精力,去看市场营销方面的书籍,学习推广和运营知识,甚至到咖啡馆里面打工、积累经验,都可以。

  • 如果你家境一般,打算靠自己攒齐启动资金,那你可能就得选择比较辛苦、加班较多,但收入也相对较高的工作。或者在业余时间接一些外包和私单,平时也多注意开源节流,以攒齐存款为第一优先级。

  • 如果你的朋友里面有管理和财务方面的专业人才,关系也足够好,你就可以把这一块完全交给他,把自己的精力聚集在其他方面。

  • 又或者,如果你打算在推广上面花大力气,那是不是可以选择新媒体相关的行业,积累这方面的经验和人际资源,为将来打好铺垫?

  • ……

翻开笔记本的第三页,把你的这些思考过程,详细地写下来。

  • 我拥有什么样的资源和优势?

  • 我需要聚焦和关注哪些最核心的条件?

  • 我可以采取什么方法解决它们?

仔细思考这些问题,大量地去查找信息,在这个基础上,提炼出一份概要的「计划」,并对它反复进行打磨。

这一步的意义在于,只做那些对长远规划有益的事情。

比如,我在之前的文章里提过,不要把时间浪费在低回报的兼职上。但是,如果你的长远目标是开一家咖啡店,那么到咖啡店里兼职有何不可呢?这个时候,它的回报就不是简单的金钱了,而是成为你整个规划必不可少的一环。

再比如,许多人一到周末,要么睡一天,要么逛街、玩游戏,这样没有什么问题,但是,如果你有一个长远的规划和方案,你是一定不会容忍自己这样的。你会去图书馆看书,会去练习技能,会早起去健身。

因为你清楚地知道,按照你的计划,只有这样,才能离你的梦想更近一步。

四、量化:我要实现什么进度?

为什么有些人制订了计划,却总是得不到落实,有些人却可以一步步朝着计划前进?

很大程度上,是由于计划本身的「有效性」。

什么是有效的计划呢?有一个通用的原则,叫做SMART原则。亦即「具体、可衡量、有可行性、有相关性、有时间期限」

刨去可行性和相关性这两个显而易见的原则(目标必须有可能实现、目标必须与整体规划和其他目标相关),可以看出,最核心的部分,就是「量化」。用一句话来概括就是:我需要在什么时间点,达成什么样的进度?

举个最简单的例子:

  • 「我要写一部小说」就不是一个计划;

  • 「我要在3个月内完成一部60万字的小说,平均每周不少于5000字。」 就是一个初步的计划;

  • 「我要在半年内完成一部小说,前3个月用于构思和准备素材,后3个月专注写作,平均每周不少于5000字,总字数不少于60万字。发布之后,在1个月内获得100个订阅,并且总体评价中好评需要超过60%。」 就是一个很完善的计划了。

同样,「我要学习市场营销知识」只是一句空洞的话,如果要使之成为计划,可以这样设置:

「我要在1年内读完20本市场营销相关的专业书籍;每晚至少读30页书,学习1-3个知识点;每周至少写一篇不少于3000字的学习心得。」

这样,就是一份有效、可执行的计划了。

请在笔记本上,翻开下一页,把确定下来的计划一条条列上去。

如果你有兴趣,可以做一份表格:横轴是每一项计划,纵轴是每一天的日期,再标出相应的进度和时间点。然后,每一天按照计划去「打卡」:今天读了25页书,就写上25;今天背了30个单词,就写上30。诸如此类。让自己对自己的执行情况、进度实现情况都能一目了然。

原则上,计划确立之后,不要频繁地去改动它。所以,一开始制订的时候,要根据实际情况控制好强度,最好设置在「需要付出一定努力就能够达到」的程度。这样才能对自己起到鞭策和激励的作用。

五、反馈:我的规划合理吗?

人毕竟不是全知全能的,不可能一蹴而就。所以,在按照计划执行的时候,做好每一天的记录。试行一段时间之后,再根据这段时间的实际情况,对下一段时间的计划进行调整。

一般来说,1-3个月重新制订一次计划比较常见。以背单词为例,如果第一个月你给自己规定的计划是每天50个单词,1个月之后,你发现没有一天能达到目标,最多也不过30个单词,那么第二个月你就可以将目标设置为30,类似这样。

同样,在实行前文所说的长远规划时,如果你发现规划有误,或者有更好的方式可以满足条件,都可以及时对规划进行修改和调整。

末了,再多说几点。

首先,这是一个思维方式,亦即「规划-列出条件-找出方案-分解量化-反馈检查」。你可以把它应用到生活中的方方面面。比如,10年能不能变成1年、3年、5年,甚至半年?当然都可以。按照你想解决的实际问题来调整就好。

然后,如果你不知道开咖啡店需要多少钱,需要学习什么知识,怎么办?你可以在网上搜索资料,实在找不到的,去问身边的人(或者通过他们去问他们的朋友),去知乎和在行上找专业人士请教,或者,直接找一家咖啡店,跟老板搞好关系,跟他闲聊,都可以。获得信息的方法无穷无尽,不要止步于这个障碍上。

最后,讲个故事,给大家一点信心吧。

我有个朋友,大学的时候,每天回到宿舍就是玩游戏,周末也一直宅着。大四的时候,他去了一家游戏公司实习,做了两个月就辞职了。

「我不喜欢那种环境。」他说。「团队,同事,办公室,每天做的事情,我都不喜欢。太混乱,太low。」

后来呢?他回家休息了两年,学英语,考雅思,两年后,考进英国某排名前五的大学,读了个管理学硕士。回国之后,参加某跨国IT咨询公司的面试,在一片计算机专业的海归硕士和专业人士之中杀出重围,顺利拿到了助理顾问的职位。现在已经是某个team的leader。

种一棵树最好的时间是十年前,其次就是现在。

本文转自知乎专栏https://zhuanlan.zhihu.com/p/21627399

前言

PHP说简单,但是要精通也不是一件简单的事。我们除了会使用之外,还得知道它底层的工作原理。

PHP是一种适用于web开发的动态语言。具体点说,就是一个用C语言实现包含大量组件的软件框架。更狭义点看,可以把它认为是一个强大的UI框架。

了解PHP底层实现的目的是什么?动态语言要像用好首先得了解它,内存管理、框架模型值得我们借鉴,通过扩展开发实现更多更强大的功能,优化我们程序的性能。

PHP的设计理念及特点

  • 多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,当然,随着时代发展,PHP也早已支持多线程模型。
  • 弱类型语言:和C/C++、Java、C#等语言不同,PHP是一门弱类型语言。一个变量的类型并不是一开始就确定不变,运行中才会确定并可能发生隐式或显式的类型转换,这种机制的灵活性在web开发中非常方便、高效,具体会在后面PHP变量中详述。
  • 引擎(Zend)+组件(ext)的模式降低内部耦合。
  • 中间层(sapi)隔绝web server和PHP。
  • 语法简单灵活,没有太多规范。缺点导致风格混杂,但再差的程序员也不会写出太离谱危害全局的程序。

PHP的四层体系

PHP的核心架构如下图:

PHP 核心架构图

从图上可以看出,PHP从下到上是一个4层体系:

  • Zend引擎:Zend整体用纯C实现,是PHP的内核部分,它将PHP代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法、实现了基本的数据结构(如hashtable、oo)、内存分配及管理、提供了相应的api方法供外部调用,是一切的核心,所有的外围功能均围绕Zend实现。
  • Extensions:围绕着Zend引擎,extensions通过组件式的方式提供各种基础服务,我们常见的各种内置函数(如array系列)、标准库等都是通过extension来实现,用户也可以根据需要实现自己的extension以达到功能扩展、性能优化等目的(如贴吧正在使用的PHP中间层、富文本解析就是extension的典型应用)。
  • Sapi:Sapi全称是Server Application Programming Interface,也就是服务端应用编程接口,Sapi通过一系列钩子函数,使得PHP可以和外围交互数据,这是PHP非常优雅和成功的一个设计,通过sapi成功的将PHP本身和上层应用解耦隔离,PHP可以不再考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。
  • 上层应用:这就是我们平时编写的PHP程序,通过不同的sapi方式得到各种各样的应用模式,如通过webserver实现web应用、在命令行下以脚本方式运行等等。

如果PHP是一辆车,那么车的框架就是PHP本身,Zend是车的引擎(发动机),Ext下面的各种组件就是车的轮子,Sapi可以看做是公路,车可以跑在不同类型的公路上,而一次PHP程序的执行就是汽车跑在公路上。因此,我们需要:性能优异的引擎+合适的车轮+正确的跑道。

Sapi

如前所述,Sapi通过通过一系列的接口,使得外部应用可以和PHP交换数据并可以根据不同应用特点实现特定的处理方法,我们常见的一些sapi有:

  • apache2handler:这是以apache作为webserver,采用mod_PHP模式运行时候的处理方式,也是现在应用最广泛的一种。
  • cgi:这是webserver和PHP直接的另一种交互方式,也就是大名鼎鼎的fastcgi协议,在最近今年fastcgi+PHP得到越来越多的应用,也是异步webserver所唯一支持的方式。
  • cli:命令行调用的应用模式

PHP的执行流程&opcode

我们先来看看PHP代码的执行所经过的流程。

opcode

从图上可以看到,PHP实现了一个典型的动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺次执行这些指令完成操作。PHP本身是用C实现的,因此最终调用的也都是C的函数,实际上,我们可以把PHP看做是一个C开发的软件。

PHP的执行的核心是翻译出来的一条一条指令,也即opcode。

Opcode是PHP程序执行的最基本单位。一个opcode由两个参数(op1,op2)、返回值和处理函数组成。PHP程序最终被翻译为一组opcode处理函数的顺序执行。

常见的几个处理函数:

1
2
3
4
5
6
ZEND_ASSIGN_SPEC_CV_CV_HANDLER : 变量分配 ($a=$b
ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER:函数调用
ZEND_CONCAT_SPEC_CV_CV_HANDLER:字符串拼接 $a.$b
ZEND_ADD_SPEC_CV_CONST_HANDLER: 加法运算 $a+2
ZEND_IS_EQUAL_SPEC_CV_CONST:判断相等 $a==1
ZEND_IS_IDENTICAL_SPEC_CV_CONST:判断相等 $a===1

HashTable — 核心数据结构

HashTable是zend的核心数据结构,在PHP里面几乎并用来实现所有常见功能,我们知道的PHP数组即是其典型应用,此外,在zend内部,如函数符号表、全局变量等也都是基于hash table来实现。

PHP的hash table具有如下特点:

  • 支持典型的key->value查询
  • 可以当做数组使用
  • 添加、删除节点是O(1)复杂度
  • key支持混合类型:同时存在关联数组合索引数组
  • Value支持混合类型:array (“string”,2332)
  • 支持线性遍历:如foreach

Zend hash table实现了典型的hash表散列结构,同时通过附加一个双向链表,提供了正向、反向遍历数组的功能。其结构如下图:
hashTable

  • 可以看到,在hash table中既有key->value形式的散列结构,也有双向链表模式,使得它能够非常方便的支持快速查找和线性遍历。
    散列结构:Zend的散列结构是典型的hash表模型,通过链表的方式来解决冲突。需要注意的是zend的hash table是一个自增长的数据结构,当hash表数目满了之后,其本身会动态以2倍的方式扩容并重新元素位置。初始大小均为8。另外,在进行key->value快速查找时候,zend本身还做了一些优化,通过空间换时间的方式加快速度。比如在每个元素中都会用一个变量nKeyLength标识key的长度以作快速判定。
  • 双向链表:Zend hash table通过一个链表结构,实现了元素的线性遍历。理论上,做遍历使用单向链表就够了,之所以使用双向链表,主要目的是为了快速删除,避免遍历。Zend hash table是一种复合型的结构,作为数组使用时,即支持常见的关联数组也能够作为顺序索引数字来使用,甚至允许2者的混合。
  • PHP关联数组:关联数组是典型的hash_table应用。一次查询过程经过如下几步(从代码可以看出,这是一个常见的hash查询过程并增加一些快速判定加速查找。):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    getKeyHashValue h;
    index = n & nTableMask;
    Bucket *p = arBucket[index];
    while (p) {
    if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
    RETURN p->data;
    }
    p=p->next;
    }
    RETURN FALTURE;
  • PHP索引数组:索引数组就是我们常见的数组,通过下标访问。例如 \$arr[0],Zend HashTable内部进行了归一化处理,对于index类型key同样分配了hash值和nKeyLength(为0)。内部成员变量nNextFreeElement就是当前分配到的最大id,每次push后自动加一。正是这种归一化处理,PHP才能够实现关联和非关联的混合。由于push操作的特殊性,索引key在PHP数组中先后顺序并不是通过下标大小来决定,而是由push的先后决定。例如 \$arr[1] = 2; \$arr[2] = 3;对于double类型的key,Zend HashTable会将他当做索引key处理。

PHP变量

PHP是一门弱类型语言,本身不严格区分变量的类型。PHP在变量申明的时候不需要指定类型。PHP在程序运行期间可能进行变量类型的隐示转换。和其他强类型语言一样,程序中也可以进行显示的类型转换。PHP变量可以分为简单类型(int、string、bool)、集合类型(array resource object)和常量(const)。以上所有的变量在底层都是同一种结构 zval。

Zval是zend中另一个非常重要的数据结构,用来标识并实现PHP变量,其数据结构如下:
zval

Zval主要由三部分组成:

  • type:指定了变量所述的类型(整数、字符串、数组等)
  • refcount&is_ref:用来实现引用计数(后面具体介绍)
  • value:核心部分,存储了变量的实际数据

Zvalue是用来保存一个变量的实际数据。因为要存储多种类型,所以zvalue是一个union,也由此实现了弱类型。

PHP变量类型和其实际存储对应关系如下:

1
2
3
4
5
IS_LONG   -> lvalue
IS_DOUBLE -> dvalue
IS_ARRAY -> ht
IS_STRING -> str
IS_RESOURCE -> lvalue

引用计数在内存回收、字符串操作等地方使用非常广泛。PHP中的变量就是引用计数的典型应用。Zval的引用计数通过成员变量is_ref和ref_count实现,通过引用计数,多个变量可以共享同一份数据。避免频繁拷贝带来的大量消耗。

在进行赋值操作时,zend将变量指向相同的zval同时ref_count++,在unset操作时,对应的ref_count-1。只有ref_count减为0时才会真正执行销毁操作。如果是引用赋值,则zend会修改is_ref为1。

PHP变量通过引用计数实现变量共享数据,那如果改变其中一个变量值呢?当试图写入一个变量时,Zend若发现该变量指向的zval被多个变量共享,则为其复制一份ref_count为1的zval,并递减原zval的refcount,这个过程称为“zval分离”。可见,只有在有写操作发生时zend才进行拷贝操作,因此也叫copy-on-write(写时拷贝)

对于引用型变量,其要求和非引用型相反,引用赋值的变量间必须是捆绑的,修改一个变量就修改了所有捆绑变量。

整数、浮点数是PHP中的基础类型之一,也是一个简单型变量。对于整数和浮点数,在zvalue中直接存储对应的值。其类型分别是long和double。

从zvalue结构中可以看出,对于整数类型,和c等强类型语言不同,PHP是不区分int、unsigned int、long、long long等类型的,对它来说,整数只有一种类型也就是long。由此,可以看出,在PHP里面,整数的取值范围是由编译器位数来决定而不是固定不变的。

对于浮点数,类似整数,它也不区分float和double而是统一只有double一种类型。

在PHP中,如果整数范围越界了怎么办?这种情况下会自动转换为double类型,这个一定要小心,很多trick都是由此产生。

和整数一样,字符变量也是PHP中的基础类型和简单型变量。通过zvalue结构可以看出,在PHP中,字符串是由由指向实际数据的指针和长度结构体组成,这点和c++中的string比较类似。由于通过一个实际变量表示长度,和c不同,它的字符串可以是2进制数据(包含\0),同时在PHP中,求字符串长度strlen是O(1)操作。

在新增、修改、追加字符串操作时,PHP都会重新分配内存生成新的字符串。最后,出于安全考虑,PHP在生成一个字符串时末尾仍然会添加\0

常见的字符串拼接方式及速度比较:

假设有如下4个变量:

1
2
3
4
$strA = '123'; 
$strB = '456';
$intA = 123;
$intB = 456;

现在对如下的几种字符串拼接方式做一个比较和说明:

1
2
3
4
5
6
7
8
$res = $strA.$strB$res = “$strA$strB
这种情况下,zend会重新malloc一块内存并进行相应处理,其速度一般
$strA = $strA.$strB
这种是速度最快的,zend会在当前strA基础上直接relloc,避免重复拷贝
$res = $intA.$intB
这种速度较慢,因为需要做隐式的格式转换,实际编写程序中也应该注意尽量避免
$strA = sprintf (“%s%s”,$strA.$strB);
这会是最慢的一种方式,因为sprintf在PHP中并不是一个语言结构,本身对于格式识别和处理就需要耗费比较多时间,另外本身机制也是malloc。不过sprintf的方式最具可读性,实际中可以根据具体情况灵活选择。

PHP的数组通过Zend HashTable来天然实现。

foreach操作如何实现?对一个数组的foreach就是通过遍历hashtable中的双向链表完成。对于索引数组,通过foreach遍历效率比for高很多,省去了key->value的查找。count操作直接调用HashTable->NumOfElements,O(1)操作。对于’123’这样的字符串,zend会转换为其整数形式。\$arr[‘123’]和\$arr[123]是等价的

资源类型变量是PHP中最复杂的一种变量,也是一种复合型结构。

PHP的zval可以表示广泛的数据类型,但是对于自定义的数据类型却很难充分描述。由于没有有效的方式描绘这些复合结构,因此也没有办法对它们使用传统的操作符。要解决这个问题,只需要通过一个本质上任意的标识符(label)引用指针,这种方式被称为资源。

在zval中,对于resource,lval作为指针来使用,直接指向资源所在的地址。Resource可以是任意的复合结构,我们熟悉的mysqli、fsock、memcached等都是资源。

如何使用资源:

  • 注册:对于一个自定义的数据类型,要想将它作为资源。首先需要进行注册,zend会为它分配全局唯一标示。
  • 获取一个资源变量:对于资源,zend维护了一个id->实际数据的hash_tale。对于一个resource,在zval中只记录了它的id。fetch的时候通过id在hash_table中找到具体的值返回。
  • 资源销毁:资源的数据类型是多种多样的。Zend本身没有办法销毁它。因此需要用户在注册资源的时候提供销毁函数。当unset资源时,zend调用相应的函数完成析构。同时从全局资源表中删除它。

资源可以长期驻留,不只是在所有引用它的变量超出作用域之后,甚至是在一个请求结束了并且新的请求产生之后。这些资源称为持久资源,因为它们贯通SAPI的整个生命周期持续存在,除非特意销毁。很多情况下,持久化资源可以在一定程度上提高性能。比如我们常见的mysql_pconnect ,持久化资源通过pemalloc分配内存,这样在请求结束的时候不会释放。 对zend来说,对两者本身并不区分。

PHP中的局部变量和全局变量是如何实现的?对于一个请求,任意时刻PHP都可以看到两个符号表(symbol_table和active_symbol_table),其中前者用来维护全局变量。后者是一个指针,指向当前活动的变量符号表,当程序进入到某个函数中时,zend就会为它分配一个符号表x同时将active_symbol_table指向a。通过这样的方式实现全局、局部变量的区分。

获取变量值:PHP的符号表是通过hash_table实现的,对于每个变量都分配唯一标识,获取的时候根据标识从表中找到相应zval返回。

函数中使用全局变量:在函数中,我们可以通过显式申明global来使用全局变量。在active_symbol_table中创建symbol_table中同名变量的引用,如果symbol_table中没有同名变量则会先创建。

其他

原文转自:http://www.nowamagic.net/librarys/veda/detail/102