真爱至上

一、

在澳大利亚毕业旅行的时候,有段旅途住在同学家。一夜的飞机断断续续只睡了三个半小时,白天又在外面逛了一天,当晚在一家德国餐厅热闹了两小时,到他家时真的是精疲力尽,第一夜没聊啥就睡了。

在同学家的第二夜,聊那些学校的往事聊到半夜一点半。和老同学聊天的话题无非就是那些:以前上学的那些事儿,现在同学的近况以及笑谈当时心里挂念的她。

「你现在还没有女朋友么?」,S问我。

「没有啊。研究生跨了专业还是挺伤的,导师又安排很多的事情,哪有时间去找女朋友」,我回答。

二、

旅途中有一天是澳大利亚乡间自驾游。

车飞速行驶着,车窗外美丽的景色不停地向身后消失。车上放着曾经传遍校园的歌曲,陶喆、周杰伦还有王力宏,边哼唱着歌边闲聊一些对人生的感悟。

「你知道么,上海的结婚率真的超低。有次在同学的动态里面看到,2017年上海的结婚率是中国大陆最低的,比倒数第二低的太多」,我打趣到。

「上海那边的节奏确实太快了,还是这边舒服、自在。大家工作都非常忙碌,通勤的时间都会花上很久,周末有的时候就想休息一下睡睡懒觉。随着年纪的增大,每个人都会形成自己固定的观念以及兴趣圈,再加上飞快的节奏,想遇到自己合适的人太难了」,我接着说到。

「是啊,人到了一定的年纪,想要互相理解真的很难」,S说。

「现在有点后悔的是,小学的时候老妈想让我学门乐器,当时我也懒,又考虑花销挺大最后就没去。老妈当时告诉我,想让我学乐器并不是希望我考级什么的,只是想让我有个高雅点的爱好。人是很孤独的,在遇到烦心事的时候,有个爱好能让自己开心起来会好很多」,我想到了一些往事。

「这个教育理念很超前啊」,S说。

「嗯,我妈是个非常智慧的人」,我笑笑。

「很多华人来了澳洲这边,都说希望自己的孩子不要再像自己小时候那样,拼命的学习,希望他们能够过上快乐的童年。可是,真到了自己孩子上学了,还是各种补习班什么的。这边的贵族学校、国际学校,华人的比例都是很大的」,S分享了一些他过来之后的感受。

「确实,很多观念不是那么容易改变的」,我说。

……

「你看过《真爱至上》这部电影么?」S问我。

「没有啊」,我说。

「这是一部比较老的电影了,我每年圣诞节都会看一遍,推荐你看看」,S说。

……

「这边我的一个朋友在澳洲当地陪,就是国内有来旅游的他当导游。有次一个北京来的女生在这边游玩之后去了悉尼,他们互相聊的也挺开心,他没跟女生说就买了去悉尼的机票,给了那个女生一个surprise,之后他们还真的成了。那个女生当时在北京的工作还很好,过的也是比较体面的生活了。后来来到澳洲,当起了一家餐厅的服务员」,S又分享了一个他来到这边之后的见闻。

「这太不可思议了」,我感叹到。虽然我感觉这个故事非常美妙,但是心里还是觉得,这对情侣的付出都太大了,尤其是这个女生,风险太大也太疯狂了。

三、

《真爱至上》是2003年献给圣诞节的喜剧电影,其中有很多大牌明星,有点像国内的贺岁片。故事的开始分享了一个另人感动的场景——在一个机场,相拥的家庭,情侣以及老友——爱无处不在。

整部电影由很多爱情故事组成:有因为拍AV误打误撞成为情侣的,有爱上好友妻子在圣诞夜表白之后道别的,有作家在另一个国度写作爱上语言不通的女佣的,有首相爱上一个来自贫民窟的服务生的,有丈夫出轨妻子表明立场之后丈夫改过自新的……各种笑料不断,每个故事的设计另人感动并且值得深思,当然也包括那句话,「有时候爱情是没有道理的,不需要任何理由」。

Love actually is all around.

四、

在临走前的最后一个晚上,S带我去一家华人餐厅吃火锅。他说明天我就要走了,在外面游玩也挺劳累,熟悉的饭菜也能多吃点,而且正好带我感受下这边的一个华人街区。

吃完饭,在经过一家店铺的时候,S朝着里面望望。S说,之前跟我提到的那个从北京辞职,因为爱情跑到这边餐馆打工的那个女生,就在这家店。

回到S家,商量了第二天送我去机场的时间之后,我准备去收拾东西。

S走到书架旁,拿了一个蓝色的DVD,坐到我身旁。DVD封面上写着《Love Actually》,我仔细一看中文,《真爱至上》。

「这就是你说的那部电影?」,我问。

「嗯,每年圣诞节我都会看一遍」,他点点头。

我笑笑,知道自己应该去看一遍这部电影了。

浅谈动态规划(二)——进阶题

上一次的动态规划的文章中(浅谈动态规划(一)——从lintcode刷题入门),借助lintcode上两个简单且典型的例子(Triangle和Climbing Stairs),阐述了动态规划的两个特点:1)最优子结构,和2)子问题重叠。这回来讲讲最近做lintcode上的几个难度稍微大一些的题目。这些题目也很符合动态规划的那两个特点。

先来看看第一个题目。

1.Paint Fence(栅栏染色)

题目描述:
There is a fence with n posts, each post can be painted with one of the k colors. You have to paint all the posts such that no more than two adjacent fence posts have the same color. Return the total number of ways you can paint the fence.
Notice: n and k are non-negative integers.

例子:
Given n=3, k=2 return 6

     post 1, post 2, post 3
way1    0      0       1
way2    0      1       0
way3    0      1       1
way4    1      0       0
way5    1      0       1
way6    1      1       0

题目中要求给n个栅栏涂颜色,有k种颜色可以选择,限制条件是最多可以有两个相邻的栅栏颜色相同。

解题思路:
令ways[i]( n = 1, 2, 3, ..., n )表示涂到第i个栅栏时的所有的方法数。这样,题目就符合动态规划的两个特征(参考之前的那篇文章分析),就可以用动态规划求解。那么我们在涂第i个栅栏的时候,有两种涂色方式:1)和第i-1个栅栏的颜色相同;2)和第i-1个栅栏的颜色不同。在1)方式下,因为要保证最多只有两个相邻的栅栏颜色相同,所以第i个栅栏的颜色和第i-2个栅栏的颜色必然是不同的,那么此时有ways[i-2] * (k-1)中填涂的方式。在2)方式下,不需要考虑之前的栅栏的颜色,只要保证和i-1个栅栏颜色不同即可,此时有ways[i-1] * (k-1)中方法。所以有状态转移方程:

ways[i] = ways[i-2] * (k-1) + ways[i-1] * (k-1)

同时发现,每次只要用到相邻的3个栅栏的方法数就可以了,这样可以减少空间的使用。所以代码为:

int numWays(int n, int k) {
	// Write your code here
	if (n == 0 || k == 0)
		return 0;
		
	if (n == 1)
		return k;
	if (n == 2)
		return k * k;
		
	int ways[3] = {0}; // 辅助数组,只使用3个变量即可
	ways[0] = k;
	ways[1] = k * k;
		
	// 动态规划步骤
	for (int i = 2; i < n; i++)
	{
		ways[2] = (k-1) * (ways[0] + ways[1]); // 依据相邻的两个栅栏的填涂方法数来求解第3个栅栏的填涂方法数
		ways[0] = ways[1];
		ways[1] = ways[2];
	}
		
	return ways[2];
}

这道题虽然也是简单的,但是因为限制条件的运用比较巧妙,所以给贴出来了。接下来看看下一题。

2.House Robber(打劫房屋)

题目描述:
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

例子:
Given [3, 8, 4], return 8.

题目要求从n个房屋中找出一些房屋取走里面财产,找到财产最大的总值,限制条件是不能有相邻的房屋同时被偷盗。

这道题虽然是道中等题,不过思路也很清晰,动态规划的两个特征也非常明显。令money[i]( i = 1, 2, ..., n )表示在偷第i个房屋时的最大值,那么在偷第i个房屋时,需要比较的只是money[i-1]和money[i-2] + A[i]值的大小(A[i]是第i个房屋的财产值),因为相邻的两个房屋不可能同时被偷。所以,状态转移方程为:

money[i] = max(money[i-1], money[i-2] + A[i])

同样,我们发现每次比较时,只需要保留最近两次的最大值即可,那么优化后的代码为:

long long houseRobber(vector<int> A) {
	// write your code here
	int n = A.size();

	if (n == 0)
		return 0;
	
	if (n == 1)
		return A[0];
	
	// 辅助数组
	long long money[3] = {0};
	money[0] = 0;
	money[1] = A[0];
	
	// 动态规划步骤
	for (int i = 2; i <= n; i++)
	{
		money[2] = max(A[i-1] + money[0], money[1]);
		money[0] = money[1];
		money[1] = money[2];
	}
	
	return money[2];
}

最后来看第3题。

3.Paint House(房屋染色)

题目描述:
There are a row of n houses, each house can be painted with one of the three colors: red, blue or green. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.

The cost of painting each house with a certain color is represented by a n x 3 cost matrix. For example, costs[0][0] is the cost of painting house 0 with color red; costs[1][2] is the cost of painting house 1 with color green, and so on... Find the minimum cost to paint all houses.

Notice: All costs are positive integers.

例子:

Given costs = [[14,2,11],[11,14,5],[14,3,10]] return 10

house 0 is blue, house 1 is green, house 2 is blue, 2 + 5 + 3 = 10

题目要求给n个房子粉刷颜色,找到最小的费用。粉刷时有3种颜色可供选择,而粉刷不同的颜色的费用是不同的,限制条件是相邻的两个房子的颜色不能相同。这道题目其实和上一道题目有点类似,均为相邻的两个有限制,不过这个在动态规划的时候,比较的是粉刷的不同的颜色。同样的方法,令value[i][j](i = 1, 2, ..., n; j = 1, 2, 3)表示正在粉刷第i个房子的时候颜色为j时的总费用(之前粉刷的位置均保证了费用最小)。为了避免相邻的两个房子粉刷的颜色相同,在粉刷每一层的时候,还要和前一层粉刷的颜色比较。那么在粉刷第i个房屋颜色为j时的状态转移方程为:

value[i][j] = min(costs[i][j] + value[i-1][k]), k = 1, 2, 3; k != j

上式中k是上一层粉刷不同颜色到达最小值时的不同颜色。在粉刷时要保证相邻的两层颜色不相同,所以k != j。

有了状态转移方程,题目的代码就好写了:

int minCost2(vector<vector<int> > &costs)
{
	int n = costs.size();

	if (n == 0)
		return 0;
	
	int i, j, k;
	int temp;
	int minValue = INT_MAX;
			
	for (j = 0; j < 3; j++) 
            if (minValue > costs[0][j])
	        minValue = costs[0][j];
					   
	if (n == 1)
		return minValue;

	vector<vector<int> > value(n, vector<int>(3, INT_MAX)); // 辅助数组,初始化时每个位置均为INT_MAX

	// 动态规划步骤
	for (i = 0; i < n; i++)
	{
		if (i == 0)
		{
			for (j = 0; j < 3; j++)
				value[i][j] = costs[i][j];

			continue;
		}

		// 找出相邻两层不相同时,粉刷不同颜色的最小值
		for (j = 0; j < 3; j++)
		{
			minValue = INT_MAX;
			for (k = 0; k < 3; k++) // 上一层粉刷不同颜色时对应的最小值
			{
				if (k == j) // 跳过相同颜色
					continue;
				// 找出最小值
				temp = costs[i][j] + value[i-1][k];
				if (temp < minValue)
					minValue = temp;
			}
			value[i][j] = minValue;
		}
	}

	// 找出粉刷完最后一个房屋时的最小费用
	minValue = INT_MAX;
	for (j = 0; j < 3; j++) 
            if (minValue > value[n-1][j])
		minValue = value[n-1][j];

	return minValue;
}

同样,代码也可以优化以减少空间消耗,在这里就不再将最后结果贴出来了。

好了,这就是这次的全部内容。这些题目是我在刷lintcode中遇到的动态规划特征比较明显的题目,且比《浅谈动态规划(一)——从lintcode刷题入门》里面的一些题目稍微难点。希望能够给初接触动态规划的童鞋一点参考。

参考资料:
lintcode
1.Paint Fence(栅栏染色)
2.House Robber(打劫房屋)
3.Paint House(房屋染色)

中国机器学习及其应用研讨会参加感受

上周末参加了中国机器学习及其应用研讨会(MLA)。这是我第一次参加学术交流的会议,就我个人感觉,这样的会议还是有必要来看看的。

先介绍一下MLA吧。

MLA一直以来都是本着“学术至上,其余从简”的原则,不征文、不收费,这可能是到场的学者和学生人数那么多的很重要的一个原因吧。当时我手机没电了,在志愿者那边充电,一个家伙聊到他以前参加过一次学术会议,学生打折之后注册费还要1200元。这次不但不收费,提供的免费饮用水都随时可取,服务很周到,整体还是很亲民的。这也使得会议的两天场馆内几乎所有时间都是人头攒动,还有很多人是站着听完会议的。这里是2016年MLA的主页,嘉宾报告时的slides在这个页面

会议的不同session也是挺吸引人的(当然,也可能是因为这是我个人第一次参加学术类workshop的原因)。会议分为Regular Session, Poster Spotlight Session, Industry Session以及Top Conference Review Session。Regular Session是邀请一些机器学习领域内的嘉宾,做主题报告,介绍他们自己研究的一些内容,每人时长为45分钟;Poster SpotLight Session是一些老师和学生,把自己在顶级国际会议上发表的论文的成果拿来交流的环节,形式是"Spotlight + Poster",即报告者在研讨会上做报告,中午会议休息的时间在场馆外展览海报,同时演讲者对参观者的提问进行讲解,每个报告者的时间是150秒;Industry Session是一些工业界的厂商来介绍最近机器学习在工业方面的发展的环节,每个嘉宾15分钟;Top Conference Review Session是邀请嘉宾,介绍一些顶级国际会议的情况,包括回顾最近一次会议和会议往年热门话题以及各个会议录取论文的一些套路、技巧的环节,每个人大约8分钟。

我相信做为学生,报告都会听过很多,所以其中Regular Session和Industry Session大家就不会陌生了,都是请嘉宾做报告,只是时间不同,内容不同。而其中Poster Spotlight Session和Top Conference Review Session可能会很吸引人了(或者说比较吸引我)。前一个环节要求报告人把自己论文的内容浓缩到150秒,这样既需要报告的内容全是重点,而且也要别出心裁设计出一些夺人眼球的内容,这样才能让人印象深刻;后一个环节吸引我的原因是,毕竟每个人的时间、精力有限,不可能什么领域都精通,这个环节恰恰是熟悉不同顶级国际会议将他们的参会经历以及会议重点告诉我们,其一丰富了我们的见闻,其二为那些未曾参加过又想在这些会议上被录取论文的那些学者提供了一定的帮助。

因为这是我第一次参加学术类的会议(虽然是个研讨会),所以会议结束后我思考了一下参加学术会议/研讨会的意义。

我个人感觉,参加类似的会议最起码有以下几种好处:
1.了解如今行业内的发展水平,了解同行的研究状况。
2.遇到志同道合,研究类似课题的人。
3.给自己一些精神上的激励,争取自己以后有机会来做报告分享。

自己刚刚入门深度学习,下面是一些自己在会议上注意到的内容以及思考。毕竟对机器学习没有积累,很多想法不太成熟,所以只分享一些在学术之外的思考:

1.不是所有的问题都是理论快于实践的。第一个报告中,嘉宾提到,当时工业界有些实验做的结果不错,但是没有相应的理论指导,于是请他做相关的理论研究。而且深度学习的很多方法、技术在数学上的证明也没有解决,但是有很多应用确实有了不错的效果。
2.当时一个老师提到,对自己的一些猜想做实验,之后有些论文提及和自己思考类似的东西,感觉自己思路对了。人们总是在做出来之后才说自己的思路是对的,其实大部分都是在试错。
3.有个题目是用数据挖掘的思路来debug。我们知道,程序和机器出现的意义就是要代替人力的,而现在的编程和一些计算机的思路发展还是挺快的,也许不久之后真的能代替人力了,而且以前一个老师也提到,可以用程序生成网页,仅仅需要一些细节的改动就可以成型,说现在自动生成网页的程序都可以代替很多程序员了,想给我们点压力。确实,机器技术发展到了一个巅峰的时候,是否真的会代替大量的人力,那么程序员自身是否会被代替?
4.周志华老师在介绍ACML(Asian Conference on Machine Learning)会议的时候,提到自己在国外和其他外国学者交流的时候,因为中国参加这些顶级国际会议的人数不多,有次被一个老外说中国人只是人多但是没脑子,所以老师当时很生气,于是也想在亚洲举办一个像样的国际会议,于是便促成了ACML。同时在Top Conference Review Session环节各位嘉宾在介绍各个会议参会包括在会议中任职的中国人的数目,也发现确实中国的人数不多(不过这些年都在加速增长),这也显示了在国际会议中,一个国家的影响力是多么重要。
5.工业界和学术界的交流非常重要。据我所知,在美国,有些高校与工业的合作是非常紧密的,尤其是硅谷,很多世界有名的公司都会和高校的学生交流合作。而这次会议请到了一些工业界的嘉宾,也拉近了机器学习领域工业和学术的距离,使得很多参会的学生也近距离的感受到了技术在商业的应用以及商业对技术的影响。
6.在一个工业界嘉宾做报告的时候,一个报告中提到了针对蓝领工人做信用判别来决定是否提供借贷的服务,我感觉这个想法非常不错。信用问题在借贷环节非常重要,但是中国很多地方的信用制度还不够完善;现在蚂蚁花呗、京东白条等等类似的业务如果能够完善,保证我在很好的信用时能够不断增加借贷总额,同时在全国范围还能不需要考虑不同银行,那么还是有不少用处的。

其他收获:

和周志华老师合影,同时请老师在《机器学习》书上给了我赠言。来此晒晒~

MLA16周志华老师合影

windows下MatConvNet深度学习框架的搭建

MatConvNet是Matlab下用于机器视觉的一个工具包,主要应用是CNN网络,当然其他的网络也涉及到了。MatConvNet简洁、高效,可以用于图片分类、分割和人脸识别等等深度学习的功能。具体的可以参见官网的介绍。

在搭建环境的过程中,发现如今网上对其的资源不太多,所以在这做一个总结。以beta22版本为例。

过程分为下面几个步骤:
1.MatConvNet的下载
2.GPU模式的使用
3.测试

1.MatConvNet的下载

在其官网的页面进行下载,解压到适当的位置。

运行其中“matconvnet-1.0-beta22\examples\vggfaces”路径下的cnn_vgg_faces.m文件,会出现下面的结果,那么说明已经可以使用了。在运行前最好把其中要下载的一些内容给放到对应的文件夹下,这样可以节省一点等待的时间。

01

2.GPU模式的使用

官网的这个页面中,提到了搭建GPU的方式。

首先,安装CUDA,在这个页面有下载。记得下载和自己系统以及显卡支持的CUDA。

接下来,要下载cuDNN(The NVIDIA CUDA Deep Neural Network library)。cuDNN是用于GPU加速的一个库函数。在这个页面有下载。

