还记得在考IELTS的前一天晚上时,和班里的一位天才同学在大工本部的旅馆里练习英语口语,当时就聊到了Economics,这时他提到了一个人名Mankiw和一本书Principles of Economics。根据他的描述,这本书是经济学入门的绝佳教材,通俗易懂,言简意骸。
这个同学的眼光我还是很相信的,况且一直想找个机会学习下经济学,于是在IELTS结束后的那几天,上了趟当当,搞定了这一套书,一共三本,宏观经济学、微观经济学和学习指南。
之前断断续续的看了前面的几章,现在打算再重新来一遍,彻底的先把微观经济学这本分册阅读一遍,呵呵,算是养成一种经济的头脑吧。
不像其他的书废话套话那么多,Mankiw的这本书第一章即是全书的精华所在,也就是经济学的十大原理。
首先要意识到,我们离共产主义还有一段日子呢,呵呵。所以要了解稀缺性(Scarcity)这个概念:社会拥有的财富资源是有限的,因此并不能生产人们所希望拥有的所有物品和劳务。而经济学(Economics)呢,就是在这个稀缺的前提下,来研究社会如何管理自己的稀缺资源。同时要意识到,社会的资源并不是有一个全权的独裁者来配置,而是由千百万家庭和企业的共同行动来配置的。
原理一:人们都会面临权衡取舍。
要知道天下并没有免费的午餐,为了得到某一样东西,通常就不得不放弃另外一样东西,也就是说,我们需要在一个目标和另外一个目标之间作出取舍。
社会经常面临的取舍是在效率和平等之间,效率(Efficiency)是指社会能从其稀缺资源中获得的最大利益,而平等(Equity)则是指将这些资源的成果公平的分配给社会成员。换句话说吧,效率就是指经济蛋糕的大小,而平等就是指如何去分割这块蛋糕。政府经常需要在这两者之前做出取舍:比如说,当政府把富人的收入再分配给穷人时,实际上等于降低了对辛勤工作的奖励,结果就是,人们对工作的热情减小了,生产的物品和劳务也就变少了。
原理二:某种东西的成本是为了得到它所放弃的东西
人们往往会面临各式各样的权衡取舍,因此做出决策时就要比较这些方案的成本和利益,但多数情况下,某种行动的成本不是一下子就能看出来的。
比如说,是否上大学的决策。这个决策的利益是丰富了知识,而且会拥有更好的工作机会。但也要考虑到成本,这里的成本并不是大学生活中学费、书费、伙食费等费用的总和,因为这些总和并不能真正代表上一年大学所放弃的东西。
上大学的最大的成本不是在于那些费用,而是时间。当你把这四年的时间用于听课时,很自然的你就不能用这些时间去工作,对多数学生来说,为了上大学而不得不放弃的工资是他们受教育的最大单项成本。至于大学中的伙食费和住宿费,即使你在大学以外的地方,你仍然需要吃穿住行,实际上大学的住宿费和伙食费往往比你单独生活时的费用低很多,这时,节省下来的那部分住宿费与伙食费反倒成了上大学的利益。
同时在这里给出一个非常重要的概念:一种东西的机会成本(Opportunity cost)即是为了得到这件东西而放弃的东西。
原理三:理性人考虑边际变量
在经济学中,往往把人假设成是非常理性的。如果机会成本既定,理性人(Rational people)系统有目的的做可以达到其目的的最好的事情。
现实生活中的很多决策并不是那种黑与白的抉择,而往往是介于其之间。打个比方,当考试临近时,你不会在放弃考试和一天学习24个小时做选择,而是是否多花一小时来复习功课。经济学家用边际变动(Marginal change)来描述对现有行动计划的微小增量调整。理性人往往会通过比较边际利益(Marginal benefit)与边际成本(Marginal cost)来作出决策。
有没有想过,为什么水这么便宜,而钻石确那么贵呢?毕竟人们需要水来维持生命,而钻石并不是不可或缺的。原因就是:人对任何一种物品的支付愿望都基于其边际利益,即物品产生的额外利益,反过来说,边际利益又取决于一个人拥有多少件这样的物品。尽管水是不可缺少的,但是由于水太多了,因而增加一杯水的边际利益微不足道,相反的,钻石就太少了,人们认为增加一块钻石的边际利益是非常大的。也就是说,当且仅当一种行为的边际利益大于边际成本时,一个理性人才会采取这种行为。
原理四:人们会对激励做出反应
大家都知道乘车要系上安全带,但如果告诉你系安全带不但不会降低死亡率,反而会提高死亡率,你相信吗?
激励(incentive)是引起一个人做出某种行为的某种东西,因为理性人通过比较成本和利益作出决策,因此他们会对激励产生反应。
激励在分析市场是如何运行的时候显得至关重要。比如,当苹果的价格上涨时,人们会决定多吃梨而少吃苹果,因为购买苹果的成本增加了;同时,苹果园的主人决定多雇佣工人去种植苹果,因为出售苹果的利益增加了。
以此类推,当安全带系上的时候,会对安全产生什么样的影响呢?直接的影响显而易见,系上安全带后的重大车祸发生时的存活率提高了,但是这并不代表事情结束了,因为系上安全带后,司机的胆子也就变大了… 也就是说,系上安全带的行为对司机开车的速度和谨慎程度产生了影响,(这并不奇怪,下雪的时候,司机开车都会比平时更慢更小心的)这样对行人的安全显然有着很消极的影响。
这个例子告诉我们,当分析任何一种政策的时候,不但要去考虑它的直接影响,同时也要考虑由于激励产生的并不是很明显的间接影响。要记住,如果政策改变了激励,就会使人们改变自己的行为。
2008年10月10日星期五
2008年10月9日星期四
数据结构学习笔记(2)--算法的威力II
继续来研究最大子序列和这个问题。
经过改良,逐层遍历这种方法的复杂度被从N3降到了N2的级别,可以说是一个非常大的进步了,还有没有更好的办法呢?
这时候该回顾下递归(Recursion)了,先举一个最简单的递归的例子,求一个整数的N次方:
大家都知道要求一个数的N次方的话,先得求出这个数的N-1次方… 以此类推,也就是从这个数的0次方开始,而下面的这段代码,正是用到了这种思想
下面这段代码只能处理幂是正整数的情况
public static int GetPow(int radix,int power)
{
if(power == 0)
{
return 1;
}
else
{
return radix * GetPow(radix, power - 1);
}
}
然后回到最大子序列上,其实仔细想一想,如果把这N个数从中间的那个数分开的话,那么具有最大子序列和的这个序列所在的位置,只有三种可能:左边、右边或者是中间。运用刚才的递归思想,不难编写出下面的Pseudocode:
Function Int PseudoGetMaxSubsequenceSum(Array array)
{
Array arrayLeft=Left(array);
Array arrayRight=Right(array);
Int leftMaxSum=PseudoGetMaxSubsequenceSum(arrayLeft);
Int rightMaxSum=PseudoGetMaxSubsequenceSum(arrayRight);
Int midMaxSum=GetMidMaxSum(array);
return MaxOfThree(leftMaxSum,rightMaxSum,midMaxSum);
}
然后逐步细化,将Left(),Right(),GetMidMaxSum()写成实际的方法,于是就有了下面的代码:
public static int RecursiveMaxSubsequenceSum(int[] arrNumbers, int left, int right)
{
if (left == right)
{
if (arrNumbers[left] > 0)
{
return arrNumbers[left];
}
else
{
return 0;
}
}
int center = (left + right) / 2;
//Calculate the max subsequence sum in the left part
int maxLeftSum = RecursiveMaxSubsequenceSum(arrNumbers, left, center);
//Calculate the max subsequence sum in the right part
int maxRightSum = RecursiveMaxSubsequenceSum(arrNumbers, center + 1, right);
//Equal to MidMaxSubsequenceSum
//Firstly, calculate the max subsequence sum from the center element of the array to the left edge
int maxLeftBorderSum = 0;
int leftBorderSum = 0;
for (int i = center; i >= left; i--)
{
leftBorderSum += arrNumbers[i];
if (leftBorderSum > maxLeftBorderSum)
{
maxLeftBorderSum = leftBorderSum;
}
}
//Secondly, calculate the max subsequence sum from the center element of the array to the right edge
int maxRightBorderSum = 0;
int rightBorderSum = 0;
for (int i = center + 1; i <= right; i++)
{
rightBorderSum += arrNumbers[i];
if (rightBorderSum > maxRightBorderSum)
{
maxRightBorderSum = rightBorderSum;
}
}
int maxMidSum = maxLeftBorderSum + maxRightBorderSum;
//Equal to MaxOfThree
return MaxOfThree(maxLeftSum, maxMidSum, maxRightSum);
}
public static int MaxOfThree(int a, int b, int c)
{
int temp;
if (a>b)
{
temp = a;
a = b;
b = temp;
}
if (a>c)
{
temp = a;
a = c;
c = temp;
}
if (b>c)
{
temp = b;
b = c;
c = temp;
}
return c;
}
根据书上的说法,采用递归的做法可将复杂度降低至N*logN的地步(这里就不给出具体的证明过程了)
接下来就是这个最令人拍案叫绝的算法了
public static int LinearMaxSubsequenceSum(int[] arrNumbers)
{
int maxSum = 0;
int tempSum = 0;
for (int i = 0; i <>
{
tempSum += arrNumbers[i];
if (tempSum>maxSum)
{
maxSum = tempSum;
}
else if (tempSum<0)
{
tempSum = 0;
}
}
return maxSum;
}
只用了一轮循环即完成运算,复杂度为N,原理请大家自己思考。
经过改良,逐层遍历这种方法的复杂度被从N3降到了N2的级别,可以说是一个非常大的进步了,还有没有更好的办法呢?
这时候该回顾下递归(Recursion)了,先举一个最简单的递归的例子,求一个整数的N次方:
大家都知道要求一个数的N次方的话,先得求出这个数的N-1次方… 以此类推,也就是从这个数的0次方开始,而下面的这段代码,正是用到了这种思想
下面这段代码只能处理幂是正整数的情况
public static int GetPow(int radix,int power)
{
if(power == 0)
{
return 1;
}
else
{
return radix * GetPow(radix, power - 1);
}
}
然后回到最大子序列上,其实仔细想一想,如果把这N个数从中间的那个数分开的话,那么具有最大子序列和的这个序列所在的位置,只有三种可能:左边、右边或者是中间。运用刚才的递归思想,不难编写出下面的Pseudocode:
Function Int PseudoGetMaxSubsequenceSum(Array array)
{
Array arrayLeft=Left(array);
Array arrayRight=Right(array);
Int leftMaxSum=PseudoGetMaxSubsequenceSum(arrayLeft);
Int rightMaxSum=PseudoGetMaxSubsequenceSum(arrayRight);
Int midMaxSum=GetMidMaxSum(array);
return MaxOfThree(leftMaxSum,rightMaxSum,midMaxSum);
}
然后逐步细化,将Left(),Right(),GetMidMaxSum()写成实际的方法,于是就有了下面的代码:
public static int RecursiveMaxSubsequenceSum(int[] arrNumbers, int left, int right)
{
if (left == right)
{
if (arrNumbers[left] > 0)
{
return arrNumbers[left];
}
else
{
return 0;
}
}
int center = (left + right) / 2;
//Calculate the max subsequence sum in the left part
int maxLeftSum = RecursiveMaxSubsequenceSum(arrNumbers, left, center);
//Calculate the max subsequence sum in the right part
int maxRightSum = RecursiveMaxSubsequenceSum(arrNumbers, center + 1, right);
//Equal to MidMaxSubsequenceSum
//Firstly, calculate the max subsequence sum from the center element of the array to the left edge
int maxLeftBorderSum = 0;
int leftBorderSum = 0;
for (int i = center; i >= left; i--)
{
leftBorderSum += arrNumbers[i];
if (leftBorderSum > maxLeftBorderSum)
{
maxLeftBorderSum = leftBorderSum;
}
}
//Secondly, calculate the max subsequence sum from the center element of the array to the right edge
int maxRightBorderSum = 0;
int rightBorderSum = 0;
for (int i = center + 1; i <= right; i++)
{
rightBorderSum += arrNumbers[i];
if (rightBorderSum > maxRightBorderSum)
{
maxRightBorderSum = rightBorderSum;
}
}
int maxMidSum = maxLeftBorderSum + maxRightBorderSum;
//Equal to MaxOfThree
return MaxOfThree(maxLeftSum, maxMidSum, maxRightSum);
}
public static int MaxOfThree(int a, int b, int c)
{
int temp;
if (a>b)
{
temp = a;
a = b;
b = temp;
}
if (a>c)
{
temp = a;
a = c;
c = temp;
}
if (b>c)
{
temp = b;
b = c;
c = temp;
}
return c;
}
根据书上的说法,采用递归的做法可将复杂度降低至N*logN的地步(这里就不给出具体的证明过程了)
接下来就是这个最令人拍案叫绝的算法了
public static int LinearMaxSubsequenceSum(int[] arrNumbers)
{
int maxSum = 0;
int tempSum = 0;
for (int i = 0; i <>
{
tempSum += arrNumbers[i];
if (tempSum>maxSum)
{
maxSum = tempSum;
}
else if (tempSum<0)
{
tempSum = 0;
}
}
return maxSum;
}
只用了一轮循环即完成运算,复杂度为N,原理请大家自己思考。
2008年10月8日星期三
计算机组成学习笔记 (2)--分层架构
就像之前提到的,计算机所能直接理解的语言L0通常都是很难理解的(比如说机器语言),为了简化大部分程序员的工作,开发一种基于L0之上的且易于理解的语言L1就显得很有必要了。同时,也需要一个高效的将L1程序转化成L0指令序列的解释器或者是翻译器M1(其实它起的就是虚拟机的作用)
然而,为了让L0到L1的转化过程变的可行,L1和L0的差别并不能"特别"大,这也就意味着,虽然L1要比L0易于理解一些,但对于一些人仍然显得不够理想(比如说从机器语言到汇编语言,虽然汇编要比二进制码可读性强了很多,但汇编的难度还是不低),于是,在L1的基础上,又有了相应的语言L2和对应的虚拟机M2… 直到语言Ln和对应的虚拟机Mn。
按照这种层次,逐层抽象,在虚拟机Mn上编写程序的程序员并不需要考虑下层的翻译器或者解释器,程序由这种逐层抽象的结构保证其正确性,而无需了解编译器或者解释器实现的具体细节。从而获得正确的结果。
Tanenbaum是这样描绘计算机的分层结构的:
从上至下依次为:
面向问题语言层:为编写解决现实问题的应用程序提供便利,例如 Java C/C++之类的高级语言
汇编语言层:实际上是底层语言的符号表示,只是为程序员提供了一种更舒服的编写底层程序的途径
然后是:操作系统机器层---->指令系统层---->微体系结构层,这些层并不是为普通的程序员提供的,而是为支持高层所需的翻译器或者是编译器而设计的
最后一层是数字逻辑层,这一层涉及的更多的是电气知识。
每层的数据类型、操作和特性构成了该层的体系结构,它的主要作用就是解决该层用户所能看见的问题。
2008年10月7日星期二
计算机组成学习笔记(1)--翻译与解释
终于开始恶补CS的基础课程----Computer Architecture,这门以前深恶痛绝的课程。没办法,作为一个SE的学生,对于硬件总是很反感的。
自己使用的Textbook是Tanenbaum的那本计算机组成 结构化方法第五版,自从看过那本Computer Networks第四版之后,就对这个荷兰老头子的书产生了浓厚的兴趣,头一次见到写的这样风趣而且不乏深度的教材,让我头一次看一本计算机的书看的不可自拔。
本以为Chapter One只是一些简要的介绍,没想到第一页就解决了我以前一直不明白的一个问题:Differences between Compilation and Interpretation~
简单的说吧,假设有一台计算机,它只支持语言L0进行编程操作,然而L0却很难,一般的人根本搞不懂,于是便有高人发明了语言L1,它抽象了L0的许多功能,而且比L0更加简单易用,但这时候问题来了,计算机只认识L0不认识L1,这怎么办呢?
于是便碰到了一个语言转化的问题,也就是如何将高易用性的L1转化成计算机认识的L0呢?
这个转化过程,就扯到了翻译和解释这两个概念:
假设现在有一个用L1编写的程序PL1
一种方法是把用PL1翻译(Compile)成一个等价的L0指令序列,计算机通过执行这个L0指令序列,来完成原来的那个PL1的功能,这个过程叫做翻译。
另外一种方法,就是用L0写一个程序(也就是解释器 Interpreter),把用PL1输入数据,然后一边顺序检查PL1的每条指令,一边顺序直接执行等效的L0指令序列,从而完成PL1的功能,这个过程就叫做解释(Interpretation)。
翻译和解释其实都是通过执行PL1所对应的L0指令序列来实现的,其中的区别在于,翻译的时候需要先把整个PL1转化成L0指令序列,然后执行这个L0指令序列,而解释的时候,PL1中的每条L1指令在被检查和译码后会立即执行。因此,解释的速度一般要比翻译快,然而,解释的实现也要比翻译难。
(关于编译的原理,这是一门很复杂的学科,建议参考龙书的第二版和一些关于自动机的书)
自己使用的Textbook是Tanenbaum的那本计算机组成 结构化方法第五版,自从看过那本Computer Networks第四版之后,就对这个荷兰老头子的书产生了浓厚的兴趣,头一次见到写的这样风趣而且不乏深度的教材,让我头一次看一本计算机的书看的不可自拔。
本以为Chapter One只是一些简要的介绍,没想到第一页就解决了我以前一直不明白的一个问题:Differences between Compilation and Interpretation~
简单的说吧,假设有一台计算机,它只支持语言L0进行编程操作,然而L0却很难,一般的人根本搞不懂,于是便有高人发明了语言L1,它抽象了L0的许多功能,而且比L0更加简单易用,但这时候问题来了,计算机只认识L0不认识L1,这怎么办呢?
于是便碰到了一个语言转化的问题,也就是如何将高易用性的L1转化成计算机认识的L0呢?
这个转化过程,就扯到了翻译和解释这两个概念:
假设现在有一个用L1编写的程序PL1
一种方法是把用PL1翻译(Compile)成一个等价的L0指令序列,计算机通过执行这个L0指令序列,来完成原来的那个PL1的功能,这个过程叫做翻译。
另外一种方法,就是用L0写一个程序(也就是解释器 Interpreter),把用PL1输入数据,然后一边顺序检查PL1的每条指令,一边顺序直接执行等效的L0指令序列,从而完成PL1的功能,这个过程就叫做解释(Interpretation)。
翻译和解释其实都是通过执行PL1所对应的L0指令序列来实现的,其中的区别在于,翻译的时候需要先把整个PL1转化成L0指令序列,然后执行这个L0指令序列,而解释的时候,PL1中的每条L1指令在被检查和译码后会立即执行。因此,解释的速度一般要比翻译快,然而,解释的实现也要比翻译难。
(关于编译的原理,这是一门很复杂的学科,建议参考龙书的第二版和一些关于自动机的书)
数据结构学习笔记(1)--算法的威力I
自从出国的计划流产之后,决定利用现在这段实习的时间,重温一遍计算机基础学科,也就是数据结构、计算机组成、操作系统、数据库、编译原理和计算机网络,就按照这个顺序来慢慢的走了。
之前已经把M.A. Weiss的那本 Data Structure and Algorithm Analysis in C 2nd Edition看过了一遍,作为一本数据结构的本科教材。在讲解的细致程度和深入程度上,它绝对达到了相当的高度。作为一本讨论计算机算法的书,它也是经典中的经典。所以这次温习数据结构,用的教材还是它,而那本CLRS则是当成一本COOKBOOK来使用了,看C的代码还是要比看Pseudocode要舒服不少的。
从摩尔定律提出到现在,30多年过去了,计算机的性能以几何的速度增长,如果按照这个速度下去,没准有一天算法会丧失它的意义呢,呵呵。不过估计那一天还早呢,毕竟,有快的算法为什么还要用慢的呢,如果说解决同一个问题,一个方法要用不到一秒,另一个方法得耗个十年八年的,你会选择哪个方法呢?
这本书的开篇就提到了一些经典的问题例如最大数选择问题和最大子序列求和,这两个问题也是不少IT公司的常见笔试问题,解决方法有不少,不过真正的最优解法(线性时间内解决)就只有那一种。虽然这本书是1997年就有,2002年就有中文版了,但到现在还是没几个人知道它的解法,不得不感叹下如今国内IT人士基础的匮乏。
现在就拿这个最大子序列求和问题开始我的数据结构复习之路吧,呵呵。
问题很简单,就是给出N个整数,正的负的都有(正的是一定有的),求出其中连续的子序列的最大值。
例如:8,9,-10,12的结果是19;9,-10,3,2,-1,7,-6的结果就是11
一般人想到的解法是逐层遍历,也就是说把这N个整数所有的连续子序列的和都计算出来,然后取最大的那个,就是答案了,这样的程序并不难写:
实现的C#代码如下:
public static int ExhaustiveMaxSubsequenceSum(int[] arrNumbers)
{
int tempSum;
int maxSum = 0;
int count = arrNumbers.Length;
for (int i = 0; i < j =" i;" tempsum =" 0;" k =" i;">maxSum)
{
maxSum = tempSum;
}
}
}
return maxSum;
}
N个数的子序列有1*2/2+2*3/2+…+N*(N+1)/2种,也就是(N3+3N2+2N)/6中,复杂度为N3
然而仔细研究代码之后,发现最内层和次内层的循环存在冗余,可以合并,改良后的代码如下:
public static int ImprovedExhaustiveMaxSubsequenceSum(int[] arrNumbers)
{
int tempSum;
int maxSum = 0;
int count = arrNumbers.Length;
for (int i = 0; i < tempsum =" 0;" j =" i;">maxSum)
{
maxSum = tempSum;
}
}
}
return maxSum;
}
此时使用了两层循环,算法的复杂度为N2
还有没有解决的方法呢?是时候使用下递归了。
之前已经把M.A. Weiss的那本 Data Structure and Algorithm Analysis in C 2nd Edition看过了一遍,作为一本数据结构的本科教材。在讲解的细致程度和深入程度上,它绝对达到了相当的高度。作为一本讨论计算机算法的书,它也是经典中的经典。所以这次温习数据结构,用的教材还是它,而那本CLRS则是当成一本COOKBOOK来使用了,看C的代码还是要比看Pseudocode要舒服不少的。
从摩尔定律提出到现在,30多年过去了,计算机的性能以几何的速度增长,如果按照这个速度下去,没准有一天算法会丧失它的意义呢,呵呵。不过估计那一天还早呢,毕竟,有快的算法为什么还要用慢的呢,如果说解决同一个问题,一个方法要用不到一秒,另一个方法得耗个十年八年的,你会选择哪个方法呢?
这本书的开篇就提到了一些经典的问题例如最大数选择问题和最大子序列求和,这两个问题也是不少IT公司的常见笔试问题,解决方法有不少,不过真正的最优解法(线性时间内解决)就只有那一种。虽然这本书是1997年就有,2002年就有中文版了,但到现在还是没几个人知道它的解法,不得不感叹下如今国内IT人士基础的匮乏。
现在就拿这个最大子序列求和问题开始我的数据结构复习之路吧,呵呵。
问题很简单,就是给出N个整数,正的负的都有(正的是一定有的),求出其中连续的子序列的最大值。
例如:8,9,-10,12的结果是19;9,-10,3,2,-1,7,-6的结果就是11
一般人想到的解法是逐层遍历,也就是说把这N个整数所有的连续子序列的和都计算出来,然后取最大的那个,就是答案了,这样的程序并不难写:
实现的C#代码如下:
public static int ExhaustiveMaxSubsequenceSum(int[] arrNumbers)
{
int tempSum;
int maxSum = 0;
int count = arrNumbers.Length;
for (int i = 0; i < j =" i;" tempsum =" 0;" k =" i;">maxSum)
{
maxSum = tempSum;
}
}
}
return maxSum;
}
N个数的子序列有1*2/2+2*3/2+…+N*(N+1)/2种,也就是(N3+3N2+2N)/6中,复杂度为N3
然而仔细研究代码之后,发现最内层和次内层的循环存在冗余,可以合并,改良后的代码如下:
public static int ImprovedExhaustiveMaxSubsequenceSum(int[] arrNumbers)
{
int tempSum;
int maxSum = 0;
int count = arrNumbers.Length;
for (int i = 0; i < tempsum =" 0;" j =" i;">maxSum)
{
maxSum = tempSum;
}
}
}
return maxSum;
}
此时使用了两层循环,算法的复杂度为N2
还有没有解决的方法呢?是时候使用下递归了。
2008年10月5日星期日
制作好了计划表
现在一共有13门课程要学习,目前已经圈定了7门。
出国暂时是不可以了,怎么也得等两年,所以得做好再考一次IELTS甚至是TOEFL或者GRE的准备了。
选定的课程有:
Intermediate English
Elementary Japanese
Elementary Mathematics
Principles of Microeconomics
Fundamentals of .Net Platform
Fundamentals of Data Structure
Fundamentals of Computer Architecture
英语是必须要学的,必须得不断提高的,这个无可替代
在大连这个地方,也许以后得用到日语,所以还是保持一下自己的那点日语水平好了(二级不敢想,三级吧)
发现数学这玩意很有趣呢,感觉自己对数学有点生疏了,简单的复习一下吧
经济学原理是作为一个要独立生活的人所必须的常识
.Net是目前正在用的技术,有必要熟悉下这个平台而不是只是拿C Sharp编来编去的
数据结构那本书以前已经看过一遍了,这么重要的课程还是再看一遍吧
搞到了Tanenbaum的计算机体系结构第五版,大二时这门课学的一塌糊涂,作为一个ITer和CSer,有必要了解一些必要的计算机硬件架构知识
出国暂时是不可以了,怎么也得等两年,所以得做好再考一次IELTS甚至是TOEFL或者GRE的准备了。
选定的课程有:
Intermediate English
Elementary Japanese
Elementary Mathematics
Principles of Microeconomics
Fundamentals of .Net Platform
Fundamentals of Data Structure
Fundamentals of Computer Architecture
英语是必须要学的,必须得不断提高的,这个无可替代
在大连这个地方,也许以后得用到日语,所以还是保持一下自己的那点日语水平好了(二级不敢想,三级吧)
发现数学这玩意很有趣呢,感觉自己对数学有点生疏了,简单的复习一下吧
经济学原理是作为一个要独立生活的人所必须的常识
.Net是目前正在用的技术,有必要熟悉下这个平台而不是只是拿C Sharp编来编去的
数据结构那本书以前已经看过一遍了,这么重要的课程还是再看一遍吧
搞到了Tanenbaum的计算机体系结构第五版,大二时这门课学的一塌糊涂,作为一个ITer和CSer,有必要了解一些必要的计算机硬件架构知识
订阅:
评论 (Atom)
