1.管道
管道是由内核管理的一个缓冲区,其容量受多方面因素影响,包括缓冲区的大小、磁盘容量大小等问题
当管道中没有信息的话,从管道中读取的进程会等待,直到另一端的进程放入信息。当管道被放满信息的时候,尝试放入信息的进程会等待,直到另一端的进程取出信息。当两个进程都终结的时候,管道也自动消失。进程对管道进行读操作和写操作都可能被阻塞,因此C正确
管道的一端连接一个进程的输出。这个进程会向管道中放入信息。管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息,管道可以同时进行读进程和写进程
参考网址:http://www.cnblogs.com/biyeymyhjob/archive/2012/11/03/2751593.html
2.
public abstract class Test {
public static void main(String[] args) {
System.out.println(beforeFinally());
}
public static int beforeFinally() {
int a = 0;
try {
a = 1;
return a;
} finally {
a = 2;
}
}
} /**
* output: 1*/
从结果上看,貌似`finally` 里的语句是在`return` 之后执行的,其实不然,实际上`finally` 里的语句是在在`return` 之前执行的。那么问题来了,既然是在之前执行,那为什么`a` 的值没有被覆盖了?实际过程是这样的:当程序执行到try{}语句中的return方法时,它会干这么一件事,将要返回的结果存储到一个临时栈中,然后程序不会立即返回,而是去执行finally{}中的程序, 在执行`a = 2`时,程序仅仅是覆盖了a的值,但不会去更新临时栈中的那个要返回的值 。执行完之后,就会通知主程序“finally的程序执行完毕,可以请求返回了”,这时,就会将临时栈中的值取出来返回。这下应该清楚了,要返回的值是保存至临时栈中的。
再来看一个例子,稍微改下上面的程序:
public abstract class Test {
public static void main(String[] args) {
System.out.println(beforeFinally());
}
public static int beforeFinally() {
int a = 0;
try {
a = 1;
return a;
} finally {
a = 2;
return a;
}
}
} /**
* output: 2
*/
在这里,finally{}里也有一个return,那么在执行这个return时,就会更新临时栈中的值。同样,在执行完finally之后,就会通知主程序请求返回了,即将临时栈中的值取出来返回。故返回值是2.
再对比下面一题
下面程序的输出是什么?
public class Test {
public static String output = " ";
public static void foo(int i) {
try {
if (i == 1) {
throw new Exception();
}
} catch (Exception e) {
output += "2";
return;
} finally {
output += "3";
} output += "4";
}
public static void main(String[] args) {
foo(0);
foo(1);
System.out.println(output);
}
}
答案 3423
参考如下代码
public class Test {
public static String output = "";
public static String foo(int i) {
try {
if (i == 1) {
throw new Exception();
}
} catch (Exception e) {
output +="2";
return output;
} finally {
output +="3";
} output +="4";
return output;
}
public static void main(String[] args) {
// foo(0);
// System.out.println(output);//输出34
// foo(1);
// System.out.println(output);//输出23
// System.out.println(foo(0));//输出34
// System.out.println(foo(1));//输出2
}
}