然后把解压好的cuDNN放在合适的文件夹下,建议在MatConvNet下建立local文件夹,同时把cuDNN文件夹中bin文件夹下的cudnn64_5.dll文件复制到matconvnet-1.0-beta22\matlab\mex文件夹下。

最后,在MatConvNet文件夹下建立compileGPU.m文件,其中内容如下。记得把对应的路径给改成自己电脑中的路径。

addpath matlab;

%% with cudnn
vl_compilenn('enableGpu', true, ...
                'cudaRoot', 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0', ...  % CUDA的安装路径
                'cudaMethod', 'nvcc', 'enableCudnn', 'true', ...
                'cudnnRoot', 'E:\postgraduate\project\Machine Learning\Deep Learning\CNN\matconvnet-1.0-beta22\local\cudnn');   % cuDNN的路径

出现下面图片中类似的结果,就代表成功了。

02

4.测试

还是根据官网的这个页面,在命令行窗口输入vl_testnn命令,测试非GPU模式,会出现下面的内容。

04

接下来测试GPU模式,在命令行窗口输入vl_testnn('gpu', true),会有类似上面的内容出现。这就是成功了,GPU模式下的速度提示还是很明显的,一般都会有十倍以上。

06

到此,MatConvNet的安装就结束了。

同时,把我在安装过程中遇到的一个问题的解决方式给写一下。在安装cuDNN的时候,可能会遇到如下的错误“Error using mex nvcc fatal : Unsupported gpu architecture 'compute_21'”,其中21可以为其他不能被10整除的数字。这个时候可以把matconvnet-1.0-beta22\matlab下的vl_compilenn.m文件中的732行的代码中"%s"改为向下取10的整数倍。

比如,原代码为

  cudaArch = ...
      sprintf('-gencode=arch=compute_%s,code=\\\"sm_%s,compute_%s\\\" ', ...
              arch_code, arch_code, arch_code) ;

可以改为

  cudaArch = ...
      sprintf('-gencode=arch=compute_20,code=\\\"sm_20,compute_20\\\" ', ... 
              arch_code, arch_code, arch_code) ;

这样,经常遇到的问题就能解决了。

 

浅谈动态规划(一)——从lintcode刷题入门

动态规划是算法中比较常见的一种分析问题的方式,最近看算法看到这,带着lintcode上面的题目,在这写个总结。

首先从一个lintcode上面简单的题目开始。

Climbing Stairs(爬楼梯)

题目描述:
假设你正在爬楼梯,需要n步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?

样例:
比如n=3,1+1+1=1+2=2+1=3,共有3中不同的方法,所以返回 3。

这是一道非常具有代表性的动态规划的一道问题。

令f[n]记录到达第n阶台阶的方法数。假设你还有最后一步就能到达第n阶台阶,那么最后一步,你可以选择两种方式:1)踏一步以及,2)踏两步。如果是踏一步,那么你要从第n-1阶台阶踏出,此时的方法数是 f[n-1];如果是踏两步,那么你要从第n-2阶台阶出发,此时的方法数是f[n-2]。所以爬到第n级台阶的方法总数有f[n] = f[n-1] + f[n-2]种。状态转移方程:

f[n] = f[n-1] + f[n-2]

这样可以写出解答的递归形式:

int climbStairs(int n) {
	// write your code here
	if (n <= 1)
		return 1;
	else 
		return climbStairs(n-1) + climbStairs(n-2);
}

此时我们发现可以用一个一维数组来记录之前出现的结果,这样可以省去递归中不必要的空间开销:

int climbStairs(int n) {
	// write your code here
	vector<int> f(n+1);

	f[0] = 1;
	f[1] = 1;

	for (int i = 2; i <= n; i++)
		f[i] = f[i-1] + f[i-2];

	return f[n];
}

其实,这个还可以进一步优化,因为每一步都只需要前两个台阶的结果,所以可以用两个变量来代替一维数组。

int climbStairs(int n) {
	// write your code here
	if (n == 1 || n == 0)
		return 1;
	
	int ways1 = 1;
	int ways2 = 1;
	int ways = 0;
	
	int i = 2;
	while (i <= n)
	{
		ways = ways1 + ways2;
		
		ways1 = ways2;
		ways2 = ways;
		
		i++;
	}
	
	return ways;
}

接下来,我们再来看一题。

Triangle(数字三角形)

题目描述:
给定一个数字三角形,找到从顶部到底部的最小路径和。每一步可以移动到下面一行的相邻数字上。

样例
比如,给出下列数字三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

从顶到底部的最小路径和为11 ( 2 + 3 + 5 + 1 = 11)。

分析问题,我们发现可以用二维数组来计算到最底层每个位置的最小路径和,令第i层下标为j的位置上最小路径和为f[i][j]。那么,第i层下标为j位置的值f[i][j],只和i-1层位置j-1下标的最小路径和f[i-1][j-1]以及j位置的最小路径和f[i-1][j]有关。即,f[i][j] = min(f[i-1][j-1],  f[i-1][j])。所以状态转移方程为:

f[i][j] = min(f[i-1][j-1],  f[i-1][j])

同时,发现每次的结果只与上面一层的结果有关,所以省去二维数组,只用一维数组作为辅助。代码为:

int minimumTotal(vector<vector<int> > &triangle) {
	// write your code here
	if (triangle.size() == 0)
		return 0;
		
	vector<int> f(triangle[triangle.size() - 1].size());
	
	// 动态规划过程
	f[0] = triangle[0][0];
	for (int i = 1; i < triangle.size(); i++) 
        { 
                for (int j = triangle.size()-1; j >= 0; j--)
		{
			if (j == 0)
				f[j] = f[j] + triangle[i][j];
			else if (j == triangle[i].size()-1)
				f[j] = f[j-1] + triangle[i][j];
			else
				f[j] = min(f[j-1], f[j]) + triangle[i][j];
		}
	}
	
	// 从辅助数组中找出最小值
	int result;
	result = f[0];
	for (int i = 1; i < f.size(); i++)
		result = min(result, f[i]);
		
	return result;
}

分析这两道题目,发现它们有两个共同的特征:
1.最优子结构:一个问题的最优解包含其子问题的最优解。
2.子问题重叠:一个问题的子问题都是相同的。那么这些子问题可以用同样的方式解决,每次将解决的子问题给记录到表中,在计算之后的问题时查找前面的结果来计算当前问题。这也就是“动态规划”名称的由来了。

在climbing stairs问题中,到达每个位置的方法个数,和之前的所有方法是相关联的。即,到达第n阶台阶的所有的方法个数,同时需要找出第n-1阶台阶的所有的方法以及第n-2阶台阶的所有的方法,以此类推。如果之前的问题找出的不是所有的方法数,那么第n阶台阶找出的结果也不是所有的方法数目。而且,第n阶台阶的求解方式和之前的台阶的求解方式是相同的。

在triangle问题中,每个位置的最小路径和需要知道前一层此位置和下一个位置的最小路径和,如果前一层的结果不是最小路径和,那么此层求出的就不是最小路径和。同样,每层问题的求解方式和之前层问题的求解方式是相同的。

所以,这也就是《算法导论》一书中表述的动态规划的两个特征:
1.最优子结构
2.子问题重叠

参考资料:

1.lintcode
Triangle
Climbing Stairs

2.《算法导论(第三版)》。
第15章动态规划

计算机入门的一点经验和对迷茫的一些分析

最近感觉自己在计算机方面有点入门了,而且恰好前几天和研一的新生聚餐,被问道一些所谓的“经验”方面的问题,所以在这里总结一下在前一个阶段自学计算机的一些尝试,也希望给看到这篇博文的自学计算机方面的人一点参考吧。

首先说明一下,自考研到目前为止,自己看过的书籍(这里所指的看过,是几乎都看完了或者看完至少一大半以上,这样我才能对书做一个评价)。

考研考的是东南大学计算机的自主命题935,科目包括数据结构,计组,操作系统。我用的书是根据统招408来的那三本,即:

同时参考了程杰所作的那本《大话数据结构》,不过当时没敲代码(这点很不对)。当时备考还用过配套的王道的那三本书,就不一一列出了。

复试是C++笔试,用过的书分别是:

之后研一,看过的书分别有:

现在正在开始补数据结构算法方面的内容,看的是《数据结构与算法分析——C语言描述(原书第2版)》

我所经历过的阶段这里也说明一下,如果你也是这些方面的初学者,也许有点参考意义。

  1. 上网搜集资料,查找经验。网上的推荐书籍有一堆,每个方面的书籍都有很多经典之作,比如计算机入门必看CSAPP啦,C语言是K&R啦,C++是《C++Primer》啦,算法必须看《算法导论》啦,SICP绝对是培养编程思维的神书之类的。总之,网上有浩若烟海的经典书籍是必读的。然后,每本书自己都想细读一番。
  2. 自己实践。显然,在本科阶段把上面这些书自己研究一遍还有点可能,但是在研究生这个阶段,有了导师给布置的任务,而且还是初学者,不太可能把这些一一翻阅。于是开始找一条收益较高的方案。网上推荐的是快速入门C++看《Accelerated C++》,我也是从这本书开始重新敲C++代码的。同时快速的翻看了一遍《CSAPP》。
  3. 入门,有了自己的学习方向。这也就是现在了,当然以后的方向可能还有变化,不过确实现在感觉对计算机编程方面自学有了一点感悟了。

如果你也是初学者,我的一些建议是:

  • 看书尽量找国外书籍看,国内的书籍大多数不适合自学。
  • 如果你的基础确实不太多,可以从以下思路考虑:一门编程语言,数据结构和算法,操作系统,计算机网络。当然,这个更多的是针对互联网企业的后台开发岗位吧,确实我对前端和APP开发不了解。
  • 每个方向的书籍两本就好,一般书籍的侧重可能不同,交叉着看能帮助理解。如果书籍太多的话,可能就会脱离自己上机实践了。前期你不可能看完那么多书的。经典书后面的课后习题,尽量做。
  • 编程语言和算法互相学习可能效果更好一点。比如看数据结构的时候用编程语言自己实现一遍,多用一些编程语言的一些知识要点。同时,看到数据结构,算法的时候,可以考虑到lintcode上面刷刷类似的题目。
  • 从网上大神的反馈和校招的情况看,编程能力、算法等基础很重要。

推荐的书籍以及考虑的参考顺序:

编程语言方面,因为我是看的C/C++,所以对JAVA不太懂,不过熟悉哪门语言都是要大量的敲代码,而不仅仅是看书。下面C/C++如果没时间就先看C++吧。看C的话主要是关注指针那块。

  1. 《C程序设计语言(第2版)》K&R那本
  2. 《C和指针》。上面那本书讲的太精炼了,参照这本书可以对C有一个了解
  3. 《Accelerated C++》。这本书最大的好处是把C++很多常用的语法和STL的一些用法给呈现出来了,而不像普通的C++书籍那样按部就班罗列知识点。
  4. 《C++大学教程》。和上面那本书对照着看。

再强调一遍,编程语言练习也就是自己多敲代码才是重要的,不要抱着书看完一遍又看一遍。

数据结构和算法:

  1. 《大话数据结构》,程杰。入门算是不错的书了,有C的代码,自己敲过一遍理解更深。
  2. 《数据结构与算法分析——C语言描述(原书第2版)》。我选这本书是因为它比较薄,上来直接啃《算法导论》我个人感觉有点太难了。

计算机基础书籍:

  1. 《深入理解计算机系统》。这本书入门计算机绝对没问题,包括了操作系统,汇编,硬件,还有网络的一些简单的东西,现在既然硬件那块需求不大,可以暂时不看吧。

我这条路在入门上面绝对能走通,不过每个人选择的书籍可能不同,也不用都照着来。方向大抵如此,同时,给出一个我看过的较全的书单:《程序员必读书单 1.0》。同样,这个书单也是仅作参考,前期你不可能都掌握的。别贪全,前期要把那些常常出现的问题给解决。

同时,再把自己所说的“入门”给定义或者说明一下,给你一个参照,以防你也是初学,而我又太low,把你带坑里。

之前,我敲代码时出错了是照着书上给的代码改自己的代码。有些确实是不懂,有些是感觉进度确实不能太慢,不然容易陷入细节的思考,还有就是时间拉太长了可能会学了后面的忘了前面的。现在,敲代码会自己设置断点改错,能够明白一些C语言的指针方面错误所在了。

简单的说就是:之前是被动输入,现在能主动输入了。即,把一些从前学过的C++、数据结构的知识进行组合,实现一些自己想到的功能,并且改错的时候能想通一些指针的特性了。这样融合起来学习,能够更好的理解书上的知识。

所以我感觉自己入门了。

我博客中前两篇文章的内容是二叉树的实现,本来其实感觉太简单不想贴出来的,不过想想可以给这篇文章做个铺垫。不信你可以对照着看一下,把《二叉树的实现以及相关操作C/C++》中的代码改写成《二叉树类的实现》中的类,就会遇到很多难题。我自己写的时候想避开《C++大学教程》上的一些方式,不过最后还是没避开,用其他方式我实现不了。当然,也许你写的代码会比我的更简洁。

同样,这里给出一个我看过的不错的入门建议,可以参考:如何从只会 C++ 语法的水平到达完成项目编写软件的水平?。我有空也会尝试的。

最后想到昨天有几个新生说迷茫,正好我也借这篇文章谈谈这个话题吧。

迷茫很正常。研一的新生可能因为刚刚开学,环境变了,同时看到以前的同学或者现在这个行业工作的人们工资很高,而自己能力不足,对未来有点担心。同时,可能是有了导师的直接管理而且感觉导师分配的任务和自己想要尝试的事情不太有交集。简单地说,其实迷茫就是对未来或多或少的担忧。

未来谁知道呢?对吧。没发生的总是没发生,谁也不能说自己的努力方向一定正确,自己的愿景一定实现。

仔细观察我们可以发现,除了大学之前我们没有过太多的迷茫感,在高考填志愿那时开始,很多人多少都会对未来有些迷茫了。因为在那之前,我们更多是在既定的轨道被动进行教育的。我们在规定的时间上课,规定的时间放学,规定的时间完成作业,每隔一段时间会被排名,从而评估你的成绩。更重要的是,那个时候我们不用直接为自己的行为负责,因为父母会给我们埋单。大学之后,我们要进行更多的选择,对自己的行为负责。同时,评估人的标准渐渐变得不那么单一了:有的人社团混的很好,人际交往让人羡慕;有的人会玩乐器,乐队在自己学校小有名气;有的人竞赛屡获佳绩,让人自愧不如。这些都会使我们努力的方向迷失,从而感觉迷茫。

现在,可能你迷茫的是一些学习方法。未来,你可能还会迷茫自己的择业,孩子的学校选择,不同城市到底安家到哪,等等。

那么在迷茫的时候,该做些什么呢?

  1. 上网搜集你所想要努力方向的资料,查找经验。
  2. 进行实践。
  3. 将自己的实践和努力的成果进行分析,修正。
  4. 重复进行2,3步。

然后,你也会找到自己的方向的。所以我在开始将我努力的过程给描述了一遍。

这里再分享一个经验:迷茫的最大敌人是拖延。

相信聪明的你,能更快地找到属于自己的那条道路。

二叉树类的实现

最近看数据结构看到二叉树的时候,自己实现了一下,同时写成了类,正好复习一下以前看C++的一些知识。代码如下。

// BiTNode.h
// 参照《c++大学教程》中P639页编写
// 模版结点BiTNode类的声明

#ifndef BITNODE_H
#define BITNODE_H

// 声明BiNTree类型
template<typename NODETYPE> class BiTree;

template<typename NODETYPE>
class BiTNode
{
	// 声明友元BiNTree类,使得BiTree类可以访问BiTNode类中的private成员
	friend class BiTree<NODETYPE>;

public:
	BiTNode(const NODETYPE &d) 
		: lchild(0), 
			data(d),
			rchild(0)
	{
	}

	NODETYPE getData() const
	{
		return data;
	}

private:
	BiTNode<NODETYPE> *lchild;
	NODETYPE data;
	BiTNode<NODETYPE> *rchild;
};

#endif
// BiTree.h
// 链表二叉树类模版的定义

#ifndef BITREE_H
#define BITREE_H

#include <iostream>
#include <iomanip>
#include "BiTNode.h"
#include <queue>
#include <stack>
using namespace std;

typedef int Status;

#define OK	1
#define ERROR	0
#define TRUE	1
#define FALSE	0

template<typename NODETYPE>
class BiTree
{
public:
	BiTree();

	void CreateBiTree();
	void DestroyBiTree();
	Status BiTreeEmpty();
	NODETYPE Root();

	int BiTreeDepth();
	int BiTreeDepthNonRecursion();

	void PreOrderTraverse();
	void PreOrderNonRecursion();
	void InOrderTraverse();
	void InOrderNonRecursion();
	void PostOrderTraverse();
	void PostOrderNonRecursion();
	void LevelOrderTraverse();

	void PrintLast();
	void PrintByDepth();

private:
	BiTNode<NODETYPE> *rootPtr;

	// utility function
	void visit(BiTNode<NODETYPE> *p);
	void CreateBiTreeHelper(BiTNode<NODETYPE> **T);
	void DestroyBiTreeHelper(BiTNode<NODETYPE> **T);
	int BiTreeDepthHelper(BiTNode<NODETYPE> *T);

	// 用helper函数的原因是对二叉树进行遍历要传入参数
	void PreOrderTraverseHelper(BiTNode<NODETYPE> *T);
	void InOrderTraverseHelper(BiTNode<NODETYPE> *T);
	void PostOrderTraverseHelper(BiTNode<NODETYPE> *T);
};

template<typename NODETYPE>
BiTree<NODETYPE>::BiTree()
{
	rootPtr = 0;
}

template<typename NODETYPE>
Status BiTree<NODETYPE>::BiTreeEmpty()
{
	if (rootPtr)
		return FALSE;
	else
		return TRUE;
}

template<typename NODETYPE>
void BiTree<NODETYPE>::CreateBiTree()
{
	CreateBiTreeHelper(&rootPtr);
}

// 按前序输入二叉树中结点的值(一个字符)
// #表示空树,构造二叉链表表示二叉树T。
template<typename NODETYPE>
void BiTree<NODETYPE>::CreateBiTreeHelper(BiTNode<NODETYPE> **T)
{
	NODETYPE val;

	cin >> val;

	if (val == '#')
		*T = NULL;
	else
	{
		*T = new BiTNode<NODETYPE>(val);
		CreateBiTreeHelper(&(*T)->lchild);
		CreateBiTreeHelper(&(*T)->rchild);
	}
}

template<typename NODETYPE>
void BiTree<NODETYPE>::DestroyBiTree()
{
	DestroyBiTreeHelper(&rootPtr);
}

template<typename NODETYPE>
void BiTree<NODETYPE>::DestroyBiTreeHelper(BiTNode<NODETYPE> **T)
{
	if (*T)
	{
		if ((*T)->lchild)
			DestroyBiTreeHelper(&(*T)->lchild);
		if ((*T)->rchild)
			DestroyBiTreeHelper(&(*T)->rchild);
		free(*T);
		*T = NULL;
	}
}

template<typename NODETYPE>
int BiTree<NODETYPE>::BiTreeDepth()
{
	return BiTreeDepthHelper(rootPtr);
}

