如果找到了对您有用的资料,烦请点击右手边的Google广告支持我继续共享知识,谢谢! http://dengpeng.spaces.live.com/

2007年3月28日星期三

“我是研究生 应聘洗碗工”

本期播客  邓鹏
     2006年毕业于西南石油大学软件学院。同年7月赴澳留学,目前就读于墨尔本大学工程学院计算机科学和软件系,攻读分布式计算工程硕士,这是全球第一个分布式计算硕士学位,获得微软直接资助,导师是高性能计算、分布式计算、网格和集群计算的国际权威Buyya教授。
生活经历
卖菜的小工大都是本科生
     刚到国外,开始几个月是道门槛,学习上的、生活上和心理上的压力一起袭来。每次到超市买东西,看着白花花的“银子”往外流心都在滴血,只好全买特价商品。鸡肉在国外最便宜,我就天天吃鸡。每到夜晚,马路上除了扛着一大包东西的我很难见到其他人。回到家,坐在电脑前,看着无尽的项目,吃着索然无味的鸡肉,孤独感与思乡之情一起爆发。那段日子,我几乎都要崩溃了。
     还好,总算熬出来了。我以接近80分的平均成绩结束了第一个学期的学习。暑期打工,开始几个星期我尝试着跟本地的软件、计算机公司联系兼职,但都石沉大海。我只得转变观念开始寻找国内大学生瞧不起的工作,记得当时打电话应聘的台词是:“您好,我是墨尔本大学的研究生,我应聘洗碗工。”
     去年圣诞节前夕,我在维多利亚市场找了份卖菜的工作。在国内,如果研究生卖菜多半又要上报纸了吧?在这里卖菜的小工大部分都是本科以上学历的。卖菜苦,圣诞节卖菜更辛苦,客流量是平时的好几倍。从早上六点开始,不停吆喝、装菜、称重量、找钱,一直忙到晚上六点才收工。两天一共工作了22个小时,真是累趴下了,不过拿到170澳币工资时还是挺兴奋的。
     新年后,我找到了份洗碗工的工作,餐馆在城里面的黄金口岸不仅工资高点还包中午饭和晚饭。自己挣了钱,生活好些了, 还买了辆自行车。不知不觉,我已经慢慢适应这里的生活了。
留学感受
回答问题 说得通就是好答案
     墨尔本大学的研究生教育分授课式和研究式两种,与国内教学最大的不同就是没有标准答案。回答问题你完全可以想到哪里说到哪里,只要能说得通就是好答案。老师鼓励创新的、与众不同的观点。在Engineering for Internet Applications课讲到系统可用性时,老师不断鼓励我们要发散思维。我记得当时的讨论已经完全超越了技术层面,涵盖社会工程学等各方面。有趣的是,当时我们就考虑过地震对互联网的影响。
     与国内教学不同的是,这里教学的幻灯片往往很精简但涉及面很广,你得不断从各种渠道进行主动学习,分析补充资料以及阅读最新的论文。Mobile Computing Systems Programming这门课就是这样--老师Lars要求每人在划定的范围内选题目研究,鼓励大家提问共同讨论,这样极大地扩展了视野。期末考试的题目甚至包含有大家讨论的内容,如果你的知识不够全面,肯定答不上。
     国外学习不仅强调理论知识的学习,更强调动手能力的培养,成绩也不仅仅局限于期末考试,更多强调平时的表现。对于中国留学生来说,考试我们是“老手”了,但在动手能力上就稍微差了点。
申请心得
申请赴澳 要成绩更要综合能力
     我在国内大学的成绩并不是最优秀的,能成功获得留学深造的机会我想更多的还是我在科技创新上的成绩。我曾在美国第一大炼油公司ConocoPhilips 举办的ConocoPhillips Cup科技作品竞赛中获得两个二等奖、一个三等奖,在复旦大学第九届“挑战杯”飞利浦全国大学生课外学术科技作品竞赛全国决赛中获得三等奖。这些成绩对我的成功申请有很大帮助。
     相对美国和欧洲,留学澳洲的总体开销相对有很大优势,所以我当时更多关注澳大利亚的名校。选校时主要是看专业方向和未来发展趋势,我分别向感兴趣的澳大利亚国立大学人机交互方向硕士和墨尔本大学分布式计算方向硕士递交了申请书而且都获得了录取通知书。最后综合考虑自己的爱好、学校、城市等因素选择了墨尔本大学。
     对于国内本科毕业准备到澳大利亚攻读研究生的学生来说,最难的就是时间问题。国内大都是6月底才颁发学位证和毕业证,几乎不能赶上澳大利亚大学7月中旬入学期,只好等待次年2月入学,很浪费时间。当时,成都华樱留学顾问饶勤老师表示会尽快办理申请手续争取赶上入学时间,给了我很大支持。最终,在华樱顾问的帮助下我顺利地在7月前往澳洲。
     与国内只关心成绩分数不同,回顾整个申请留学过程,我觉得国外著名大学除了看重学生的成绩外,也看重学生的综合能力、创新能力。就算是你不是国内名校毕业、成绩也不是最优秀的,只要你有突出的综合能力,国外大学依然会优先考虑。
