试题
1 C语言程序阅读
#include<bits/stdc++.h>
using namespace std;
int f(int* i) {
static int x = 0;
x++;
printf("%d -1, *i= %d\n", x, *i++);
printf("%d -2, *i= %d\n", x, *i++);
return *i;
}
int main() {
int x[3] = { 1,2,3 };
x[0] = f(x) + f(x) + x[x[0]];
printf("x[0]=%d\n", x[0]);
}
输出是
1 -1, *i= 1
1 -2, *i= 2
2 -1, *i= 1
2 -2, *i= 2
x[0]=8
(这输出也太奇怪了吧局部变量x增加了,x[0]没有变,所以求值策略是什么?感觉要看汇编代码)
(后来知道这个++优先级更高。。。太蠢了)
2 Scheme设计
实现trim,去掉列表的最后一个元素。相当于 vector<int>v;v.pop_back()
(define (my-trim lst )
(cond ((null? lst) ; if the list is empty
'error) ; error
((equal? (cdr lst) '())
'())
(else ; if the list is non-empty
(cons (car lst) ; cons the first element in the list
(my-trim (cdr lst) ))))) ; with the result of advancing the recursion
3 指称语义
*I1=*I2
var *I1=&I2
let var *I1=&I2 in C
(照着I=E和*I=E的语义瞎写的。有没有人来告诉我ppt最后两行是错的,当时就应该问老师的QAQ)
4 哲学家用餐问题
一个用synchonized实现的哲学家问题,问会出现什么问题,怎么改进,我正好找到了源码博客[1],和里面的教学思路一致(国内的java并发实现真的找不到标准代码)。
public class Philosopher implements Runnable {
// The forks on either side of this Philosopher
private Object leftFork;
private Object rightFork;
//引用调用,指向同一个对象,所以可以锁住
public Philosopher(Object leftFork, Object rightFork) {
this.leftFork = leftFork;
this.rightFork = rightFork;
}
private void doAction(String action) throws InterruptedException {
System.out.println(
Thread.currentThread().getName() + " " + action);
Thread.sleep(((int) (Math.random() * 100)));
}
@Override
public void run() {
try {
while (true) {
// thinking
doAction(System.nanoTime() + ": Thinking");
synchronized (leftFork) {
doAction(
System.nanoTime()
+ ": Picked up left fork");
synchronized (rightFork) {
// eating
doAction(
System.nanoTime()
+ ": Picked up right fork - eating");
doAction(
System.nanoTime()
+ ": Put down right fork");
}
// Back to thinking
doAction(
System.nanoTime()
+ ": Put down left fork. Back to thinking");
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
public static void main(String[] args) throws Exception {
final Philosopher[] philosophers = new Philosopher[5];
Object[] forks = new Object[philosophers.length];
for (int i = 0; i < forks.length; i++) {
forks[i] = new Object();
}
for (int i = 0; i < philosophers.length; i++) {
Object leftFork = forks[i];
Object rightFork = forks[(i + 1) % forks.length];
if (i == philosophers.length - 1) {
// The last philosopher picks up the right fork first
philosophers[i] = new Philosopher(rightFork, leftFork);
} else {
philosophers[i] = new Philosopher(leftFork, rightFork);
}
Thread t = new Thread(philosophers[i], "Philosopher " + (i + 1));
t.start();
}
}
}
class DiningPhilosophers {
}
应该就是这里改的
5 JAVA多态 终极版
类似作业里的题 大概长这样,但是里面还试图对内部类进行多态(定义了内部类,private内部类变量,内部类extend父类的内部类,子类通过set内部类实例到父类里)。个人理解内部类无法多态。类似这种
public class Foo {
public void method1() {
System.out.println("foo 1");
}
public void method2() {
System.out.println("foo 2");
}
public String toString() {
return "foo";
}
}
public class Baz extends Foo {
public void method1() {
System.out.println("baz 1");
}
public String toString() {
return "baz";
}
}
public class Mumble extends Baz {
public void method2() {
System.out.println("mumble 2");
}
}
public static void main(String[] args){
Foo[] pity = {new Baz(), new Bar(), new Mumble(), new Foo()};
for (int i = 0; i < pity.length;i++) {
System.out.println(pity[i]);
pity[i].method1();
pity[i].method2();
System.out.println();
}
}
method | foo | bar | Mumble | baz |
---|---|---|---|---|
method1 | foo 1 | baz 1 | ||
method2 | foo 2 | bar 2 | numble 2 | |
toString | foo | baz |
感想
近年考试比较简单,同学也是这么觉得。课程大作业可以没有代码实现,总之还是算能水过的核心课之一。
但是要真的掌握,内容太多了,每一章都能作为一节课。
作用域、闭包、堆栈帧、参数传递、prolog、语法、lambda演算都没考(基本也不是重点,但基础不好的我看了好久)。
我今天复习的时候真的折磨。java并发的内容是真的多、又不懂java,又不懂并发。