template<typename NODETYPE>
int BiTree<NODETYPE>::BiTreeDepthHelper(BiTNode<NODETYPE> *T)
{
	int i, j;

	if (!T)
		return 0;

	if (T->lchild)
		i = BiTreeDepthHelper(T->lchild);
	else 
		i = 0;
	if (T->rchild)
		j = BiTreeDepthHelper(T->rchild);
	else
		j = 0;

	return i > j ? i+1 : j+1;
}

template<typename NODETYPE>
NODETYPE BiTree<NODETYPE>::Root()
{
	if (!rootPtr)
		return ' ';
	else
		return rootPtr->data;
}

// 借用层次遍历的思想,实现非递归形式求出二叉树深度
template<typename NODETYPE>
int BiTree<NODETYPE>::BiTreeDepthNonRecursion()
{
	if (!rootPtr)
		return 0;

	BiTNode<NODETYPE> *p; // 工作指针,每次记录从队列队首弹出的结点
	BiTNode<NODETYPE> *back; // 记录每层二叉树的最右边的结点。此结点在每次遍历一层之后的队列队尾
	int level = 0; // 层数,初始值为0
	queue<BiTNode<NODETYPE> *> Q;

	Q.push(rootPtr);
	back = Q.back();
	while (!Q.empty())
	{
		p = Q.front();
		Q.pop();

		if (p->lchild)
			Q.push(p->lchild);
		if (p->rchild)
			Q.push(p->rchild);

		if (p == back) // 如果p == 每层的最右边的结点,则层数+1,同时重新赋值队尾结点
		{
			level++;
			if (!Q.empty()) // 如果队列为空,则下一步的操作出错。主要用于防止最后一个结点弹出队列之后的那次操作
				back = Q.back();
		}
	}

	return level;
}

template<typename NODETYPE>
void BiTree<NODETYPE>::PreOrderTraverse()
{
	PreOrderTraverseHelper(rootPtr);
}

template<typename NODETYPE>
void BiTree<NODETYPE>::PreOrderTraverseHelper(BiTNode<NODETYPE> *T)
{
	if (!T)
		return;

	visit(T);
	PreOrderTraverseHelper(T->lchild);
	PreOrderTraverseHelper(T->rchild);
}

// 前序遍历非递归形式
template<typename NODETYPE>
void BiTree<NODETYPE>::PreOrderNonRecursion()
{
	if (!rootPtr)
		return;

	BiTNode<NODETYPE> *p;
	stack<BiTNode<NODETYPE> *> S; // 借助栈实现非递归的前序遍历

	p = rootPtr;
	while (p || !S.empty())
	{
		while (p) 
		{
			visit(p); // 在每次入栈之前进行访问
			S.push(p);
			p = p->lchild;
		}
		if (!S.empty())
		{
			p = S.top();
			S.pop();
			p = p->rchild;
		}
	}
}

template<typename NODETYPE>
void BiTree<NODETYPE>::InOrderTraverse()
{
	InOrderTraverseHelper(rootPtr);
}

template<typename NODETYPE>
void BiTree<NODETYPE>::InOrderTraverseHelper(BiTNode<NODETYPE> *T)
{
	if (!T)
		return;

	InOrderTraverseHelper(T->lchild);
	visit(T);
	InOrderTraverseHelper(T->rchild);
}

template<typename NODETYPE>
void BiTree<NODETYPE>::InOrderNonRecursion()
{
	if (!rootPtr)
		return;

	BiTNode<NODETYPE> *p;
	stack<BiTNode<NODETYPE> *> S;

	p = rootPtr;
	while (p || !S.empty())
	{
		while (p)
		{
			S.push(p);
			p = p->lchild;
		}
		if (!S.empty())
		{
			p = S.top();
			S.pop();
			visit(p); // 在每次出栈之时进行访问
			p = p->rchild;
		}
	}
}

template<typename NODETYPE>
void BiTree<NODETYPE>::PostOrderTraverse()
{
	PostOrderTraverseHelper(rootPtr);
}

template<typename NODETYPE>
void BiTree<NODETYPE>::PostOrderTraverseHelper(BiTNode<NODETYPE> *T)
{
	if (!T)
		return;

	PostOrderTraverseHelper(T->lchild);
	PostOrderTraverseHelper(T->rchild);
	visit(T);
}

template<typename NODETYPE>
void BiTree<NODETYPE>::PostOrderNonRecursion()
{
	if (!rootPtr)
		return;

	BiTNode<NODETYPE> *p;
	BiTNode<NODETYPE> *r; // 用于记录栈中弹出的结点的右子树是否访问过
	stack<BiTNode<NODETYPE> *> S;

	p = rootPtr;
	r = NULL;
	while (p || !S.empty())
	{
		while (p)
		{
			S.push(p);
			p = p->lchild;
		}
		if (!S.empty())
		{
			p = S.top();
			if (p->rchild && p->rchild != r) // 此结点的右子树尚未入栈
			{
				p = p->rchild;
				S.push(p);
				p = p->lchild;
			}
			else
			{
				S.pop();
				visit(p); // 每次出栈时访问结点
				r = p;
				p = NULL;
			}
		}
	}

}

template<typename NODETYPE>
void BiTree<NODETYPE>::LevelOrderTraverse()
{
	if (!rootPtr)
		return;

	BiTNode<NODETYPE> *p;
	BiTNode<NODETYPE> *back; // 操作中记录队列尾部的指针
	queue<BiTNode<NODETYPE> *> Q; // 使用辅助队列

	Q.push(rootPtr);
	back = Q.back();
	while (!Q.empty())
	{
		p = Q.front();
		Q.pop();
		visit(p);

		if (p->lchild)
			Q.push(p->lchild);
		if (p->rchild)
			Q.push(p->rchild);
	}
}

template<typename NODETYPE>
void BiTree<NODETYPE>::PrintLast()
{
	if (!rootPtr)
		return;

	BiTNode<NODETYPE> *p;
	BiTNode<NODETYPE> *back; // 操作中记录队列尾部的指针
	queue<BiTNode<NODETYPE> *> Q; // 使用辅助队列

	Q.push(rootPtr);
	back = Q.back();
	while (!Q.empty())
	{
		p = Q.front();
		Q.pop();

		if (p->lchild)
			Q.push(p->lchild);
		if (p->rchild)
			Q.push(p->rchild);

		if (p == back)
		{
			visit(p);
			if (!Q.empty())
				back = Q.back(); // 更新back指针的位置
		}
	}
}

template<typename NODETYPE>
void BiTree<NODETYPE>::PrintByDepth()
{
	if (!rootPtr)
		return;

	BiTNode<NODETYPE> *p;
	BiTNode<NODETYPE> *back; // 操作中记录队列尾部的指针
	queue<BiTNode<NODETYPE> *> Q; // 使用辅助队列

	Q.push(rootPtr);
	back = Q.back();
	while (!Q.empty())
	{
		p = Q.front();
		Q.pop();
		visit(p);

		if (p->lchild)
			Q.push(p->lchild);
		if (p->rchild)
			Q.push(p->rchild);

		if (p == back)
		{
			cout << endl;
			if (!Q.empty())
				back = Q.back(); // 更新back指针的位置
		}
	}
}

template<typename NODETYPE>
void BiTree<NODETYPE>::visit(BiTNode<NODETYPE> *p)
{
	cout << left << setw(5) << p->data;
}

#endif

为了省事,main函数有些代码直接使用了前面一篇文章里面c的代码。

// main.h
#include <iostream>
#include "BiTree.h"
using namespace std;

int main()
{
	int i;
	BiTree<char> T;
	char e1;
	
	//StrAssign(str,"ABDH#K###E##CFI###G#J##");

	T.CreateBiTree();

	printf("构造空二叉树后,树空否?%d(1:是 0:否) 树的深度: %d\n",T.BiTreeEmpty(), T.BiTreeDepthNonRecursion());
	e1 = T.Root();
	printf("二叉树的根为: %c\n",e1);

	printf("\n前序遍历二叉树:\n");
	//T.PreOrderTraverse();
	T.PreOrderNonRecursion();

	printf("\n中序遍历二叉树:\n");
	T.InOrderTraverse();
	//T.InOrderNonRecursion();

	printf("\n后序遍历二叉树:\n");
	//T.PostOrderTraverse();
	T.PostOrderNonRecursion();

	printf("\n层次遍历二叉树:\n");
	T.LevelOrderTraverse();

	printf("\n每行二叉树的最右边的结点为:\n");
	T.PrintLast();

	printf("\n按层次输出每行的结点:\n");
	T.PrintByDepth();

	T.DestroyBiTree();
	printf("\n清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",T.BiTreeEmpty(),T.BiTreeDepth());
	i = T.Root();
	if(!i)
		printf("树空,无根\n");

	getchar();
	getchar();
	return 0;
}

写这个代码的时候,感觉自己计算机编程入门了——之前写代码主要都是照着书写,出错了更多都是照着书查找错误。写这个二叉树类的时候有个地方指针出错了,自己设断点改错,改了很久。所以入门的一些经验在下面一篇文章里面谈谈吧。

参考资料:
1.《大话数据结构》
2.《C++大学教程(第七版)》

二叉树的实现以及相关操作C/C++

夏天看机器学习之余,把C语言给过了一遍,现在开始数据结构的学习了。最近看的二叉树,照着书实现了一下。

其中包括二叉树的一些基本操作:初始化,建立,销毁,判空,深度和几种遍历。因为书上没给出非递归的遍历的非递归形式,自己这边给总结一下。代码本来是用C写的,但是其中有些功能的实现需要用到队列或者栈,直接调用C++的STL了。如下是相关代码。



#include "string.h"
#include "stdio.h"    
#include "stdlib.h"   
#include "math.h"  
#include <queue>
#include <stack>
using namespace std;

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 100 /* 存储空间初始分配量 */

typedef int Status;

typedef char TElemType;
TElemType Nil = ' ';

/* 用于构造二叉树********************************** */
int index=1;
typedef char String[24]; /*  0号单元存放串的长度 */
String str;

Status StrAssign(String T,char *chars)
{ 
	int i;
	if(strlen(chars)>MAXSIZE)
		return ERROR;
	else
	{
		T[0]=strlen(chars);
		for(i=1;i<=T[0];i++)
			T[i]=*(chars+i-1);
		return OK;
	}
}
/* ************************************************ */

typedef struct BiTNode
{
	TElemType data;
	struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

Status InitBiTree(BiTree *T);
void CreateBiTree(BiTree *T);
void DestroyBiTree(BiTree *T);
Status BiTreeEmpty(BiTree T);
TElemType Root(BiTree T);
TElemType Value(BiTree p);
void visit(BiTree T);

int BiTreeDepth(BiTree T);
int BiTreeDepthNonRecursion(BiTree T);
int BiTreeDepthNonRecursion2(BiTree T);

void PreOrderTraverse(BiTree T);
void PreOrderNonRecursion(BiTree T);
void InOrderTraverse(BiTree T);
void InOrderNonRecursion(BiTree T);
void PostOrderTraverse(BiTree T);
void PostOrderNonRecurion(BiTree T);
void LevelOrderTraverse(BiTree T);

void PrintLastInEachLevel(BiTree T);
void PrintLevelOrderByLevel(BiTree T);

int main()
{
	int i;
	BiTree T;
	TElemType e1;
	InitBiTree(&T);
	
	//StrAssign(str,"ABDH#K###E##CFI###G#J##");

	CreateBiTree(&T);

	printf("构造空二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepthNonRecursion2(T));
	e1=Root(T);
	printf("二叉树的根为: %c\n",e1);

	printf("\n前序遍历二叉树:\n");
	PreOrderTraverse(T);
	//PreOrderNonRecursion(T);

	printf("\n中序遍历二叉树:\n");
	InOrderTraverse(T);
	//InOrderNonRecursion(T);

	printf("\n后序遍历二叉树:\n");
	PostOrderTraverse(T);
	//PostOrderNonRecurion(T);

	printf("\n层次遍历二叉树:\n");
	//LevelOrderTraverse(T);
	PrintLevelOrderByLevel(T);
	printf("\n输出每层的最后一个结点:\n");
	PrintLastInEachLevel(T);
	
	DestroyBiTree(&T);
	printf("\n清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
	i=Root(T);
	if(!i)
		printf("树空,无根\n");
	
	getchar();
	getchar();
	return 0;
}

//* 构造空二叉树T */
Status InitBiTree(BiTree *T)
{
	*T = NULL;
	return OK;
}

// 按前序输入二叉树中结点的值(一个字符)
// #表示空树,构造二叉链表表示二叉树T。 
void CreateBiTree(BiTree *T)
{
	TElemType ch;

	scanf("%c", &ch);

	if (ch == '#')
		(*T) = NULL;
	else
	{
		*T = (BiTree)malloc(sizeof(BiTNode));
		if (!*T)
			exit(OVERFLOW);
		(*T)->data = ch;
		CreateBiTree(&(*T)->lchild);
		CreateBiTree(&(*T)->rchild);
	}
}

// 初始条件: 二叉树T存在。操作结果: 销毁二叉树T 
void DestroyBiTree(BiTree *T)
{
	if (*T)
	{
		if ((*T)->lchild)
			DestroyBiTree(&(*T)->lchild);
		if ((*T)->rchild)
			DestroyBiTree(&(*T)->rchild);
		free(*T);
		*T = NULL;
	}
}

// 初始条件:二叉树存在
// 操作结果:若T为空,则返回TRUE;否则返回FALSE
Status BiTreeEmpty(BiTree T)
{
	if (!T)
		return TRUE;
	else
		return FALSE;
}

// 初始条件:二叉树存在
// 操作结果:返回T的根
TElemType Root(BiTree T)
{
	if (!T)
		return Nil;
	else
		return T->data;
}

// 初始条件:节点存在
// 操作结果:输出结点的数据域
void visit(BiTNode *p)
{
	if (p)
		printf("%c ", p->data);
}

// 初始条件:二叉树存在
// 操作结果:返回二叉树深度
// 递归实现
int BiTreeDepth(BiTree T)
{
	if (!T)
		return 0;

	int i, j;

	if (T->lchild)
		i = BiTreeDepth(T->lchild); // 递归求出左子树高度
	else
		i = 0;

	if (T->rchild)
		j = BiTreeDepth(T->rchild); // 递归求出右子树高度
	else
		j = 0;

	return i > j ? i+1 : j+1;
}

// 求二叉树高度的非递归形式
int BiTreeDepthNonRecursion(BiTree T)
{
	if (!T)
		return 0;

	queue<BiTNode *> Q; // 借助队列实现层次遍历,从而求出高度
	BiTNode *p; // 记录队列头部
	BiTNode *back; // 记录队列尾部指针
	int level = 0; // 队列高度

	Q.push(T);
	back = Q.back();
	while (!Q.empty())
	{
		p = Q.front();
		Q.pop();

		if (p->lchild)
			Q.push(p->lchild);
		if (p->rchild)
			Q.push(p->rchild);

		if (p == back)
		{
			level++;
			if (!Q.empty()) // 防止最后Q为空时出错
				back = Q.back();
		}
	}

	return level;
}

// 求二叉树高度的非递归形式
int BiTreeDepthNonRecursion2(BiTree T)
{
	BiTNode *Q[MAXSIZE]; // 借助队列实现层次遍历,从而求出高度。此时用数组实现队列
	int level = 0; // 二叉树高度
	int last = 0; // 每层次最后一个结点
	int front = -1; // 队列头指针
	int rear = -1; // 队列尾指针
	BiTNode *p;

	Q[++rear] = T;
	last = rear;
	while (front < rear) // 队列不空
	{
		p = Q[++front];

		if (p->lchild)
			Q[++rear] = p->lchild;
		if (p->rchild)
			Q[++rear] = p->rchild;

		if (front == last)
		{
			level++;
			if (front < rear)
				last = rear;
		}
	}

	return level;
}

// 初始条件:二叉树存在
// 操作结果:前序遍历二叉树
void PreOrderTraverse(BiTree T)
{
	if (!T)
		return;

	visit(T);
	PreOrderTraverse(T->lchild);
	PreOrderTraverse(T->rchild);
}

// 前序遍历非递归形式
void PreOrderNonRecursion(BiTree T)
{
	if (!T)
		return;

	stack<BiTNode *> S; // 借助栈实现非递归遍历
	BiTNode *p;

	p = T;
	while (p || !S.empty())
	{
		while (p)
		{
			S.push(p);
			visit(p); // 在每次入栈时进行访问
			p = p->lchild;
		}
		if (!S.empty())
		{
			p = S.top(); 
			S.pop();
			p = p->rchild;
		}
	}
}

// 初始条件:二叉树存在
// 操作结果:中序遍历二叉树
void InOrderTraverse(BiTree T)
{
	if (!T)
		return;

	InOrderTraverse(T->lchild);
	visit(T);
	InOrderTraverse(T->rchild);
}

// 中序遍历二叉树非递归形式
void InOrderNonRecursion(BiTree T)
{
	if (!T)
		return;

	stack<BiTNode *> S;
	BiTNode *p;
	
	p = T;
	while (p || !S.empty())
	{
		while (p)
		{
			S.push(p);
			p = p->lchild;
		}
		if (!S.empty())
		{
			p = S.top();
			S.pop();
			visit(p); // 每次从栈中弹出的时候访问结点
			p = p->rchild;
		}
	}
}


// 初始条件:二叉树存在
// 操作结果:后序递归遍历二叉树
void PostOrderTraverse(BiTree T)
{
	if (!T)
		return;

	PostOrderTraverse(T->lchild);
	PostOrderTraverse(T->rchild);
	visit(T);
}

// 后序遍历非递归形式
// 难点是分清栈中弹出根结点时,是从左子树弹出还是右子树弹出。所以使用辅助指针r。
void PostOrderNonRecurion(BiTree T)
{
	if (!T)
		return;

	stack<BiTNode *> S;
	BiTNode *p;
	BiTNode *r; // 用指针r记录最近访问的结点

	p = T;
	r = NULL;
	while (p || !S.empty())
	{
		while (p)
		{
			S.push(p);
			p = p->lchild;
		}
		if (!S.empty())
		{
			p = S.top();
			if (p->rchild && p->rchild != r) // 如果右子树存在,且未访问过
			{
				p = p->rchild;
				S.push(p);
				p = p->lchild;
			}
			else
			{
				S.pop();
				visit(p);
				r = p;
				p = NULL;
			}
		}
	}
}

// 初始条件:二叉树存在
// 操作结果:层次遍历二叉树
void LevelOrderTraverse(BiTree T)
{
	if (!T)
		return;

	queue<BiTNode *> Q; // 借助队列实现层次遍历
	BiTNode *p;

	Q.push(T);
	while (!Q.empty())
	{
		p = Q.front();
		Q.pop();
		visit(p); // 每次弹出的时候访问结点

		if (p->lchild)
			Q.push(p->lchild);
		if (p->rchild)
			Q.push(p->rchild);
	}
}

// 初始条件:二叉树存在
// 操作结果:访问每层二叉树最右边的结点
void PrintLastInEachLevel(BiTree T)
{
	if (!T) // 如果树为空,则返回
		return;

	queue<BiTNode *> Q;
	BiTNode *p;
	BiTNode *back; // 指向每层最后一个结点的指针

	Q.push(T);
	back = Q.back();
	while (!Q.empty())
	{
		p = Q.front();
		Q.pop();

		if (p->lchild)
			Q.push(p->lchild);
		if (p->rchild)
			Q.push(p->rchild);

		if (p == back)
		{
			visit(p);
			if (!Q.empty())
				back = Q.back();
		}
	}
}

// 初始条件:二叉树存在
// 操作结果:分行输出每层二叉树的结点
void PrintLevelOrderByLevel(BiTree T)
{
	if (!T)
		return;

	queue<BiTNode *> Q;
	BiTNode *p;
	BiTNode *back; // 记录每层最右边的结点,从而实现分行输出

	Q.push(T);
	back = Q.back();
	while (!Q.empty())
	{
		p = Q.front();
		Q.pop();
		visit(p);

		if (p->lchild)
			Q.push(p->lchild);
		if (p->rchild)
			Q.push(p->rchild);

		if (p == back)
		{
			putchar('\n');
			if (!Q.empty())
				back = Q.back();
		}
	}
}

本身感觉现在这些在计算机专业里面应该是太基础的东西了,不想贴出来的,但是确实这个算是一个里程碑吧——感觉自己对编程有点入门了。下一篇会把用类实现的二叉树的代码贴上来,之后再写点自学编程上面的一些感悟或者说一些经验吧。

参考资料:

1.《大话数据结构》

如何快速学习

最初想到这个问题是因为自己跨专业到了计算机。众所周知(如果你不知道,我现在一说你也就知道了:P),计算机行业的发展是非常迅速的,每年都有很多新的技术产生,这样计算机行业对其从业者要求就会很高,因为他们要不断地学习新的技术来应对日新月异的技术更迭。

看了很多计算机专业的招聘以及网上对计算机从业者的要求,发现学习能力都是一个合格的程序员的必备能力之一;同时因为自己跨专业,发现和身边科班出身的同学们在专业方面的能力差别很大,也希望能更快的学习到更多的知识,所以在自学计算机基础方面的课程时也注意思考“如何快速学习”这个问题。在经过了一年的学习,阅读了很多著名程序员的博客之后,将一些经验和思考总结在此。

从本质上说,我个人认为,是不存在“快速学习”这个概念的。一个人在某个方面学习的速度:1)和他在这个方面所花去的有效时间是成正比;2)和他之前对这个方面的知识储备是成正比的。

这里面的第一点比较好理解,对于大部分人而言,你在一个方向面花去了多少时间,就会有多少收获。不论是学习知识、技能还是你对自己兴趣爱好的追求。同时,我们生活中一定观察过这样的现象:有些人(也可能是自己)在某些学科花费了很多时间,但是收益却不明显,很大的原因就是这些花去的时间并不都是有效时间——真正用于这方面知识积累的时间。最常见的例子就是,中国很多大学生学习英语好多年,然后有很多人竟然连四、六级都没能通过,就更不用说能够流利使用英语了。根本的原因之一就是,他们并没有真正的想去学习(使用英语解决问题的技能),都是抱着应付考试的心态去努力(当然还有一个重要的原因是方法不太恰当)。

对于第二点,这也是我跨计算机专业之后才发现的。当时还有一个同学也是跨专业,但是他很快就入门了,而且学习效率更高。经过比较,我才发现这个区别的:虽然同样是跨专业,但是他的本科学校更好(高中学习更好,这也意味着他自我管理等等方面会好很多)、要求更高,本科学习过《离散数学》、《C语言》等等科目。这些都算是计算机方面的基础性学科,很多计算机学科的学习有了这些知识都会事半功倍的。

当然,学习的速度还和方法有关,甚至有很大的关系,不过当我们刚刚接触一门学科的时候,我认为方法的作用是不太明显的。因为你对这个方向上没有太多的认识,都是看网上或者听前辈讲述方法,真正重要的东西往往都要自己有了一定的知识积累,才能感觉到学习方法的重要。

将以上的内容进行总结,可公式化表示为:

:学习速率; :方法系数; :有效时间; :初始的知识储备,甚至可以包涵一个学习者的整体能力。

因为,学习速率和方法成正比,和有效时间成正比,初始的知识储备或者一个学习者的整体能力会对初始学习速率有影响,不过对于学习速率的影响总是有一个范围。

那么如何做到“快速学习”呢?

我个人认为,要做到快速学习,一个学习者(尤其是一个领域的初学者)应该具备以下能力或者习惯。

1)良好的自我管理能力。