对话播客
出国前多学几道家乡菜
    记者:打工有何帮助?收入有多少?
    邓鹏:打工可以让你尝试并最终融入当地社会。通过与当地人接触,语言能力也会突飞猛进。出门靠朋友,打工可以扩大你的社交圈,出现困难时也有求援的对象。打工还可以补贴生活费,提高生活质量。现在我在餐馆打工,每小时8元澳币。不算多,但补贴生活费还是够了。
    记者:给四川想出国的学生一些建议吧。
    邓鹏:在留学名牌大学的光环下,要独自克服各种各样的困难,感觉痛苦的同时也证明你在成长。在出发之前最好能购买到所学课程的书籍,这将给出国后节省很多时间和费用。行前如果还能够预习一下,对于第一学期的学习有很大帮助。要出国的同学要做好身体、学习、心理的各方面准备。出来之后,难免会感觉很孤独,要多与父母沟通,因为父母始终是你的坚强后盾。在生活上,希望各位在国内就加强锻炼身体,同时做好要吃苦的心理准备。如果有时间,还可以在国内参加厨师、汽车修理、电器维修一类的培训,能获得认证证书对你留学打工会很有好处。四川的朋友们,建议大家增强独立生活能力,多学做几道家乡菜。

成都商报

另附:我在澳大利亚的留学生活

2007年3月25日星期日

Install MPICH NT 1.2.5 Step By Step

1. Download MPICH 1.2.5 from http://www-unix.mcs.anl.gov/mpi/mpich1/download.html

2. Setup all components in MPICH to local disk. For example, C:\Program Files\MPICH

3. Execute MPIRegister.exe in C:\Program Files\MPICH\mpd\bin. Type in the account name and password on this local machine. (NOTE: all the MPI clients should run under the same account and password, or error you will encounter. And firewall need to be disabled on every node.)

4. To verify your installation, you can run a sample program provided by MPI under C:\Program Files\MPICH\SDK\Examples\nt. Please use VC++ 6.0, Visual Studio 2003 .net or Visual Studio 2005 to open the examples.dsw file. Compile all projects to get executable files.

5. Create a folder and put the same executable files you want to execute on every node in this network. In this example I put cpi.exe into this folder.

For example on node1 “C:\MPI

                        on node2 “C:\MPI

                        on node3 “C:\MPI

                        ……

6. to execute this program, just type mpirun –np 4 cpi. And it will show some information like this below:

C:\>cd MPI

C:\MPI>mpirun -np 4 cpi

Process 2 on mote.

Process 0 on mote.

Enter the number of intervals: (0 quits)

Process 1 on vmote.

Process 3 on vmote.

 

C:\MPI>mpirun -np 4 cpi

Process 2 on mote.

Process 0 on mote.

Process 3 on vmote.

Process 1 on vmote.

Enter the number of intervals: (0 quits)

You can see that 2 nodes (mote and vmote) are running parallel.

2007年3月12日星期一

Alchemi: PrimeNumberGenerator SourceCode

using System;
using Alchemi.Core;
using Alchemi.Core.Owner;



namespace Tutorial
{

[Serializable]

class PrimeNumberChecker : GThread
{

public readonly int Candidate;

public int Factors = 0;



public PrimeNumberChecker(int candidate)
{

Candidate = candidate;

}



public override void Start()
{

// count the number of factors of the number from 1 to the number itself

for (int d = 1; d <= Candidate; d++)
{

if (Candidate % d == 0) Factors++;

}

}

}
class PrimeNumberGenerator
{

public static GApplication App = new GApplication();



[STAThread]

static void Main(string[] args)
{

// create grid threads to check if some randomly generated large

// numbers are prime

Random rnd = new Random();

for (int i = 0; i < 100; i++)
{

App.Threads.Add(new PrimeNumberChecker(rnd.Next(1000000)));

}



// initialise application

Init();



// start the application

App.Start();



Console.ReadLine();



// stop the application

App.Stop();

}
private static void Init()
{

// specify connection properties

App.Connection = new GConnection("localhost", 9000, "user", "user");



// grid thread needs to

App.Manifest.Add(new ModuleDependency(typeof(PrimeNumberChecker).Module));



// subscribe to ThreadFinish event

App.ThreadFinish += new GThreadFinish(App_ThreadFinish);

}
private static void App_ThreadFinish(GThread thread)
{

// cast the supplied GThread back to PrimeNumberChecker

PrimeNumberChecker pnc = (PrimeNumberChecker)thread;



// check whether the candidate is prime or not

bool prime = false;

if (pnc.Factors == 2) prime = true;



// display results

Console.WriteLine(

"{0} is prime? {1} ({2} factors)", pnc.Candidate, prime, pnc.Factors);

}

}

}