前面说了,学习速度和花去的有效时间成正比,那么就需要良好的自我管理能力来约束自己,不要终日拖延,不要有三天打鱼两天晒网的现象,要能够静下心来学习。同时,在刚刚进入一个新的学科的学习是有很多困难的,尤其是自学。我相信大家都有过类似的经验:在初学某样事情的时候会觉得这个事情特别困难,这因为初期时我们对这个方面的重点和学习技巧掌握的太少,这个就要多看看前人的经验了。

2)查找所学行业的经验,找到适合自己的方法。

我们都是站在巨人的肩膀上去寻找前方不太清晰的路途的。很多问题已经有了相当多的经验可循,而且现在互联网发达,遇到事情之前上网查查,寻找一下类似的经验,可以省去很多不必要的弯路。而且每个人学习的方法不同,学习的习惯不同,有人愿意早起,有人愿意晚睡,看看其他人的经验结合自己的实际来做出自己的计划是非常重要的。这个有点像考研的时候你会上网或者向专业学长询问考研经验。这点对于新学习一个行业非常重要。

3)找到领域内长期不变的东西,学扎实。

每个领域都有很多知识是长期沉淀下来的产物,而且因为沉淀了很久,这些知识变化很慢,甚至是不会改变的了。我们都应该有这样的经历,在一门课程刚开课的时候,老师都会给我们介绍书籍,而这些书籍往往都是很厚且较为久远的书籍了。其中一个原因就是,一门学科发展到一定的阶段,必定有很多知识是研究的很透彻的了,不太容易改变。不过这些知识往往是很重要的,新的技术很多都是这些知识在不同方面的应用。当然还有一个原因可能是,任课老师一般最少都比我们大个10岁8岁,他们看过的书籍肯定都是较为古老的书籍(这个是针对计算机,其发展也不过几十年,而且这几年国内有众多的相关书籍出版,所以10年前就比较久远了,有些传统行业的学科肯定在高校学习到的知识会更古老)。

4)保持自我充电的习惯。

利用业余时间扩大不同学科的涉猎,可以针对自己行业周边学科优先选择。这些学科不要求自己都能很清楚的理解,但是要对一些学科有一些通识性的认识(脱盲)。这样,在自己想要学习新的知识的时候,会发现很多东西是自己已经了解的了,这样在前期学习的时候困难曲线会平缓很多。

如果还要加一条的话,那么就应该是热爱这个方向。当你学习一个自己喜爱的学科的时候,会愿意在其中投入更多的时间,并且乐此不疲。长此以往,你的积累会超乎自己的想象的。

当然,这仅仅是我根据以往的观察以及这一年经验所思考的结果,一定有很多地方需要修正,甚至有些观点可能是错误的。以后也会在有了新的感悟之后,再来更新以往的认识的。

顺序单链表插入新节点的一种方法

在学习链表的时候我们都接触过单链表插入新结点的问题。其中有一类就是在顺序链表中插入新节点,并保持链表的递增或者递减性质。

最近看《C和指针》一书中提到了一种方法,我个人感觉不错,并且思想非常好。

这是最常见的思维:

//sll_node.h  
  
typedef struct Node  
{  
    int value;  
    Node *next;  
} Node;  
#include "sll_node.h"  
#include <stdio.h>  
  
#define TRUE    1  
#define FALSE   0  
  
// insertNode:把newValue的值插入到递增排序的链表中,正确返回TRUE,错误返回FALSE  
// rootp是链表的头指针。  
int insertNode(Node **rootp, int newValue)  
{  
    Node *newNode; // 新节点的指针  
    Node *previous; // 当前指针的前一个指针  
    Node *current; // 当前指针  
  
    current = *rootp; // 初始化  
    previous = NULL;  
  
    // 查找插入的位置  
    while (current != NULL && current->value < newValue)
    {
        previous = current;
        current = current->next;
    }
  
    // 给新节点分配空间  
    newNode = (Node *)malloc(sizeof(Node));  
    if (newNode == NULL)  
        return FALSE;  
    newNode->value = newValue;  
  
    // 更改新节点的前驱和后继节点  
    newNode->next = current;  
    if (previous == NULL) // 此时插入节点的为链表中第一个节点,修改头指针  
        *rootp = newNode;  
    else  
        previous->next = newNode;

    return TRUE;
}

我以前编写的时候也会用这样的方法:一个当前指针和指向当前指针之前的指针,这样需要讨论原链表是否为空。书中提到了一种抽象,每次插入新的节点,都是改变一个指向这个新节点的指针以及指向下一个节点,这样可以省略讨论插入的节点是否为第一个节点的步骤。代码如下:

#include "sll_node.h"
#include <stdio.h>

#define	FALSE	0
#define TRUE	1

// insertNode2:把newValue的值插入到递增排序的链表中,正确返回TRUE,错误返回FALSE
// nextp是指向当前节点的指针,最初是头指针
int insertNode2(Node **nextp, int newValue)
{
	Node *newNode; // 新节点指针
	Node *current; // 当前节点指针

	current = *nextp; // 最初当前节点为nextp指针指向的节点
	// 查找新插入节点的位置
	while (current != NULL && current->value < newValue)
	{
		nextp = &current->next;
		current = current->next;
	}

	// 为新节点分配内存
	newNode = (Node *)malloc(sizeof(Node));
	if (newNode == NULL)
		return FALSE;
	newNode->value = newValue;

	// 统一了插入的步骤。即:每次插入,都是前一个指针指向新节点,新节点指向下一个节点
	*nextp = newNode;
	newNode->next = current;

	return TRUE;
}

main函数

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "sll_node.h"

int insertNode(Node **rootp, int newValue);
int insertNode2(Node **nextp, int newValue);

int main()
{
	srand(time(0));

	Node *head = (Node *)malloc(sizeof(Node));
	head->next = NULL;

	for (int i = 0; i < 5; i++)
	{
		int temp = rand() % 50;
		printf("%d\n", temp);
		//insertNode(&head,temp);
		insertNode2(&head,temp);
	}
	
	Node *p = head->next;
	while (p != NULL)
	{
		printf("%d\n", p->value);
		p = p->next;
	}

	getchar();
	getchar();
	return 0;
}

因为我个人没有经过正经的课堂训练,自己考研才接触编程、数据结构之类的。看了很多对自学编程提的建议都是多编写,并且要有抽象的思想,所以将这个方法写了下来,可能对很对科班出身的人不算什么问题了吧。

我感觉这个抽象很好,希望是给自己编程道路的一个好的开端吧:)

同时,因为我在初学时发现测试代码也会花费很多时间,所以将完成的代码都贴了上来,而不仅仅是函数,希望也能帮助到更多的想我这样的初学者吧。

博客时间轴

16.08.29

添加如下插件:

1.LaTeX for WordPress。此插件可以在wordpress编辑LaTex公式。这个插件的作者就是我的推荐博客中阅微堂的博主写的。这个页面中有一些关于此插件用法的总结。

16.08.26

对自己博客的手机端进行了一些优化,比如首页只显示三篇文章标题等,不过手机端的显示每次在更新博文之后几个小时之内会显示成为修改之前的样式。

添加如下插件:

1.WordPress Mobile Themes。此插件可以实现wordpress手机端和桌面端使用不同的主题。
2.WP Super Cache。把wordpress页面静态缓存,提高浏览速度。
3.Dynamic To Top。在文章页面中增加跳转回顶部的插件。
4.BackUpWordPress。众所周知,备份是很重要的,如果出现什么问题,之前的备份就会有很大的作用了。这款插件就是实现自动备份wordpress的插件,可以选择时间将备份的wordpress内容发送到你的邮箱。
5.WordPress 导入工具。将以上提到的BackUpWordPress插件备份的内容还原。之前其实就用过这两款插件。因为本来博客的页面是frankge.me的,但是后来出现了一些问题,所以改到了frankge.me/blog页面,就是用的这两款插件。

16.08.17

添加如下插件:

1.Akismet:此插件可用于过滤垃圾留言。
2.Google XML Sitemap:给自己的博客生成sitemap,方便搜索引擎抓取文章。
3.SyntaxHighlighter Evolved:便于插入代码。支持很多种编程语言:cpp, java, python, css等等,使用方法和支持的语言具体参见这个页面

16年05月

GoDaddy买域名frankge.me。主机采用的戈戈主机。采用wordpress搭建。

建站过程

按照知乎用户@waylight 在怎样搭建一个自有域名的 WordPress 博客?的回答进行。建站期间还遇到一些问题,所以将自己的建站过程记录如下。

主要步骤为:

1.建立本地博客文件

建立博客的过程中肯定需要记录一些信息(比如博客的登录名和密码,主机服务器的ip和登录名密码,还有博客头像和一些备份内容等等)和一些待解决的问题(建立博客可能不是一次就完成的)。这个文件夹用于存放这些信息,便于以后的查看、修改和一些重要信息的备份。

2.购买域名

前文说了,我个人是在GoDaddy上面购买的域名,个人感觉还不错,同时看好像是支持支付宝付款,方便不过我个人是用Visa信用卡付款的。

同时正如知乎的回答中所说,如果你提前想好了想要买的域名,在自己的购物车中放几天,然后GoDaddy就会给你邮箱发送优惠券的,优惠券好像只能信用卡支付使用,具体的忘记了。

3.购买主机空间

只有购买了主机空间,将自己博客内容上传到自己的主机之后,才能让别人看到你的博客内容。支付成功之后主机提供商会给你域名的对应IP,同时还有一些其他的信息。

4.域名解析

使用DNSPod进行域名解析。具体步骤为:

1)在DNSPod中添加域名。
2)把DNS地址修改为DNSPod。登录自己的GoDaddy账户,点击DOMAINS左边“+”号,选择Manage DNS。将其中Nameservers改为"f1g1ns1.dnspod.net","f1g1ns2.dnspod.net"。
3)将域名指向主机服务器的ip,即在DNSPod中添加“A记录”。填写完成后如下图。

域名解析01

域名解析03
其中黑色笔划去的部分填写你的主机供应商提供的ip地址。

5.安装wordpress

知乎回答的原文说,不同的主机空间有不同的虚拟主机控制系统,安装的过程也不尽相同,但是步骤都是差不多的。这个具体的我也不太清楚,我的主机空间使用的也是cPanel面板。

1)登录cPanel面板,“数据库”->“MySQL数据库”,创建一个数据库,然后创建用户,将用户添加进数据库,勾选“所有权限”。

wordpress安装01

wordpress安装02

wordpress安装03

wordpress安装04

wordpress安装05

2)上传WordPress。进入cPanel首页,点击“文件”->“文件管理器”,选择public_html文件夹,将wordpress文件夹中的文件上传至此文件夹(忽略我下图中的“wordpress”和"blog"文件夹)。

wordpress安装06

3)按照提示设置wordpress的信息。

以上完成之后,就可以在浏览器中输入你的博客地址,进入wordpress的界面了。

6.主题选择

网上有很多免费的wordpress的主题可供选择,当然也有很多收费的,这个根据自己的需求选择。之后的内容都很简单,就不一一写明了。我个人的主题使用的是twenty fifteen。

初到四牌楼

一、

出了文昌宿舍所在的小区,横穿太平北路的一个斑马线,经过文昌桥走到小路的尽头,向右转再走不到100米,就是东南大学四牌楼校区的东门了。

在我眼中,四牌楼校区相比于九龙湖校区,简直是没有可比性的。四牌楼这边宿舍陈旧,实验室太小以至于要两个人做一张桌子,浴室的承载能力有限,在高峰的时候洗澡很不方便,更不用说食堂饭菜不好,体育场也很小等等这些细枝末节的问题了。

当然,这边还是有很多惊喜的。因为去年复试就是在四牌楼,所以国立中央大学的旧址所带来的古朴和厚重就显得没那么吸引我了,令我欣喜的,反倒是另外一番景象。

街道上散落的炒饭摊点,道路两旁整齐的绿化,许久没听见的大片大片的蝉鸣,以及一个城市中老居民区的生活。

听同学说,这个宿舍原本是居民小区,因为学校宿舍不够用征用过来的,所以这附近住着很多的南京本地的居民。有居民的地方,周边自然有很多生活元素:小吃摊、水果店、理发厅等等。这些当然不足为奇,但是这对于在九龙湖那边的生活来说,可算是再奢侈不过了。同时,这些元素让我想起很多年前还能常常呆在家中的时光了——每天早上都要排队等候的包子铺,教育孩子要好好学习的家长,以及下象棋打牌的中年人——起码上了大学之后就没再经历过这样的生活了。这种感觉,只有融入了这样的行为模式一段时间之后才会有,不是仅仅看看就能产生的。

刚到这边的时候给我印象最深的是一家小店,叫做「战将鸡排」,因为它不像附近其他几家炒饭摊那样满是油污,而且这边食堂整体没有九龙湖那边好吃,所以要提前找好懒得去食堂的时候能够饱腹的地方。

最近天热了,看到这家店门口正好贴着凉面皮的价格,我就走过去要了一份。老板拌凉面皮的功夫,我和她搭起话来。

「你这地方不大,卖的种类到不少呢,还真没看出来」,我有点惊叹的问到。

「啊,那可不是么」,老板边忙着拌凉皮儿边回答着我为了避免静默所引起尴尬的随意的话语。

「好久没吃过凉皮了,大概上了大学之后就没再吃过了吧。我刚才九龙湖搬过来,这边四牌楼食堂感觉不太好吃。对了,记得小时候最喜欢吃凉皮里面的面筋泡子,多放点吧」,我接着说到。

「行」。老板爽快的答到。

「我家儿子也是,在外面上大学,整天抱怨食堂的饭菜不好吃,经常在外面吃」,我的话仿佛说到了全国各地大学食堂的通病,她也不禁地帮着儿子抱怨着。

之后,老板又说了说自己店面干净,不仅是学生,还有好多居民都到她这边买小吃的情况,我也跟着搭搭话,表示以后会常来关顾的。

回到寝室吃着凉皮,感觉还是没有小时候家边店里面的味道。

二、

提到蚌埠,大部分人的印象可能是以前坐火车经过此地吧。再多一点,就是蚌埠是一个大站了。

是的,蚌埠是火车拉来的城市,提到它想到蚌埠火车站一点不令人出乎意料。

其实最早听到以「火车拉来的城市」的称呼来形容蚌埠,还是从本科室友的口中。

大概是刚刚上大学没多久,我聊到家乡蚌埠。他说蚌埠是火车拉来的城市。

我听了他的形容之后惊异的问到:「『火车拉来的城市』在以前地理书上面介绍的不是株洲么?」

「我们上地理课时,老师还举了个例子,说我们省的蚌埠也是火车拉来的」,他回答说。

可能是因为他也是安徽人的原因吧,所以老师才会拿一个比较熟悉的城市举例。这是我之后想到一个合理的解释。

其实,蚌埠的小吃也是不错的。可能是因为交通便捷,文化交流会多一点,很多南方北方的小吃本地都有。蚌埠本地曾今有首RAP,叫做《烧饼夹里脊》,里面有句歌词唱到:「都说中华美食遍天下,遍天下的美食都在蚌埠开了花。烧饼,包子,油茶,春卷,辣汤,麻圆,米线,凉皮,火锅,拉面,水单饼,大麻花。吃啥啥香,你要啥有啥」。当然,对于自己家乡的印象每个人都有很多很多,且都如数家珍。熟悉的街道、肆无忌惮开着玩笑的发小儿、伴随着记忆中的自己成长的那些学校,还有在家中做个孩子的味道。

记得刚搬过来的时候,在沙塘园食堂吃饭的时候突然发现有豆腐脑儿,一时兴起想要尝尝,发现也不如小时候家边店里的好吃:汤不是骨头汤,里面没放粉丝,没放黄豆,竟然吃到了一点孜然的味道。吃完了之后想了想,可能也不见得就是不好吃,人家没准认为这是美味呐。只是这不是我熟悉的味道罢。

三、

一转眼,来到四牌楼校区一个月了。

搬到一个新的地儿,自然要置办一些东西,来适应新的住所。这边寝室的地方实在太小了,自己想买一个大点儿收纳箱,把一些柜子里面放不下的衣物给塞到收纳箱里。

这边校区在市区,不远处就有超市,这个我倒是挺满意的。即使在这个网络购物已经足够便捷、实惠的时代,不时去趟超市,看看生活中最常接触的柴米油盐,看看生活中最常遇到的普通百姓,还是很有必要的。而不仅仅是被充斥着京东首页的数码产品或者是铺满淘宝首页的时尚衣物或者是网络媒体中所报道的名人大V所占据。

想了想,好久没吃太多的零食了,而且,很久也没大鱼大肉一番了。其实很久以前,大鱼大肉对我的吸引力就已经不怎么存在了。记得在九龙湖那边时,几次和室友去吃自助,自己都是不停地拿蔬菜水果,而不是去弥补在校园食堂里面亏欠的动物蛋白。

上次一个人逛超市大概是一年多之前吧,研一阶段去超市一直是和室友一起的。看了好几款,挑了一个大小适中,颜色淡雅的收纳箱,放到了手推车里。终于,来到这边宿舍最大的一桩事情算是弄好了——我的东西差不多能放下了。

走到零食的那一排排货架前,自己还是在那放缓了步伐,毕竟我每次都会买点饼干之类的简单食品,留在晚上饿了的时候充饥。现在零食的种类确实丰富,不论从口味还是包装,都足够吸引人。我拿了一袋看看,这个钠含量太高了,给放了回去;又拿了一袋看看,这个能量太高,也不需要,又给放了回去。我在这排货架面前驻足了有大约十几分钟,最后还是拿了自己常吃的那种饼干放到了推车里面:有一点糖分,在晚间能补充能量;钠的含量不高,对于现代人的生活节奏而言比较合适;而且每个小包装里面数量不多,不用怕放久了回潮。

走到收银台那边,不经意间看到一个顾客推车里面放满了零食,我没忍住嘴角微微扬起:「原来在很多方面,我已经足够理性了。」

「人到了一定年龄,分化的程度太令人可怕了。」我有点无奈地笑笑。

四、

2016年7月的南京,甚至全国,都是挺令人难忘的吧。湖北、安徽等地区遭遇了多年不遇的强降雨,很多地方水灾泛滥。起初天气还不算热的,但是雨一停,直接进入了以往夏季的燥热。空气中到处都弥散着令人窒息的热气。

横穿太平北路,经过文昌桥。经过文昌桥,再横穿太平北路。去实验室,回寝室。这是再熟悉不过的路程了。

横穿太平北路的时候,要经过一个斑马线。斑马线前的红灯,大约80秒左右。在这盛夏的时节,等个红灯,也足以让人感到筋疲力尽。

那天,我在看到绿灯刚刚过了之后,站在很远的树荫下等红灯。红灯后,一个女生从斑马线的另一端走过来,白皙的皮肤,穿着蓝色上衣、白色的裙子,打着遮阳伞。她大概注意到我了,嘴角微微上扬,视线向另一侧转去。其实在等红绿灯的功夫我就注意到她了。我也微微笑笑,然后径直地穿过了斑马线。

当我们在谈论「社会」的时候我们在谈论什么

记得在我小的时候,家人对社会的评价是偏「负面」的,比如「人情味比较淡薄」、「黑暗」等等之类的词语。

甚至在最近几年,我的父母还经常说:「我有点太理想主义了,太单纯了,进入社会就会明白很多东西不像你想象的那么简单。」

于是在我刚开始建立「世界观」的时候,就感觉「社会」可能是一个不太好的东西,想要趁着在学校的生活当中学习到更多的知识技能,这样才能立足于社会,不被这个「黑暗」的社会所欺负。

渐渐地,我长大了。上大学、上研究生,期间还学过车,而且有过两次独自去一个陌生城市旅行的经历,于是开始对从前认知的「社会」有了新的了解。

下面我来谈谈我所理解的社会。

为了便于思考,我将社会的最基本单位分为「职业」。社会是由不同的职业构成,比如「教师」、「出租车死机」、「程序员」等等。

每种职业有每种职业运行的规则,甚至潜规则,所以我们对于社会中的不同的职业有着不同的理解。

比如,商业的运转中,逐利性是商业的一个共性之一,所以「饭店老板」、「超市店铺店主」需要进到更低价位的东西,然后以高价卖出,这样他们才能生存。那么进货的渠道就是一个很重要的事情了。进来的货物是否安全、质量合规,就是我们消费者关注的事情了。就像前几年比较引人注意的事情那样,「地沟油」的小摊小贩必备道具,这就变成了条潜规则;一些不法商贩进货渠道有问题,出售假货、高仿货或者残次品给客户,这也就成了一些行业的潜规则,比如有些运动鞋的店铺等等。那么商业的本身的运转有问题么?我个人认为是没有问题的。问题出在法律、法规是否健全以及法律、法规的执行是否合法。

再比如,娱乐圈的潜规则,大家都懂。这也是因为,在有些方面,法律无法硬性的规定别人的私生活,让一些人找到了漏洞。在我们中国这样一个人口众多、人口密度很大的国家,这些问题被放大了。同样,我猜测,在国外这个圈子应该也是有类似的潜规则的,因为这个圈子本身就是依靠人来发展的,所以这是个没法避免的问题。

从以上两个例子我们可以看出,我们对有些行业的疑虑,并不是因为这些行业本身,而是因为我们没有去认真思考。每个行业可能有很多不符合我们平常的认知、价值观念和道德观念的地方,因为每个人的见识毕竟有限。同时在我的观察中发现,一些同学、亲戚朋友,他们对法律、法规的建立并不关注,所以造成他们对生活中的很多行业变得并不信任了。因为长期的信任的缺失,所以「贵圈很乱」、「中国食品质量不过关」这样的理念渐渐深入人心。究其根本,应该建立完善 法律、法规,并且相关的机构认真执行。

说到身边很多人对法律、法规的不关心,我还想到另一个问题。生活中,我们经常称自己「老百姓」,甚至更早的中国百姓见到官员时都称自己是「草民」。我感觉这就是一个不好的习惯,这就让我们本身觉得自己是低人一等。英语中有一个词叫做citizen,直译为「公民」。我个人感觉中国人更应该树立每个人的「公民感」。话题扯远了。

那么我们能做的是什么呢?或者说对于一个出身一般,同时对自己的未来有一定期望,在面对因为社会本身的一些不完善所带来的阻力时应该怎样努力呢?

从我个人的经验来说,可以朝着以下几个方面来努力:

1.改变「社会黑暗」的观念。社会必然不完善,甚至还有很多问题,但是在很多时候,社会中的人还是很友善的。令我印象最深刻的一次,是我在北京地铁找不到方向,而且刚到那边目的地也不清楚,手机还没电了,只能回忆要去的地方有哪些地标性建筑,最后地铁里面的志愿者大妈花很久帮我想乘车方式,甚至两个大妈为了讨论哪条线路更近,都吵起来了。

2.努力踏实地学习自己赖以谋生的知识技能。这个其实不需要再强调一遍了,我想强调的是,学习的方向也不是说一次择业决定终身的。像我,就是从一点不懂编程跨专业到计算机的,同时自己大学的时候还巧合认识了一个家伙从学化工跨考到金融。不同的行业在不同时代发展不同,甚至在某些对从业人员要求较高的职业或者岗位,对人才的尊重会更高。人们总说要适应环境,其实还要不停的提高自己的能力、素质,去寻找适合自己性格或者实际情况的环境。在现在信息传递加速,信息获取逐渐平等的时代,找到适合自己的环境已经不是天方夜谭了。

3.仔细思考自己行业运转的方式,这样才能不停地提高自己的层次(虽然我不太喜欢把人划分为不同的层次、阶级等等,但是这样简单的表述确实能够将一些想法简单地表达出来,这里的「层次」可以理解为不同的收入或者不同的社会地位)。举一个简单的例子,如果你是做生意,那么在一个小区门口卖东西和做一个地区的代理卖东西所挣到的钱是不同的吧?而且在一个高档小区里面卖同样的东西也比在一个低档小区卖东西挣钱吧?

4.理解不同职业的运转规则。原因有二。其一,从小到大,我们有很多同学,亲戚朋友,肯定是分布在不同职业的,如果你对他们的职业不理解,甚至有偏见,那么这会使得你们逐渐疏远。其二,理解了不同职业的运转规则,会使你懂得如何跟不同职业的人进行沟通。同时,拿同学经常说的程序员到了一定年纪就敲不动代码来说,到了未来你可能会技术转管理。那么如果你不理解管理方面的知识技巧,你能很好的管理别人么?即使你不会转岗,那么在你被别人管理的时候,你如何分辨别人的管理是否明确可行呢?

5.了解一些和自己密切相关的法律法规。在我们初入职场的时候确实会处于比较被动的地位,了解法律法规才能保护自己。甚至社会的不断发展,很大程度上就是要靠法律法规更加完善、健全,同时公民的法律意识更好才行。当然这是一个长久的过程了。

leadership是什么

目录:

一、leadership是什么
二、我眼中leader的一些要求
三、我的一些经验以及总结

一、leadership是什么

leadership是什么?

leadership is not authority, but trust.

简单的说来,就是如此。

我曾经仔细地思考过这个问题。生活中我们肯定有很多的“领导”:小时候,我们的家长是领导;在学校,我们的老师是领导;走向工作岗位了,我们的上级是我们的直接领导。在学校我们的班长、组长以及课代表是在某些方面是我们的领导;工作中一般会有team,不同的team一般也都会有leader。

问题是,我们不一定会服从,或者真正愿意服从某些“领导”。比如有些家长教育出来的子女相对比较听话,茁壮成长,成为出色的人;但是有些孩子总是与家长对着干,打架斗殴,不好好学习,长大了连一个心智健全的人都做不到(当然我没有说“听话”就一定是好事,不听话就一定错误。但是在我们小时候,对世界没有特别多的观念的时候,对于大多数家庭,“听话”是个相对正确并且风险比较低的事情)。比如有些老师上课我们极其讨厌;比如有些班干总是打小报告;比如在某个team中的leader私心很重,总是想着实现自己的利益最大化而剥削其他成员等等等等。

上面的例子我想1,2两个大家都会经历过,第3个例子我个人没经历过,但是网上的评论上面确实会有,甚至现在研究生阶段我听说很多导师对于学生的做法就有些类似这种情况。

我想很多人肯定也有过类似的思考。

直到有一天,我看到了TED上面的一个视频——《Why good leaders make you feel safe》——解开了我心中很多的疑惑。总结下来,就是下面一句话:

Leadership is not authority, but trust。领导力并不是(因为)权威,而是(因为)信任。

视频中一个例子非常生动。

Bob Chapman是一家非常大的制造业公司的CEO,公司名叫Barry-Wehmiller,在美国西海岸。2008年金融危机的时候,有一天一夜之间损失了30%的订单。这对于一家大公司而言无疑是一笔巨大的数字,甚至都养不起公司的员工了。他们需要节省1000万美元。就像很多公司一样,Barry-Wehmiller公司的董事会开始考虑裁员。但是Bob拒绝了。Bob不同意大多数人的意见,他认为每个人都承担一些损失比我们其中某些人承担一个巨大的损失要好的多。于是公司采取了一个休假的方案,从秘书到CEO,公司中的每个员工都被要求去4个星期的无薪休假,可以在任何他们想要的时间去休息。因为公司的决策让每个人感到了安全,同时每个人也更愿意信任公司并且合作起来。而且出乎意料的是,公司中竟然员工之间互相帮助,可以承担的更多的员工把自己无薪水的休假延长,让给家庭条件稍微差一点的员工能减少无薪水休假。最后的结果呢?大家士气上升,省下了2000万美元。

视频中的一个比喻我感觉很恰当。

那些出色的领袖就像是父母一样。他鼓励我们自信,给我们机会尝试甚至失败,传递给我们经验(原话是education,在此处不好翻译,意译),在需要的情况下规范我们。这样我们能够成长并且超越原先的自己。

里面有句话说的非常好:

We call them leaders because they go first. We call them leaders because they take the risk before anybody else does. We call them leaders because they will choose to sacrifice so that their people may be safe and protected and so their people may gain, and when we do, the natural response is that our people will sacrifice for us.

我看完之后思考:怎样才能成为一个合格的leader呢?

二、我眼中leader的一些要求

经过总结,有了一些浅见,我认为一个出色的leader可能应该具备一下几个特点:

1.技术方面

我认为一个出色的leader应该是了解甚至是比较熟悉一些技术的。虽然说leader的主要职责是人力资源的调配,但是如果对与项目上面技术方面的事情都不太了解,我感觉也不能做好人力资源的合理调配。

2.管理方面

1)有气度,尊重人,尊重差异

一个团队中有不同的成员,个性差异肯定会有的,我认为一个合格的leader应该尊重每个人的个性,只要不是影响团队工作的,应该予以接受。同时,更不能以权压人,这样别人也不会信任这个leader的。比如我们在上“软件项目管理与实践”课程的时候,老师就举过一个例子。在老师担任项目经理的时候,手下有一个代码能力特别强的人(我们暂且称他为A),(我个人从语气和老师的性格上面猜测,可能因为老师在一些事情上面不听取A的意见,或者没有照顾到A的个性,所以)在很多事情上面A背地里和老师对着干。有一次A说一个程序里面有问题,老师问他哪里有,他说不知道,就是感觉有,不信后果自负。因为老师的代码能力还没他强,所以老师召集除了A以外的所有人一起找这个bug,最后没找到。之后问A,我怎么觉得没问题?A说,那可能就是没问题吧,可能我看错了。这样里外肯定会耽误很多时间。可见尊重别人的重要性。

2)主动承担一些必要的责任

团队出现问题时,可能不是因为某个人那方面有问题而造成的,有可能是整体team中一些沟通环节没做好。这个时候可能需要leader把责任给揽下来,分析、解决。

3)创造人性化的气氛

我们可以观察到,一些很好的企业,确实是有企业的文化的。同时,这些好的企业中人员和谐,相互照顾,我很羡慕这样的企业。那么如何做到的呢?这肯定和管理层面有很大的关系。一个小组中的leader,肯定做到了创造出了一个适合的氛围。比如适当的聚会甚至旅行,从而增进成员了解,关系和谐。了解成员的生日情况,到了这些日子大家一起high一下。甚至,也是“软件项目管理与实践”的老师说,如果确实有些问题不是因为主观失误(比如甲方不断改需求等等),leader甚至都可以带头骂骂这些不愉快事情,缓解成员的一些心头的不甘等情绪。

当然,这是就我观察到的现象的思考和总结,甚至有很多是我想要加入的团队所具有的特性。仅仅是一些浅见,而且未来工作之后会将更深入的思考这些。有没有这样的团队我相信绝对是有的,能不能加入这样的团队就看个人的努力了。

三、我的一些经验以及总结

说了那么多的思考,其实有些我还真的尝试过。在研一的学年里面,我接触过三次小组形式的活动:研一上、下学期的英语课程的模拟学术会议以及创业project,还有就是“软件项目管理与实践”课程。这几个事情上面恰恰我做的事情最多,甚至有的就是leader的作用,我将一些情况分享一下。

因为“软件项目管理与实践”从头到位持续了好几个星期,而且参与人数和任务分配比较清晰,所以拿这个做为一个案例分析。当然,看到这篇文章的童鞋可能有对这些事情比较熟悉的,我不会对其中个人进行明确点名,我分析这个事情只是希望把遇到的问题找出来,更在意如何解决,请不要过多联想。

过程:

1.分配角色及选题

项目是模拟一个项目的执行过程,要定题目分角色。开始我并没有当项目经理的想法,因为我本科没接触过这门课程,而且算刚入行,真的不懂。但是最后被选当项目经理。我想可能是因为这个课程大家都不当回事,而且想减轻的负担。其实我也有点这种想法,因为被选当项目经理绝对事情最多,但是确实这不是主要原因。因为我个人确实比较喜欢完成一些事情,尤其是富有创造性、有挑战的事情。

接下来是选题。选题的时候让大家讨论,其实还挺好,但是我发现了一个问题。我让每个人想一个选题,然后大家投票。最后有一个组员A,提出了一个题目,最后通过选了这个题目。但是我让A提出一些规划甚至谈谈看法的时候,A竟然说没有啥就是突然想到的。其实题目倒是思路很明确,而且大家想出的题目也有类似的。但是我说这是个问题是想表明,如果一个人提出一个方向,尽然自己没有一些规划或者看法,那么在一个team中他这个发言真的是经过思考而做出的么?

2.整体小组表现

我们小组表现较差。我想主要原因有二:1.我(项目经理)确实对这个课程不熟悉。因为这是“软件项目管理与实践”,大部分学生本科应该上过“软件工程”这门课程,而我不太熟悉,影响很多任务分配。这也就是我上节所说的,一个leader,在技术方面,应该熟悉,最起码了解任务的原因。2.我们小组是跨专业最多的一组,而且后期因为课程安排,很多同学要到另一个校区。其实问题不在于这,我们小组整体入校成绩都不算好,虽然说成绩和小组活动没有必然联系,但是从我有限的观察来看,确实成绩不好,而且没有自己特别强的兴趣爱好的人,做事情不主动,得过且过。

3.表现较差的几个问题

1)我想这个是每个小组都会有的一个问题,就是一般小组(除非那种合作很好的小组)几乎从头到尾干活的不会有半数人。这可能因为是学校的课程,而且大家都不太在意,认为课程较水的原因吧。但是,毕竟也要交一份比较不错,最起码不差的东西出来吧。一个小组把任务完成的那么差,大家会怎么看待自己的小组呢?

2)大部分人把责任往外推,几乎没人主动找自己在行的事情分担,更重要的问题是在群里面发消息还没人回。同理,一个小组打分根据大家任务完成程度,一个活动完成不了,大家都脱不了干系。其实在学校还好,如果是真正在企业,一个项目完成不了,你开工资能不受影响?所以我感觉这些意识一定要提早培养的。

3)确实会有人要挑战leader的权威。这个我上面也分析了,leader应该尊重小组每个人,给予他表现的机会。如果真的遇到能力强的了,换人呗。一个项目如果长期运转良好的话,你的工资肯定也会提升的。而且也许由于你的人才培养得当,你升迁了也说不定。

4.我的不足之处

1)对课程不了解,对小组成员分配任务不当。

2)不敢/不好意思给每个人分配任务。这个也因为自己是跨专业考虑。毕竟很多同学都是一个实验室的,有些同学一副打酱油的样子,总是催也没用,还怕把关系搞僵了。但是这样小组其他同学会有意见。不过这些老师打分肯定都会考虑进去的。

5.我的可取之处

1)像上面我个人对leader的要求所说,对人平等、尊重。同时很多问题因为确实不懂,听取了大家的意见。