2007年3月8日星期四

JDK1.5中的线程池使用简介

在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多对并发特性的支持,例如:线程池。这里介绍的就是1.5种的线程池的简单使用方法。
创建日期:2005-05-11
最后修改日期:2007-03-06
panhaidong@gmail.com

 

一、简介
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:

 

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
 


  • corePoolSize
    线程池维护线程的最少数量
  • maximumPoolSiz
    线程池维护线程的最大数量
  • keepAliveTime
    线程池维护线程所允许的空闲时间
  • unit
    线程池维护线程所允许的空闲时间的单位
  • workQueue
    线程池所使用的缓冲队列
  • handler
    线程池对拒绝任务的处理策略

一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。
当一个任务通过execute(Runnable)方法欲添加到线程池时:


  • 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
  • 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
也就是:处理任务的优先级为:
核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。
workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue
handler有四个选择:

  • ThreadPoolExecutor.AbortPolicy()
    抛出java.util.concurrent.RejectedExecutionException异常
  • ThreadPoolExecutor.CallerRunsPolicy()
    重试添加当前的任务,他会自动重复调用execute()方法
  • ThreadPoolExecutor.DiscardOldestPolicy()
    抛弃旧的任务
  • ThreadPoolExecutor.DiscardPolicy()
    抛弃当前的任务

二、一般用法举例


 