2)这个活动有上台展示的机会,每次活动前我都问是否有人主动上台,但是几乎没人。我个人考虑是当中演说是一个相当困难的事情,要面对的是现场所有观众对你的反馈,并且实时,所以这个很锻炼人,我希望有更多的人愿意尝试。

3)每次任务布置较早,周五上课,所以一般周一周二布置(周六、日没布置事情,毕竟每个人都想放松一下),而且都将上周课程的一些笔记整理发到群里。但是,我们组真的带不动。。。

因为这仅仅是一个课堂的小组活动,所以也没什么好深究的。但是暴露出的一些问题,应该是值得分析和思考的。当然,也正因为这是一次简单的课堂内容,所以我将思考写在这儿,要是未来工作了,一些思考和分析,可能就不能进行这样较为公开的分析了。

研一这几次小组活动,修正了我对团队、和leader的一些看法:

1)如果一个小组整体实力不好,一个严格的规则(奖惩措施)是非常重要的。最起码这个能让任务顺利完成。当然,这时候leader需要一定的权力。

2)如果有机会选择团队,最好不要为了自己想当leader而到一些相对水平较低的队伍。其实选择加入这组之前也有考虑过,也有人让我加他们组。之前就想到他们会坑我当项目经理,但是考虑到沟通成本——因为研究生阶段班级的概念相对淡多了,很多都不熟——我们小组好多同学都熟了,所以很多东西好商量。事实证明,在一些稍微大型一点的项目上,很多人真的是带不动的。其实后来想想,如果加了其他组,可能混熟的同学还能多一些。

3)如果未来的公司,管理层面有问题,整体水平还比较混乱怎么办?当时我就想到了这个问题。如果遇到这样的问题,首先会想到可能是因为自己能力有不够,所以才会沦落到这样的一个地步。我感觉可以在考虑成熟之后,向上级委婉的提出看法,并说出解决方案。如果一直如此,自己先考虑有没有啥能学到的东西,然后存点钱,等到把风险啥的考虑清楚一点之后,赶紧跳槽,不然绝对是跟着公司一块悲剧。

在九龙湖的那些日子

一、

「今天复试成绩公布,自己通过了复试。我想请问下老师一般什么时候在办公室?」我在邮件中问了之前联系过的一个导师。

「首先祝贺你通过复试,加入计算机学院!我本周二下午应该在办公室,你可以过来我们聊一聊。我的办公室在九龙湖校区计算机楼×××,电话是×××,来之前请先给我打个电话确认一下。」老师回复到。

复试是在四牌楼,到了周二下午,动身去九龙湖校区。那个时候地铁三号线还没有开通,要先坐1号线,再转816路。

到了老师约定的地点,和老师聊了大概有近一个小时,但是那个老师没有想要收我的意图,只和我插科打诨一番。

之后,找了提前联系的学长。联系导师前同学和我说过,让我到实验室转转,老师有的时候会忽悠学生,到实验室多了解了解情况,尽量找一个不是所有杂活脏活累活都找学生做的导师。

把这些正经事儿给搞完之后,在南京逛了逛,因为之前有些著名的景点是拜访过的,所以这回去的是游客相对较少的地儿。去了奥体中心呆了一下午,在回味品尝了评分较高的鸭血粉丝汤,穿梭在中山北路找寻到了正宗的韩复兴盐水鸭。也算是个错开了著名景点人潮拥挤的周末吧。

有天晚上,自己在南京稍稍远离闹市区的一条道上走了很久。整齐的梧桐树,昏暗的霓虹,下了班步履匆匆的职场人士,刚出酒店的醉醺醺的生意人,还有就是晚饭后慢悠悠走在路边的老伴儿。

有段时间自己也特别想体验一下出国读书的感觉,于是问了问在国外读书的同学生活啥样,然后还询问了下自己想去的那个国家读一年研究生花费大概多少。最后,那个同学我跟我说了句:「真的,你在哪住久了感觉都差不多。」

二、

三月,莺飞草长。

挺大的校园,不同功能的建筑之间相距较远,还有就是雄伟气派的图书馆。那次去见导师,初识了九龙湖,但没有想到不久便会离开。

正儿八经的到了这边生活、学习,才发现一些更加有趣的地方:由于校园里有些地儿植被较多,而且有些奇奇怪怪的生物,这边有些人把它称为「九龙湖野生动物园」;为了沿袭四牌楼的仪式感,这个偌大的校区建筑对称,并且青砖绿瓦——这有点像骨灰盒。当然,这都是些玩笑话。

呆上一段时间,九龙湖这边的生活还是蛮符合我的节奏的:看书的时候就是看书,心静下来才能看得下去;出去玩的时候要花上一整段时间,让自己沉浸在一个不太熟悉的环境,探索属于自己的更大的世界。九龙湖校区是远离市区的,而且自己现在对手头的事情太不擅长,对于我这样一个太过于浮躁的人,就有更多的时间能专心用于学术了。

然而,事情并没有想象的那么顺利。没有一些先修基础,很多课程都是走马观花,混事儿的那种交了作业了了事;研究生阶段,比以往多了太多消耗精力的事情要处理,而且班级的氛围不如以前了;你有了直接的「领导」,导师多少都会占据你的自由支配的时间。

客观说来,课程不是特别多。不喜欢的事情,也推出去了不少。但是一些课程上面的小组活动,我倒是有不少抱怨:毕竟这是一个teamwork,这么多人推脱事情、责任,久了,别人愿意和你合作玩耍么?搞的我也萌生了一些想法,比如不要没事往自己身上揽事情,比如有些活动的负责人能躲就不要当,等等等等。当然,后来想想,还是坚持了以往的自己。当你照着自己的处事风格坚持下去,是会遇到那些和你相同的人吧。「物以类聚、人以群分」不是么。

上课,下课。看书,休息。

慢慢地,我开始想要养成一些习惯,想要用一些文字记录些什么。于是便在空闲时间堆砌些文字。

以前,像我这样的一个工科生,是不明白为什么有文学性文章的。一些简简单单的事情,能啰啰嗦嗦地展开成千上万字:有悲天悯人的,有顾影自怜的,有期盼海枯石烂真性情永不变的。有这些功夫,做点儿实在事儿,不更能推进人类社会的进步么,能获得更多人的赏识,能够为真情延续带来更多的砝码么?

后来有些明白过来:人生犹如泛舟于湖海之上,终点不是沧海一粟的个体所能预测得到的。风浪总会在不经意间降临,航向迫不得已会变。文学里面记载的一些东西,让我们在遇到困难、困惑的时候,坚定一些、从容一些;让我们在人性面前,更加懂得尊重生命一些;让我们在利益得失面前,权重多偏向真性情一些。不仅仅是些聊以自慰。

于是,我便成了理解人文学科的工科生了:)

本科的时候养成一个习惯——看别人的博客。当你细细品读那些博客的时候,发现他们的人生历程尽收眼底,尤其是看到那些出色的人们的博客的时候,他们生命中每一个脚步都记录在了自己的文字当中,不会感到很惊奇、很羡慕么?所以当时我也产生了写博客的想法。

那时候我感觉没什么可写的,然后算算域名、虚拟主机的费用,一年可能也要个500块,于是便放弃了。现在明白过来,既然这是一件收益如此大的事情,它能够记录自己,总结学到的知识,那么就不应该因为这一年仅仅500块的开销就搁置下来,应该是想到学更多的东西来让自己有所记录啊。想想这几年下来,又误了不少大好青春。

一件你认为是正确的事情,开始的越早越好,而不应该考虑一些细枝末节。

上课,下课。看书,休息。休息的时候,跑步是个不错的消遣的方式了。既能够提高心肺功能,还能够消散一些负面情绪。

这一年就这样过来了。

三、

最早坚持跑步的时候,是在考研那会儿吧。所有的科目都没有接触过,每天心情不太好,借助跑步分散注意、调节心情、提高身体素质。

起先奔驰在跑道上的那几天,总是感觉到有太多人跑在你的前面,不论你怎么加速,还是追不上他们的脚步。更严重的是,随着体力的消耗、透支,你离那个定位标杆的人越来越远,直到放弃了追赶。就在这时,在你后面的人也追赶了上来。

恰好一次,我遇到了一个同学,他也经常来跑步,我问了下他为什么跑那么快。

「哦,这个啊,我跑了很多年了啊,小时候身体不好,为了锻炼身体才坚持下来的。」他很不以为然的笑着说道。

可是,即使一个小时候身体不好的人,也都比我跑快了这么多啊。我听了他的话心里感叹道。

程序员未来要天天对着电脑,保持健康非常重要,于是我把跑步坚持了下来。

开学没一学期,发现很多同学也都有跑步的习惯,有几个同学跑得很快,于是我又上去问了问他们跑了多久。

「从大学就开始跑了,参加过很多次马拉松了,成绩是××……」,其中有几个同学这样回答道,同时脸上洋溢着略显自豪的微笑。

「怪不得」,我笑笑。

四、

几天的雨停了之后,天气很好,空气中弥散着没有雾霾的空气的味道。晚间我还是往常那样一个人去跑步。

遇到心情不好的时候,我会更想去操场跑跑步,希望能够将不愉快的情绪给发泄在这单调的往复回环的操场上。

跑步有个一年多了,虽然速度不快、长度也一般,但是收益还是很大的。

可能是跑道上雨水还未干透,操场上面的人比往日里少了很多。不过跑道上的景象倒是差不太多:有些人刚上来就加速很快,然后不久就慢了下来,被后面的人赶上;有些人匀速飞驰,甚至我都能认出一些熟悉的面孔;有些人拿着手机,悠闲地走在那儿,不会在意周边跑步的人们到底步伐怎么样。

我已经习惯了这样一个人沉浸在音乐中慢跑了,而且也很久不会和身边跑步的人赌气看谁跑的更快一些了。

你会知道周围的人到底跑了几圈?你会知道他今天跑了多久?你会知道他从开始跑步到现在有几年了么?

相反,我每天会带着运动手表计时,而不会带上略显累赘的手机;也会依据最近几天的睡眠状况,调整自己的速度。

跑着跑着,我突然意识到,刚刚开始学计算机的我,又何必去急躁呢?这条跑道上也终究只有自己一个人。那些本科阶段就已经是大神的家伙短期我也不可能赶上;那些早已融入了简单重复生活的人,我在不久就能够积累到比他们多的专业知识;同时,每个人会根据自己的兴趣,变到不同的轨道,更谈不上追赶与否了。

每个人的经历都是与众不同的,那个熟悉你爱好的、决定你未来道路的,有且只有自己。

跑步回来,因为又想通了一些问题,我心情很好,夜里又翻了翻龙应台的散文集《目送》。

在《山路》那节,恰好读到了一句话:「才子当然心里冰雪般地透彻:有些事,只能一个人做。有些关,只能一个人过。有些路啊,只能一个人走」。

「要是自己能够早点读到就好了」,我笑笑。每次读书仿佛都会有这种感觉。

「幸好现在也不晚」,我又接着告诉自己。

五、

16.04.28,周四,五一准备回家,29号晚上的票。因为周五一天都有课,所以提前一天收拾收拾东西,把几本宿舍里面放不下的与专业课无关的书给带回去——《全球通史》和《社会性动物》。

收拾好了,时间挺早,感觉外面阳光不错,于是出去站会儿。我们宿舍在一楼,橘四D138,最东南的那个拐角,终日见不到阳光。

我带上耳机,选择了宫崎骏的那首《talk about our old days》——在那些脑海里琐碎的记忆泛起点点涟漪的安静的时候我总是喜欢放这首歌。

快到傍晚了,阳光还是挺刺眼,我眯着眼迎着光照,趁着这不多的生命中忙碌的间隙,无忧无虑的伸着懒腰,孩子般的对着天空笑笑。

空气很好,手机上面显示的PM2.5的指数是67。你要知道,在我们这个时代,在这个城市,这样的日子是不多的。天空很通透,宿舍园子里面的小树叶子,也一改往日的灰蒙蒙的无精打采,泛出可人的绿莹莹的光泽。

这个点大家或是在上课,或是在实验室应付老板的工作,或是在和他们的好友们一道在球场上分享着在未来某天可能会终结的友情。哦,对了,我指的是研究生。

室外也挺安静的,除了大自然原本的声音——风声,其他一点嘈杂的声音也没有。

我伸着懒腰,享受着这短暂的悠闲的傍晚的阳光。

六、

我们实验室在学期末要搬到四牌楼,我回首着近一年的生活,能想到也就这么多吧。没有跌宕起伏,没有波澜不惊,有的就是滴滴点点的生活片段。

我闲逛在九龙湖校园中,梳理着这学年的生活,竟也有了些「悟以往之不谏,知来者之可追。实迷途其未远,觉今是而昨非」的想法了。

其实在快离开这里之前,我漫步过不知道多少次校园了吧——那些脑海里琐碎的记忆泛起点点涟漪的安静的时候。

才一年,我竟然也眷恋起了这没呆多久的地儿了。

16.06.22,周三,我把几乎所有的东西都搬到了四牌楼。花了好久,才把一年多没人住过的床铺给收拾好,自己的位子才稍显干净整洁一些。这个校区除了在市中心方便娱乐,在生活,学习方面,都没有九龙湖校区好。宿舍很小,食堂不如以前配置好。公共浴室容纳人数有限,到了人流高峰的时候很不方便。甚至还和以前的室友调侃到「舍友也是原配好」。

「又要适应新环境啦,住一段时间肯定会习惯的」,室友在橘园D138的群里面回复说。

其实,我从来没有怀疑过自己的适应能力。只是,即使是你适应了的环境,还是应该去怀疑它是否合理吧?如果每一个人都仅仅是适应环境,不去考虑怎样能够把它变得更好,那么这个世界会有创新?会有改变?会有更舒适的生活以及更符合情理的观念?

终究会有些人,不愿意踩着无数人踩过的脚印,再去重演一遍简单的生老病死,在适当的年龄读书,适当的年龄结婚生子,适当的年龄放弃对所谓的「命运」的挣扎罢?

我们的大学应该怎样度过

不同人过法不同。

大学阶段应该怎样度过,取决于你想成为什么样的人。但是很多学生(包括当时的我在内),由于个人见识和家庭条件的限制,其实是不太清楚自己想成为什么样的人(其实除了少数人,大部分学生也不会考虑到这么遥远的课问题的),就不太清楚自己该怎么度过。所以有些学生会因为参加了各种社团而荒废了学业,有些学生会沉迷于游戏连身体都弄坏了等等。这些我都迷茫过,也都思考过。现在我上研究生,感觉以前有些方面可以做的更好,但是确实时间回不去了,于是想把一些思考结果分享一下,也许能给后来进入大学阶段的学生有个方向性的指导。

因为每个人因为自身经历、条件不同,所以不可能适用所有人,所以我先把大学的阶段是什么样给介绍一下,也便于自己会思考、有想法的同学找到更适合自己的生活、学习方式。

大学阶段,对于大部分学生而言,是这样的一段生活:

  1. 第一次离开家,来到一个遥远的城市,感受不同的文化,和不同地域的同学居住在一个宿舍中。
  2. 第一次有机会,可以自主选择:选择课程、选择社团、选择朋友当然还有选择男女朋友以及是否要交男女朋友。这是一个接近自由的环境,所以这也是一个更需要自律的环境。
  3. 可能是最后一次,有如此长时间的宽松的环境,可以自主支配 ,可以试错。因为可能不少人会选择大学之后工作,如果选择的是在中国读研究生,就我现在知道的情况,工作还是挺辛苦的,相比本科阶段,自由支配的时间少很多了。
  4. 你可能在这个阶段形成比较完整的一部分世界观。当然,你的世界观还会随着未来的见识的丰富而完善 ,但是这四年,会形成一些基本的框架,甚至对于有些人而言,可能就会把世界观写封闭了。

好了,知道了这四年的特殊性、重要性,就更加容易讨论一些问题了。

一、生活

你可能会在一个语言、饮食习惯完全不同的城市上大学,这是一个很好的机会去认识不同的文化,增加自己的包容心。你的室友可能来自五湖四海,你会了解到不同地区的生活习惯,会分享自己家乡的乡土人情,这是每一个大学生刚进校都会接触到的事情。随着社会人口流动性的提高(当然,我个人感觉中国的流动性还是太低了),你会在未来和一些不同生活习惯、饮食习惯的人工作、生活,以一颗包容心对待不同的个性是非常重要的。比如我在大学时期,虽然没有到一个离家特别远的地方上大学,但是班级里面从内蒙、陕西到广州、海南的同学都有,感觉到这是一个不错的经历。

这四年是一段自由的时光,很多事情都可以自己决定,但是也容易因为自己的懒惰而浪费了青春、甚至是放弃了提升自己的最好的时期,所以这段时间一定要养成自律的好习惯。自律不一定是每天都按照一个点睡觉、起床,但是一定要能够明辨是非,在一些时候能够做出比较正确的选择。上大学之后我看过很多同学在玩游戏上面花费了很多的时间,不能说每个人都是在浪费时间,但是在我看来大部分人在这上面投入过多精力,尤其是那些整天熬夜的同学。而且你会发现一些有趣的现象,那些出色的人,即使玩游戏都玩的出色,那些愿意消磨时间,对很多事情得过且过的人,在玩游戏上面都表现的不好。当然,玩游戏本身没有错误,但是如果你不是想要成为电竞运动员,长时间投入精力,甚至熬夜玩游戏,都是不太值当的。

是否要谈恋爱呢?这个问题也是我想了很久的一个问题(另一个想了很久的问题是是否应该参加社团,下面会单独拿出来讨论,这个问题没有单独讨论的原因是因为它更加私密,越私密的问题越不容易一概而论)。我属于比较贪玩的那种家伙,然后本科专业的男女比例是35:1,如果要找妹子要参加社团或者更多的聚会活动等等,我感觉这有些浪费时间了,所以就没花太多的时间在这上面。大三、大四快毕业那会,看了一些给大学生的建议,有的说大学这个阶段一定要谈一段简单、纯洁的恋爱,学习如何照顾人、如何倾听另一半等等的益处,搞的我感觉自己大学有点不完整。但是到了研究生阶段,随着一些生活态度的改变,世界观又有了新的更新之后,又有了些新的思考。

谈恋爱确实没有想象中的那么必不可少。大学阶段确实比较单纯,是个找寻人生另一半的好时光,有各种人以各种理由说明找个对象多么重要。但是如果你发现了更大的世界,心中感觉自己以前基础较差,很多方面还需努力,那么还是在奋斗个几年吧。当你因为自己以往的不足和当下想要努力所做出的挣扎搞的满心烦躁之时,是不太可能处理好你的感情的。「人生若只如初见,何事秋风悲画扇。等闲变却故人心,却道故人心易变」这两句词大家应该都熟悉,我个人想到的,就是恋人其中一方或者两方,见识到了更大的世界,心中的努力方向变更了,双方的爱情观念不同了,所以分开了。亲密关系想要维系,应该是双方的成熟程度相近,并且成长速度都差不多的。如果一方努力另一方不愿突破自我局限,那么保持关系会很累的。而且,当你想要发愤苦读的时候,也许其他人有这样的想法呢,那么未来你会遇到的也是这样的人,你未来还会遇到他们的。当然,这个还看个人,每个人有不同的抉择,人生的选择总是在不停的权衡利弊得失,即使你没有显性的思考,潜意识里面肯定也是有一些权衡的。我所得出的结论是,谈恋爱没有想象中的那么必不可少。

二、学习

无疑,所有人都需要面对生活这个课题,每个人都会有社交,所以我把生活放在第一位来讨论。生活中最重要的部分,可能就算学习了。

我在《为什么我们的工资没有别人高?》中讨论过,未来别人付给你工资,主要就是因为你在某一领域或者某些领域,掌握了相对系统的知识。而上面说过,大学阶段,你拥有一个很长,而且可以自己支配的环境。在这样的环境中,你可以自己选择喜欢的方向、科目,系统的学习某些知识。

当然,这个方面每个人的喜好不同,不过我认为概括一下,应该不外乎以下几个方面:

  • 科学方面的通识教育
  • 生活技能的积累
  • 某一专业知识的积累
  • 社会实践的经验积累

    现在我来逐一说明。

首先是科学方面的通识教育。这个方面不是我们所说的数学、物理、化学等等知识,而是一些种类的入门级知识。比如,逻辑清晰绝对是科学方面的最重要的一个方面,而批判性思考又是科学里面很重要的思考方法。所以在大学阶段可以看看一些阐述科学、传授批判性思考的书籍。比如我以前看过的《学会提问》,感觉就是非常不错的批判性思考的书籍。同时,对我们生活影响较多心理学、经济学方面的一些入门级读物或者畅销书之类的也可以看看。比如心理学里面的《决策与判断》、《摇摆》、《心理学与生活》等,经济学里面的《微观经济学原理》等。其实如果你感兴趣,也可以看看哲学史,同学推荐我的《苏菲的世界》感觉也能看看。还有一个很重要的一点就是,应该看看关于生理健康教育(包括性教育)、中医是否科学等等方面的书籍或者讨论。就我个人而言(我是蚌埠的,一个小城市),以前家庭很多的观点,和中国现在一些尚未完全改变的一些错误的观念影响我们很多,但是确实有很多是不科学的。虽然不是所有我们都能改,都会去改,但是最起码我们应该了解一点吧。这些方面的书籍我确实没看过,就不推荐了,不过可以到果壳、科学松鼠会等等地方看看帖子。方向是,弥补一些我们大学之前,因为国家水平和家庭水平的现状,没有接触到的,但是应该接触的科学知识,理解科学的思考方法,学会独立思考。

第二个方面可以算是生活技能的积累。因为这个不需要特别刻意的花特别多的时间,而且在我看来,生活确实是生命中最重要的一个课题,所以我给列为第二条讨论。这个我想说的不算多,个人感觉离开了家,自己应该是一个独立成年人了,计算一些生活费用的开销,清洗衣物,关注自己的常用药品,定期整理自己书桌、电脑垃圾,每周做一些锻炼等等。总之,要学会照顾好自己。

第三点就是某一专业方面知识的积累了。我把这个列为第三点,有两个考虑:1.我个人感觉生活确实是生命中最重要的课题,没有之一。你怎么选择你的生活,才决定了后面的选择方向。2.有些同学(包括当时的我)应该上大学前没有自己感兴趣或者特别想努力的方向,到了大学才有了新的想法,但是与自己专业不符。基于以上两点,我将此排在第三。大学阶段,一定要系统地学习某一个方面的知识。学东西,越早越好。现在学习的技能,将是你以后从业的资本,你所赚到的工资,都是因为你所拥有的某项或者某些技能。显然,行业不同,薪资水平是不同的。当前,计算机、金融行业还是不错的,但是像心理学、生物等等专业的就业可能就不好。当然,这个也不是绝对的,不管你从事什么行业,你的薪资和你个人的能力绝对是成正相关的,而且,如果你真的是喜爱某个感觉收入不太好的学科,可以考虑读读试试的,如果成绩很好,家庭条件允许,出国读研、读博已经不是什么新鲜事儿了。如果能力足够,可以选择某个薪资不错的行业,然后业余发展自己的爱好,双管齐下,也是不错的。

最后,就是社会经验的积累。人总是社会的动物,不可能独立存在的。未来工作、生活,都要遇到不同的环境、状况。比如:你到医院排队不停被插队,你一直忍让还是强行理论;室友半夜结石疼痛难忍,叫救护车去ATM取款是否会把因为慌忙而忘记拔卡;自己一个人在陌生城市找路以什么样的语气,问哪些人能够更顺利;学车的时候(在某些不规范的场合、地方)是否遇到吃拿卡要(遇到所谓的潜规则)……这些都是我所经历过的,都需要细心观察生活中的琐碎细节才能更好的处理。所以这个也要多观察,别让自己吃亏。当然,不是也不去占人便宜。

三、社团

我本科没有参加过任何的社团,大三大四那会会考虑自己大学阶段过的是否完整之类的(比如也许我参加社团能遇到合适的妹子、找到一些志同道合的家伙之类),所以对这个也有一点看法。简单的说来就是:

  • 如果你学习踏实,本科不错,那么参加社团是个不错的选择。你可以认识不同的、有趣的人,拓展自己的视野,发现更出色的自己。
  • 如果你所在的学校不是特别好,整体平台不算高,而且自己又有自觉性能够努力看书,那么就发愤读书缩小大学之前的差距吧,不参加也罢。

现在的网络资源已经足够发达,很多东西都可以自己学习到了。

就我当时的大学而言,社团很多,但是正儿八经的没几个,而且都是耗费时间,那你去当廉价劳动力。即使到了后来当了主席能够指挥别人了,做的事情还是没有什么特别需要哪些能力的,提升的不多,有些东西通过观察、看书,也能理解。

当然,这个都是根据自己的特点,根据自己的喜好来的。比如你的学校可能不太好,但是某个社团确实精英云集(我个人感觉这个概率比较小),那么参加这个确实能学到不少东西,结交不少朋友。如果你确实学校不好(如果没有太好的标准,可以以你的学校是否是二本及以上来评判),而且没有太多的想法,那么就低头看书吧。相信我,机会总是留个有准备的人的。而读书,确实是最简单、有效,而且成本很低的方法。当然,我指的是比较正经的书,而且就赚钱这个功能性而言,非文学类的书籍才行,而且最好是领域内沉淀比较久的经典。

四、必学技能

想了想,因为我个人的价值观念(实现更出色的自己)和性格,自己想另外补充一点,感觉能够更好的提升自己,所以希望能够引起一些关注吧。

我个人感觉,如果想要人格独立,那么学会独处几乎是一个必不可少的阶段。什么是人格独立呢?我的理解是,自己有主见,在重大决策面前能够独立(不是独自,你会参考别人的意见,但不是让比人帮你决策)做出选择,自己在一些根本的问题上面有原则。学会独处能让你思考自己是谁,想成为什么样的人,哪些事情做的不对、哪些事情可以做的更好等等。这些都会在阅读、生活经历还有就是独处时思考自己的好恶、价值取向的时候,慢慢搭建成为较为稳定的框架。

英语。这个技能的作用几乎已经不用过多的阐述了,但是还有不少同学认为,如果自己不出国,或者工作之后不会用英语等理由说不学英语是可以的,那么真的有点可笑的了。研究生开始,你会阅读很多的英文文献,如果到时候再学,那么相当花费力气。互联网也将很多人在信息的获取面前变得平等的多了,你可能还会用英语搜索,或者通过网上的英语资源自学。当然,还有很多其它方面的。我想说明一点,千万别把通过四六级做为努力的标准,尽量多看看英文的网站,比如TED.com等等,练习英语的同时还能拓展视野。

融入团队的能力。很久之前,一个人想要做出很多的事情就不太可能了,更别说现在了。但是为什么我这边会再强调一下呢?因为现在上大学的同学们,很多都是独生子女,每个人在家受到宠爱,都有很强的个性,这很好。但是在团队中,总有些人有些奇怪的习惯、处事风格,要以包容的心态去面对。如果遇到了,尽量不要总是从自己的角度来说明自己受到了委屈,个性受到了压迫等等。所以大学是个很好的练习包容心的地方。

五、其他

也许看到这篇文章的你,可能还没有步入大学,也许大学阶段过半。但是有些未来的机会和选择,总是不确定的。比如我以前从未有过读博的想法,但是现在有了,遗憾的是,就算我能出国读博,因为跨专业太大知识没有积累,家里的积蓄也不能一直供我这样不停地试错,所以读博对于我来说性价比很低了。现在我将一些未来你可能遇到的机会给简单的写写。

1.读研与读博

上大学前就想到了读研,但是远远不会想到自己有想法去读博的。之前的一些想法确实太幼稚了,比如感觉研究生与博士生就是搞科研。

搞科研不假,但是对一个人发展的意义远不止于此。

1)你可以接触到更高的平台,认识更多志同道合的人,同时,你看那些出国读书回国创业的人,估计就是因为拓宽了自己的视野,学到了前言的技术,找到了更多的队友,而且遇到了投资人,才能将自己的愿景实现的。

2)如果你的科研方向和本科一致,而且功底较扎实的话,科研的任务还是能够顺利完成的。学校的环境更简单,你还有更多的时间思考自己。

3)科研本来也就是一种人生的经历罢?探索、坚持的能力,在哪都需要的。

2.关于出国

现在出国的门槛越来越低了。身边的同学出国的经验,让我对出国有了一些想法,总结到这儿。

1)如果家庭条件允许,出国读个好学校的研究生是比较划算的。英国等一些国家及地区的研究生时间比国内一些3年的研究生要短,而且学术氛围相对要好,你更早的毕业了回来拿着国外的证书,有更好的敲门砖更早的拿工资,不会亏的。比如我有个同学去的港大,价格相对去国外便宜一点,一年半毕业,文凭我想会比国内很多的高校的文凭更好一点吧。如果有机会,尝试着申请一下吧。

2)因为要申请好学校,所以,大学阶段的学分、绩点啥的,一定要保持不算低。开始你没想到出国,到时候有机会了,突然发现自己绩点等等硬性条件不够,后悔去吧。

3)申请国外高校,要英语的。

3.旅游

我个人感觉,在这段可以自由支配的时间里面,不管是因为现代化还是风景吸引你,到不同的城市,出去多跑跑都是很好的选择。你会丰富自己的经历,可以去看看未来想定居或者工作的城市,亲自去看看书中所描述的令你想去一探究竟的地方,和同学一起出行能够学习到teamwork,自己独行能够学习规划线路和应对一些想象不到的问题。总之,趁着年轻多跑跑。

六、一些问题

我为什么要啰嗦的写这些文字呢?就我个人的经验来看,大部分人是不会,甚至不可能照着这些方面都完成的,包括当时大学阶段的我。在那个时候,我看了李开复老师的《给大学生的七封信》、《做最好的自己》等等,同样也是从我个人的经验来看,虽然我没有照着这些做,但是确实收获很多:

1.拓宽了自己的视野。很多人不能实现更出色的自己,是因为他在一些黄金时期没有认知到更大的世界。如果让他发现了更广阔的空间,他可能在这段时间、精力都很充沛的一段时期,挣脱一些束缚。

2.发现了自己的不足,同时有完善的措施。
3.发现原来有些人,竟然是以这样的方式思考、审视自己的。

问:你可能会说,只要低头努力就可以了,很多人这样都成功了,看这些没用的是浪费时间。

答:有方向、有方法的准备一件事情,比起蒙头苍蝇似得乱撞,往往会事半功倍,更加游刃有余不是么?

问:我在其中没有给出特别详尽的计划与评价标准,这有什么用啊?

答:从我个人的经验来看,这样一份宏大的展望,详尽是没有用的。每个人想成为的自己,想要努力的方向都不同,我只是提出一些方向性的建议,希望能够拓展你的认知。变化永远存在,不可能有一份清单,能够适用任何人,任何情况的。

问:你这写东西网上都太多了,有什么不同么?

答:是的,这些告诫等等的每个人都能说出一堆,我个人是这样认为的:a.网上很多都是很有名的写的,我是个普通的学生,现在不停的突破个人的局限,探索更大的世界,实现更出色的自己。我写这些,希望让人感觉到,做到这些,不仅仅是那些少数的人。我在做更大的努力,是因为同学中,有人做的更出色。b.每个人给的建议侧重不同,这是我,以一个结束大学生涯不算久的研究生写的,也带有自己的价值取向。c.推陈出新,结合自己的经验,希望把踩过的坑给分享出来,希望有更多的人能够突破自我局限。

问:从语文的角度来说,这篇建议中没有重点,没有中心,什么都是泛泛而谈,那么有什么用呢?

答:我的中心是鼓励你实现更出色的自己。文中提出一些当时你可能没有在意到的局限,我将这些给列出来,希望你能考虑到自身的情况来审视一下自己努力的方向。一件事情有用没有,真的不好从一而论。况且,当你一股脑的只想着一件事情的时候,更容易选择性的无视其他方面的事实。

最后介绍一下自己的情况,看看能不能给大家一些激励吧。本科的专业叫做弹药工程与爆炸技术,大二大三班级第一,获得过国家励志奖学金,甚至因为专业特殊,大三下学期有西班牙爆破公司来招聘,有机会带薪去国外读研。但是自己感觉不是特别喜欢,而且现在计算机行业还算不错,所以跨专业到了计算机。我在探索更大的世界,去实现更出色的自己。

当然我说这些不是想说自己厉害啥的,只是想表明这样几个事实:

1.如果不是因为我当时坚持了自己,没有因为不喜欢自己的专业就给时间浪费掉,西班牙公司来招聘的时候能有机会么?

2.如果不是我在有些方面准备的相对充分,在面临考研这个选择的时候,我能够坚定的选择跨考一个几乎没有认知的行业么?我当时的大学同学中,很多人是不信想我会做出这样的举动的。对了,上面的文字忘了说句,不要相信大学就是尽情享受之类的言论。

3.相信我,我没有多厉害,或者多不厉害。我将一些努力过的途径,以及自己对自己努力方式的思考,写在这儿,如果你有些想法,评估了一些风险之后,为什么不尝试一下呢?

相信聪明的你,也能找到更出色的自己。

借寒冬之名

这是16.01.24号写的,现在给腾上来。

一、

你知道吗?今天是南京25年来最寒冷的一天呢。

大朵的雪花不停地飘下,遮掩住了城市的喧嚣,让夜显得更加的静了。昨日一早,蓄势已久的大雪已经趁着人们在熟睡的时候悄然离去,方便人们欣赏这美丽的雪景。全国各地仿佛都在这几日迎来了许久不见的大雪,同学们在空间中、朋友圈里晒着他们自己或是不经意间、或是寻觅各处所拍到的雪景。这一张张照片,可能洋溢着他们遇见这久违的大雪的欣喜;也可能弥漫着他们捕捉到如诗如画瞬间的得意;亦或许,是他们也不想错过了这个机会,表明自己还在某个角落默默地努力着。

你看,大兴安岭加格达奇摄影爱好者们,相约来到城市最南面的甘河大坝和政府大楼广场,冒着-32℃严寒,用手中的相机记录下这精彩一刻。新浪微博上也博得了人们的眼球。

泼水成冰
                                              泼水成冰

连几乎一辈子都没见过雪花的广州人、重庆人,也纷纷在微博上分享者他们偶遇飘雪的欣喜,也让我们感到了不同的快乐。重庆人民的雪人比广州人民的雪人大那么多呢!

03
                                                重庆人民的大雪人
02
                                        广州人民的大雪人

今日,南京最低温度-10℃,最高温度-5℃。这寒潮给南京带来了25年以来最寒冷的一天。每一次出门,都是一次挣扎,极低的温度加上刺骨的寒风,让人们在不知不觉中学会了爱尔兰踢踏。昨日铺满地上的雪结成了冰,尽管同学揶揄着我的幼稚,我还是在冰上乐呵呵的跑来跑去,玩的不亦乐乎。

二、

「这周末还来无锡玩么?」 几日前,同学给我发来微信问我。

「不去了吧,天太冷了。待四五月吧,恰好去看春暖花开。」我回复到。

看到这周末的天气预报之后,我也改变了计划。许久之前都盘算好了,想要在学期末找个近处,出去走走。可惜天气偏不予人方便,只得暂且搁置在这。

当然也感谢这天气,让我能有机会静静的整理一下思绪,让能够我尽情享受将烦恼抛之脑后的时光。

上次我无忧无虑享受着时光从身边飞快溜去的日子还是20天前。当时我们考完了算法和模式识别,那个下午我在寝室看电影《小王子》。毕竟这是我看的第一本英语版本的书籍啊,怎么能不欣赏下电影么。当然我不会跟你说,我这辈子到现在也只看完过这本完全以英文印刷的书籍的,当然除了英语书。

之前室友就说考完政治之后一起去看场电影吧,毕竟也那么久没出去了。我有些不太想去,只想在寝室休息一下,毕竟几天之后还有考试。

看到《小王子》精彩的部分,室友又在群里商量着看电影的事情,问我去不去。

当小女孩想要逃离那个规划完整的人生大计的时候,当小女孩逃过了自负的警察逮捕的时候,当小女孩巧妙的说服了掌控电梯的国王到达顶楼的时候,当王子先生反叛了教授的命令的时候,当王子先生无视了商人的嘲讽的时候,当王子先生和小女孩乘飞机快要逃离了满是高耸楼宇以及步调整齐、成熟如一的大人们的星球的时候。

「我去。」我在群里回复到。

原本我可以多花点篇幅介绍一下小王子的剧情,用点心思将我想表现的主旨和《小王子》的剧情给串联起来,这样就能即不失美感又不显突兀。

可是我没有这样。我不愿让自己落入那略显俗套的剧情之中,即使是在天马行空之后我笔下所堆砌出来的文字。

「是的。」

三、

大雪不告而别的那个夜晚,我躺在床上久久没能入眠。

窗外,晶莹的雪花悠闲的飘下,落在枯枝上,盖在屋顶上,铺满了宿舍外的公路上。连距我们宿舍之外仅有二三十米远的公路,都安静了许多,少了平日里车辆来去的嘈杂。大雪有种魔力,它能够将绿叶离去的枯枝再显生机,将单调的屋顶彰显个性,将令人生厌的嘈杂的公路也带去宁静。它能够将我的被理工科思维中逻辑部分所僵化了的大脑,也灵动了起来,闪现着五线谱上俏皮的乐章。

我躺在宿舍床上狭小的空间翻动着身子,一遍又一遍。

我在思索着之前的一个决定,想着如果不踏进计算机行业会怎样。毕竟这个决定的机会成本很大。或者在我看来,很大。

以前在看《浪潮之巅》的时候,看着书中那些科技公司,或是抓住了机会,扶摇直上;或是没有紧跟时代的节奏,被抛之千里;或是举起了前人的大旗,继续昂首前行。真的犹如见证了难得一见的潮起潮落一般,振奋人心。不是谁都可以成为弄潮者;想要迎着潮水持续高涨不落下,更是不可能。不过我想这互联网的浪潮还没有退去,能够做个观潮者,能够站在这风口浪尖,亲历潮水的起落,或许也是一种惊心动魄的体验吧。只是这潮水不同的是,没人能预测得到它什么时候能够涨到最高点,没人能预测的到它什么时候退去。

睡意不知不觉的袭来,我打了个哈欠,眼里涌出了泪水。我向左侧翻了下身子,泪水从眼角划过。

四、

今天是25年中南京最冷的一天。经过了持续一周的雨雪天气,昨天天晴了。天气格外的好。这两天我在寝室到食堂的路途中,想去发现一些非同寻常的美丽,弥补一下没能逃离这熟悉环境的遗憾。

今天是一个月圆之夜。