package cn.simplelife.exercise;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThreadPool {
private static int produceTaskSleepTime = 2;
public static void main(String[] args) {
//构造一个线程池
ThreadPoolExecutor producerPool = new ThreadPoolExecutor(2, 4, 0,
TimeUnit.SECONDS, new ArrayBlockingQueue(3),
new ThreadPoolExecutor.DiscardOldestPolicy());

//每隔produceTaskSleepTime的时间向线程池派送一个任务。
int i=1;
while(true){
try {
Thread.sleep(produceTaskSleepTime);

String task = "task@ " + i;
System.out.println("put " + task);

producerPool.execute(new ThreadPoolTask(task));

i++;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}







package cn.simplelife.exercise;

import java.io.Serializable;

/**
* Ï̳߳ØÖ´ÐеÄÈÎÎñ
* @author hdpan
*/

public class ThreadPoolTask implements Runnable,Serializable{

//JDK1.5中,每个实现Serializable接口的类都推荐声明这样的一个ID
private static final long serialVersionUID = 0;

private static int consumeTaskSleepTime = 2000;
private Object threadPoolTaskData;

ThreadPoolTask(Object tasks){
this.threadPoolTaskData = tasks;
}

//每个任务的执行过程,现在是什么都没做,除了print和sleep,:)
public void run(){
System.out.println("start .."+threadPoolTaskData);
try {
//便于观察现象,等待一段时间
Thread.sleep(consumeTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
threadPoolTaskData = null;
}
}


对这两段程序的说明:



  1. 在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。
  2. 一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。
  3. 在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。

    • 这个小组里面队员至少有两个,如果他们两个忙不过来, 任务就被放到任务列表里面。
    • 如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员, 至多只能雇佣 4个。
    • 如果四个队员都在忙时,再有新的任务, 这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发, 直到接受这个任务为止(更残忍!呵呵)。
    • 因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。

  4. 通过调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制, 改变这两个值就可以观察不同速率下程序的工作情况。
  5. 通过调整4中所指的数据,再加上调整任务丢弃策略, 换上其他三种策略,就可以看出不同策略下的不同处理方式。
  6. 对于其他的使用方法,参看jdk的帮助,很容易理解和使用。

 

本文摘自SimpleLife

2007年3月4日星期日

在NetBeans 5.5下开发简单的Java Serialize和Deserialize

定义一个类,继承Serializable。该类的实例将被写到文件,并被读出还原。

Junk.java

/*
* Junk.java
*
* Created on 2007?¨º3??3¨¨?, ????11:24
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/


package serializableapp;
import java.io.Serializable;

public class Junk implements Serializable {
private static java.util.Random generator = new java.util.Random();
private int answer; // The answer
private double[] numbers; // Valuable data
private String thought; // A unique thought

public Junk(String thought) {
this.thought = thought;
answer = 42; // Answer always 42

numbers = new double[3+generator.nextInt(4)]; // Array size 3 to 6
for(int i = 0 ; i<numbers.length ; i++) { // Populate with
numbers[i] = generator.nextDouble(); // random values
}
}


public String toString() {
StringBuffer strBuf = new StringBuffer(thought);
strBuf.append('\n').append(String.valueOf(answer));
for(int i = 0 ; i<numbers.length ; i++) {
strBuf.append("\nnumbers[")
.append(String.valueOf(i))
.append("] = ")
.append(numbers[i]);
}
return strBuf.toString();
}
}

执行Serialize的程序

SerializableApp/serializableapp/Junk.java
SerializableApp/serializableapp/SerializeObjects.java
/*
* SerializeObjects.java
*
* Created on 2007?¨º3??3¨¨?, ????11:24
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/


package serializableapp;

//import java.io.ObjectOutputStream;
//import java.io.BufferedOutputStream;
//import java.io.FileOutputStream;
//import java.io.IOException;
import java.io.*;

public class SerializeObjects {
public static void main(String[] args) {
Junk obj1 = new Junk("A green twig is easily bent.");
Junk obj2 = new Junk("A little knowledge is a dangerous thing.");
Junk obj3 = new Junk("Flies light on lean horses.");
ObjectOutputStream objectOut = null;
try {
// Create the object output stream
objectOut = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream("C:/Beg Java Stuff/JunkObjects.bin")));

// Write three objects to the file
objectOut.writeObject(obj1); // Write object
objectOut.writeObject(obj2); // Write object
objectOut.writeObject(obj3); // Write object
/*
System.out.println("\n\nobj1:\n" + obj1
+"\n\nobj2:\n" + obj2
+"\n\nobj3:\n" + obj3);
**/


} catch(IOException e) {
e.printStackTrace(System.err);
System.exit(1);
}

// Close the stream
try {
objectOut.close(); // Close the output stream

} catch(IOException e) {
e.printStackTrace(System.err);
System.exit(1);
}

System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
ObjectInputStream objectIn = null; // Stores the stream reference
int objectCount = 0; // Number of objects read
Junk object = null; // Stores an object reference
try {
objectIn = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("C:/Beg Java Stuff/JunkObjects.bin")));

// Read from the stream until we hit the end
while(true) {
object = (Junk)objectIn.readObject();// Read an object
objectCount++; // Increment the count
System.out.println(object); // Output the object
}

} catch(ClassNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);

} catch(EOFException e) { // This will execute when we reach EOF
System.out.println("EOF reached. "+ objectCount + " objects read.");

} catch(IOException e) { // This is for other I/O errors
e.printStackTrace(System.err);
System.exit(1);
}

// Close the stream
try {
objectIn.close(); // Close the input stream

} catch(IOException e) {
e.printStackTrace(System.err);
System.exit(1);
}
}
}

执行Deserialize的程序

Deserialize/serializableapp/Junk.java
Deserialize/deserialize/DeserializeObjects.java
 
/*
* DeserializeObjects.java
*
* Created on 2007?¨º3??4¨¨?, ¨¦???9:34
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/


package deserialize;


import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.EOFException;

class DeserializeObjects {
public static void main(String args[]) {
ObjectInputStream objectIn = null; // Stores the stream reference
int objectCount = 0; // Number of objects read
serializableapp.Junk object = null; // Stores an object reference
try {
objectIn = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("C:/Beg Java Stuff/JunkObjects.bin")));

// Read from the stream until we hit the end
while(true) {
object = (serializableapp.Junk)objectIn.readObject();// Read an object
objectCount++; // Increment the count
System.out.println(object); // Output the object
}

} catch(ClassNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);

} catch(EOFException e) { // This will execute when we reach EOF
System.out.println("EOF reached. "+ objectCount + " objects read.");

} catch(IOException e) { // This is for other I/O errors
e.printStackTrace(System.err);
System.exit(1);
}

// Close the stream
try {
objectIn.close(); // Close the input stream

} catch(IOException e) {
e.printStackTrace(System.err);
System.exit(1);
}
}
}