喏,我把它分享给你。

月亮01

 

如何停止焦虑?

这是以前看过的一篇英文文章,原名为How to stop overthinking: 9 Simple Habits. 直译过来应该是《如何避免过度思考:9个简单的习惯》。当时感觉文章说的一些观点比较不错,而且是帮助人们提高执行力的,所以想到给贴出来。这是大概两三年前翻译的吧,英语能力有限,所以有翻译不恰当的地方欢迎指正。

以下是正文内容:

是什么阻碍了那些想要好好生活的人们的正常生活?

我认为,有个非常普遍、并且非常具有破坏性的问题就是他们想的太多了。

他们过度的思考了每个小的问题,直到这些小问题逐渐变大、变得可怕,然后就真的发生了。他们过度的思考了一些原本是是乐观的事情,直到事情变得不那么乐观。

或者他们过度的分析一些事情,以致他们错过了那些源于享受某些美好瞬间所带来的快乐。

当然,仔细的思考问题是个好事。不过,过度的思考会使人们裹足不前,会使人们自己破坏了那些发生在你身边的美好事情。

这一切我都了解。我过去就是一个过度思考的人,过度的思考使阻碍了我的正常生活并且使我终日愁眉苦脸。

大约八年前左右,我学会了怎样使这个问题变小,并且使它尽量不再发生。如果我再次陷入过度思考之时,我知道该做些什么来克服它。

在这篇文章中,我想要分享9个习惯。这些习惯帮了我非常大的忙,使我成为了一个简单并且智慧的思考者,并且使我的生活多了几分快乐,少了几分忧愁。

1.把问题放到一个更大的时间范围内考虑

人们容易在小的事情上陷入过度的思考。所以当你正在思考事情的时候,试着问问自己:这些事情在5年之后还会困扰我么?在5个星期之后呢?

我发现,把事情放到更大的时间范围内考虑这个简单的办法可以使我迅速的摆脱过度思考的状态,让我把时间和精力专注于真正困扰我的事情上来。

2.在做决定之时设置一个较短的限制时间

在你必须做一个决定并且需要采取行动的时候,如果你没有一个时间限制的话,你会不断的思考这件事情,从而使你大脑中的每个角落都浮现出这件事情,然后这个状态会持续很久很久。

所以,在日常生活中,应该学会更好的做出决定,并且在截止时间之前开始行动。不论这是一个小的决定还是大的决定。这些是对我来说非常有用的小方法:

  • 对于一些小的决定,例如是否刷盘子、是否回复一封电子邮件、是否进行锻炼,我通常给自己30秒或者更少的时间来做出决定。
  • 对于大一些的决定,在过去总是会花费我几天或者几周的时间来思考它们,而现在我给自己限定在30分钟内做决定或者是在这周的工作日之前。

3.做一个付诸行动的人

当你明白了如何能够持续的以采取行动来开始一件事情,那么你会花费更少的时间来过度思考。

设置时间限制的方法使我成为了一个更加善于付诸行动的人。

每次完成任务的一小部分,并且只专注于完成这一小部分的任务,是另一个非常有效的方法。

这方法真的非常有效。因为你不会感到备受打击,所以你不会想要拖延你的时间。即使你仍感到有些害怕,不过每次完成任务的一小部分是件比较容易的事情,不致使你陷入担忧之中。
4.意识到你不可能掌握一切

试着将问题彻底思考50遍可能是能够掌控一件事情的一种方法。如果你把所有可能的结果都给想过了,那么你就不会出错、失败或者看上去像个傻子。

但是这些事情是生活的一部分,是生活中能够扩展你舒适空间的事情。任何你欣赏的人或者在生活中给予你鼓励的人都失败过。他们也都犯过错误。

但是在大多数情况下,他们仍然把这些失败看成是学习中弥足珍贵的反馈。这些事情看上去可能是负面的,不过这些事情使他们收获很多,为他们的成长提供了不可估价的帮助。

所以放弃去试图掌握一切事情。这样做可能毫无用处,因为没有人可以看到未来的所有可能发生的事情。

这当然也是说的容易做的难。所以以你喜欢的方式慢慢的尝试它吧。

5.在自己知道自己不在思考状态的时候就要停下来

有时候,当我饿了或者躺在床上准备休息的时候,一些负面的想法就会在我的脑海里打转。

在过去,它们可能会对我影响很大。但是现在,我可以更快的意识到此并且告诉自己:不,不,现在不是思考这些问题的时间。

我知道,当我饿了或者困了的时候,我的大脑不太能够进行清晰的思考,而且容易朝着不好的方面去考虑。

所以在我告诉自己不要再思考下去之后,我还会告诉自己,当我知道自己的大脑能更好思考的时候,我会再将这个问题仔细地思考一遍。

例如,当我吃过一些东西之后或者是已经睡了一觉之后,我会把问题再思考一遍。

养成这个习惯也需要经过一段时间的练习,不过我真的从这种推迟思考的方法中受益良多。根据我的经验来看,当我在头脑清醒的时候再次考虑这些问题,80%的问题都是很容易就能够解决的。

如果真的遇到了一个棘手的问题的话,我的大脑也已经可以更好的处理它,并且可能提出更加富有建设性的方法来解决它。

6.不要陷入未知的恐惧之中

另一个多次使我陷入过度思考的问题是,我会陷入生活中未知的恐惧之中。所以我就会胡思乱想,想象着如果我做了某些事情可能会带来的糟糕的后果。

然后我学会了质问自己:仔细的想想,最坏的结果能是什么呢?

当我想出了实际中可能发生的最坏的结果是什么之后,然后我还会花一些时间思考,如果这个不常出现的事情真的发生了,我能做些什么。

然后我发现,现实中真正可能发生的最糟糕的情况并不像我想象的那么可怕。

通过这种方法来明晰你的思路,通常只需要花费几分钟的时间和少量的精力。不过这可以帮你节省下许多时间并且使你避免痛苦。

7.锻炼

这听起来可能有点令人不可思议。但是就我的经验来看,锻炼,尤其是举重,可以帮我赶走内心的压力和担忧。

锻炼经常能够使我更加果断,同时当我处于过度思考的时候,它能使我大脑停止过度思考,使我的思想变得更加富有建设性。

8.花更多的时间来关注当下

在日常生活中,通过更加关注当下的事情而不是考虑过去或者未来可能发生的一些事情,这样你会花更少的时间在过度思考之中,而有更多的时间可以关注当下。

以下三种方法是我常用的,能够使我重新关注当下事情的一些方法:

  • 放慢你的节奏。放慢你现在正在做的一切事情的节奏。例如,步伐放慢一些、说话的节奏放慢一些、把自行车骑得更慢一些。这样做你可以更清楚的了解到自己使用肢体的方式,并且使自己感知到你周边发生的事情。
  • 告诉自己:我现在正在做……我经常告诉自己:我现在正在做……你可能正在刷牙、可能正在森林中散步,或者是正在洗碗。这个简单的提醒帮助我停止胡思乱想,并且重新使我的注意力专注于正在发生的事情。
  • 打断你的思想并且重新关注当下的事情。如果你认为自己陷入了过度思考之中,那么你可以告诉自己:停下!然后再花上1-2分钟的时间全神贯注于发生在你周围的事情来使你的大脑重新关注眼前的事情。努力的调用你的一切感官——触觉、听觉、嗅觉和视觉以及用你的肌肤去感知当下发生的事情。

9.花更多的时间与那些不会过度思考事情的人们相处

你的社交圈对你的思考方式影响很大。这里的社交圈不仅仅指生活在你身边的那些人或者团体,而且还包括了你所阅读的、你所听到的和你所看到的。这些都包括:你看的博客、书籍、论坛、电影、以及你所听的播放列表和歌曲。

所以思考一下,不论在你身边与否,是否存在一些能够使你更加倾向于过度思考的人。并且思考一下,是否有与之相反的人。

花更多的时间和注意力在能够对你的思考有积极影响的人和事情上,花更少的时间和注意力在那些对你过度思考习惯有加深趋势的事情上。

生命中,会,或者不会遇到的一切

人生是由苦难交织的,自古圣贤皆寂寞,财乃身外之物,死亡是人生的一部分,朋友很重要,以及要听妈妈的话。

等等等等。生命中,会,或者不会遇到的一切,都出现在了《阿甘正传》这部电影当中。

昨天,我都不会想到,我今天会看完这部电影。甚至曾经,我都不会想到,自己能静静地看完这部两个多小时的完全没有提供我新的信息、知识的电影。

可是今天我却看完了。

生命中每一个新日升起的一天都非常令人充满期待。

就像电影中说的那样:

Life is a box of chocolates. You never know what you're going to get.

摘抄几句不错的句子,分享在这儿。

Death is just a part of life. Something we are all destined to do.

I happen to believe you make your own destiny.

——What's my destiny, mama?
——You're going to have to figure that out for yourself.

There's only so much fortune a man really need and the rest is just for showing off.

I am not a smart man, but I know what love is.

You got to put the past behind you before you can move on.

Sometimes it would stop raining long enough for the stars to come out and than it was nice.

信念,甚至信仰,就是你对简单的东西的执着。

羽毛飘落,到了阿甘的脚下。

羽毛飘走,也从阿甘的脚下。

They just couldn't believe that somebody would do all that running for no particular reason.

为什么我们的工资没有别人高?

为什么有些人工资能拿那么高呢?

我经常会思考一些暂时没有出现的问题,希望以后真的遇到这样的问题的时候,能够有个准备。

想要弄清这个问题,我们首先要理解别人给你发工资的依据是什么。

我想有人会说,领导给我们发工资,是根据每个人的「能力」来评定的。但是「能力」依然不能让我们清晰地理解它到底是什么。我个人认为,只有当你对一件事情理解到特别透彻,并且你在向别人解释它的基本概念的时候,别人也能轻而易举的理解,才能说明你真正的把一件事情给分析、理解透彻了。

我是这样理解「发工资的标准」这个问题的。领导发给你工资,是根据你系统地掌握某一领域或者某些领域的知识的总量所决定的。

上面这句话可能有些拗口,我来举几个例子。

比如,我未来可能是程序员,程序员需要掌握的基本知识有:数据结构、操作系统、一门编程语言以及数据库等等。当然,有些领域的程序员还要掌握计算机网络的知识,图像的领域还要掌握信号的知识,这些我就不一一举例了。(我个人刚刚跨专业到计算机,很多东西了解的也不够深刻,所以上面如有错误,请指出,谢谢。)如果你仔细观察,那些程序员中工资拿的特别高的,全部是他对这些基础知识掌握的特别牢固的人。同时,你会发现还有一些程序员工资更高,超出一般程序员很多,那是因为他系统地掌握了更多的知识,比如,他同时熟悉好几门编程语言,他对很多编程领域的知识都很了解等。所以,他的工资又会突破一个瓶颈。这样的人都可以在一些横向领域起到关键性的作用。我以前看过一个句子,现在记忆犹新:

No field of study can advance significantly unless outsiders bring their knowledge and experience to that field of study.

有些跨领域人才的工资,是因为他使得某些领域大踏步的进步了好多,所以他们工资会让人不可想象。最近今年,机器学习因为计算机性能的发展,带来的新的机遇,所以那些熟悉两个领域的知识的专家在一些行业发展起来之前,已经收入不菲了。

程序员的例子可能不是每个人都能理解,我再举一个生活中随处可见的例子:餐厅服务员。虽然餐厅服务员可能不需要掌握数学、物理、化学等等知识,但是他们需要处理好「与客人之间的关系」:当遇到态度不好的客人的时候要怎么做,当遇到自己餐厅出问题了怎么解决能够使得店主和客人都能接收等等。这些能力虽然书本上或者说我们课堂上没有传授,但它确确实实是一种技术。尤其是在中国这样人口众多的国度。所以,那些处理关系得当的服务员,晋升为餐厅经理,甚至有些人把店主的进货渠道给打通,自己开店去了。这就是因为他们系统地掌握了:「与人交流」、「管理服务员」和「处理更加困难的纠纷」以及「开餐厅」的知识或者能力。

生活中人与人之间的工资差距那么大,就是因为有些人系统地掌握了更多的知识。

注意,我一直强调是系统地掌握,而不仅仅是掌握。其实,年纪差不多的人,掌握的信息的总量是差不多的,因为从统计学的角度上说,大部分人每日的睡眠,饮食等等时间花销,差别不大。常见的,有些人会打打游戏,有些人也在处理人际关系表现不差。但是,这些人没有能够系统地掌握这些方面的知识,所以他们的工资没有突破某个瓶颈。这不,在现在这个开放且快速发展的中国社会,游戏上面有天赋且愿意努力训练的人也能拿到很好的薪水了不是么?所以我们可以观察到,那些出众的人,知识的掌握程度较为专一,在有些方面真的是一窍不通。因为他们把时间都专注于系统地学习其他方面的知识了。

那么我们想通了这些有什么用呢?

这就可以为我们以后的努力方向提供方法论了啊。

比如,我们应该放弃一些暂时会给我们带来快乐,但是长期不会给我们带来收益的事情。年纪大了,我们会发现自己玩游戏的注意不集中了,反应能力也没以前好了,所以可以适当的放弃些打游戏的时间了。每日都有人花大量的时间在刷微信和一些娱乐新闻上面,但是仔细思考,这样事情只能影响当下,我们是否可以放弃了。摄影、阅读,都是能够修身养性的事情,我们是否可以利用一些碎片时间来培养这些爱好,长此以往,五年十年之后,这些方面的知识可能就比较成系统了,即使不能给你带来金钱的回报,但是在自己家庭、朋友圈子中,也足以露一小手,显摆一下,这些都可以提高生活质量。

当然,我并没有说不玩游戏、或者不刷娱乐新闻等等。毕竟这也是普通人生活中的一部分,只是我们不要太过于执着其中罢了。比如,久违相逢的好友,坐到网吧,来上一局dota,也是友情不减当年不是?对了,我指的是男性。

知道了为什么再去努力,我们会更坚定,不是么?

 

这是最近总结的一些想法,自己的思考可能因为见识的局限而不太成熟,未来可能会在更新。如需转载,请保留原文链接,谢谢。

如何能够提高语言表达能力

如需转载请保持原文链接,谢谢。

生活中,我们有时会发现自己的语言表达能力不太好,最近发现了一些心理学的研究可能能够解释这个问题。

先修知识

我们的大脑有两个半球,不同的半球负责的功能不是完全相同的。同时,左半球接收身体右半侧的感觉传入,支配右半侧肌肉运动;而右半球接受身体左半侧的感觉传入,支配左半侧肌肉运动。大脑左半球擅长语言、写作和阅读等,是主要的语言中枢。大脑右半球在解决空间关系、符号推理和艺术活动等方面更有优势。人脑中有一个叫做胼胝体的结构,大脑通过它连接左右两个半球,使得信息能够在两个半球间相互传递。

实验内容

为了研究大脑两个半球的功能,心理学家做过一系列实验,对于切除了胼胝体的严重的癫痫病患者(这些疾病的治疗需要切除胼胝体,所以没有伦理学的争议)进行视觉、听觉和触觉的测试。

一个实验是对视觉进行测试。在进行实验时让被试(切除了胼胝体的严重的癫痫病患者 ,下同)面前放有水平排列一排灯泡的木板,并且用一些方法使得这些灯泡只能投射到大脑的左半球或者右半球的单侧区域(称为“视野”),而不是同时让大脑两侧都看到。开始时,灯泡在被试的左、右视野依次闪烁,但是当询问被试的时候,被试说只看到木板右侧灯泡闪烁过。之后,心理学家让被试的左视野上(大脑右半球接收信息)的灯泡闪烁,被试却说什么也看不见。随后再一次让所有灯泡都闪烁,被试依然只能说出右边的灯泡闪烁,但是当心理学家要求被试用手指出哪些灯泡闪烁过的时候,被试能够指出所有闪烁的灯泡。这个实验得出的结论是,被试的两个大脑同时接收到了视觉信息,但是由于左半球负责语言功能,所以只能够说出右侧的灯泡闪烁。

还有一个实验是对触觉能力进行测试。让被试右手(大脑左半球)触摸一种物品,但是不让其看到或者听到,这样被试能够叫出物品的名字,并能描述它,指出用途。然而,当同样的物品放在被试的左手时(大脑右半球),被试不能说出物品的名字,也不能描述它。但是,此时把不同的物品放在被试面前,让他分辨刚才左手所触摸的物品时,被试能够找出来。这个实验同样显示,大脑左半球接收到信息后,能够用语言表达出你所接收的信息,但是右半球不能。因为大脑左半球是主要的语言中枢。

同时,心理学家还对被试进行了情绪反应的测试。他们突然给一名女性被试大脑的左半球呈现一张女人的裸体照,这名被试能够描述出图片的内容,并且脸上会有狡黠的笑容。然后当这张照片呈现给她大脑的右半球时,被试不能说出这张图片的内容,但是脸上还会露出相似的笑容。这说明视觉刺激能够在大脑两个半球引起类似的情绪反应。

从这些实验我猜测,生活中有些人语言表达能力有些欠缺,是因为他想表达的部分信息是主要通过大脑右半球处理和加工,且未被写入大脑的左半球,这样负责语言的那部分区域无法识别并且提取。所以如果我们要想提高自身的语言表达能力,应该把想要表达的内容写下来并且阅读、朗读记忆,这样才能够让这些信息被大脑左半球的语言区域提取,从而更好的表达出来。

同时《改变心理学的40项研究(第五版)》中《一个脑还是两个脑》一节中还写到:

即使大脑完好无损的正常人,大脑两半球之间的联系也并不完全充分。例如,如果特定的信息,比如形成某种情绪的信息,没有以语言的方式存储起来,大脑左半球就不可能提取它。结果就可能是你感到伤心,却说不出原因。由于这是一种令人不适的认知情景,大脑左半球会试图用语言寻找一个原因来解释这种悲伤(毕竟,语言是它的主要工作)。然后,由于大脑左半球不具备所需的充足资料,它的解释可能是完全错误的!

虽然说可能很早前我们就知道,把想要表达的事情默默重复几遍可以提高我们的语言表达能力。但是现在我们知道了为什么这种方法能够奏效,执行起来会更加坚定不是么?

参考文献:
1.《改变心理学的40项研究(第五版) 》

Much to Live for

刚把属于自己的博客给弄好,所以迫不及待想在这个属于自己的一块空间上面留下些什么。

这是以前看到的一首小诗,遇到烦心事的时候会读读背背。没找到出处,最早是在一期疯狂英语杂志上面看到的。

Much to Live for

There is so much I have not been, so much I have not seen.

I have not thought and have not done or felt enough — the early sun, rain and the seasonal delight of flocks of ducks and geese in flight, the mysteries of late-at-night. I still need time to read a book, write poems, paint a picture, look at scenes and faces dear to me. There is something more to be of value — something I should find within myself — as peace of mind, patience, grace and being kind. I shall take and I shall give, while yet, there is so much to live for — rainbows, stars that gleam, the fields, the hills, the hope, the dreams, the truth that one must seek.

I’ll stay here — treasure every day and love the world in my own way!

最近被很多事情搞的心烦意乱。抱怨什么的有用么?没有啊。所以我会找个事情来分散一下注意:比如看看这首诗,想想自己想做的事情,还有就是把遇到问题的思考和解决方式给写到这里。

献给每一个对未来困惑但依然坚持心中信念的人。

这个世界上还有人和你一样的,加油。