【PoRE】Lab1: Java Programming

回到目录

内容总结

  • 第一节课的Lab0实质上是关于git仓库的建立和教程,这个就不再赘述了。
  • Lab1是致力于Java编程的。这个思路也很正常:要学会逆向别人的代码,那就需要读懂它们,要能够读懂它们最直接的方法就是我也能写出它们。Java Programming的这个实验是为了之后Android Programming打下基础。
  • 因为大部分选上这门课的同学都有C++的基础,至少对面向对象的理念不会陌生。因此这里简单地概述一些有关于Java的语法特征。如果您想要系统地学习Java,可以在网上找到数不尽的资源,或者也可以和你旦教务处沟通一下,在上半学期开一门Java编程课程。

数据类型: Java的数据一共有两种类型,分别是原始类型(Primitive Type)以及引用类型(Reference Type)。原始类型包括:byte(1字节)、short(2字节)、int(4字节)、long(8字节)、float(4字节)、double(8字节)、char(2字节)、boolean。关于原始类型的参数传递是值传递。其中特别注意的是,char在Java中是2字节的,因为Java使用Unicode编码,这在之后的Native Code一块也会有所呼应。除了原始类型,是引用类型,包括但不限于String、StringBuilder、Random。

类: 类(class)可以说是Java中几乎一切的基础。这一块和C++大抵一致,都有field(instance field和static field)和methods(instance methods和static methods)。instance field/methods和static field/methods的关键区别,在于是否依赖一个实例化的对象。构造函数(constructor)的概念,也基本和C++一致。

多态: 由于所有自己定义的类都属于引用类型,而Java也允许一般类之间的单继承,因此也会引入多态。与C++中显式地定义virtual不一样的是,Java的非private方法都是动态绑定(Dynamic Binding)实现的。

方法的重写和重载: 重写(Override)和重载(Overload),这个和C++中的概念一致,这里不多赘述。

内部类: 分为普通的内部类、静态的内部类以及匿名内部类。在之后的反编译得到的代码中,会大量见到内部类。

反射: 在获得目标类的字节码文件的情况下,知道一个类,可以知道它的所有字段和方法,并且获取和实现它。这个也是Java的一个强大的机制,在之后的Java-specific Obfuscation中会提到反射机制的使用。

JNI: 声明native,通过库文件的调用,可以调用如C等非Java语言的代码。这部分的知识在Native Code部分会提及。

垃圾回收: 垃圾回收(Garbage Collection),与C++中需要显式地销毁(堆上)对象不一样的是,Java采取垃圾回收机制。关于这部分机制的介绍,可以参见更多相关的教程。这一机制的存在,可以使我们在大部分时刻不太用关心空间的维护和释放。

Lab简介与参考

这个Lab一共分成5个Task:(Task0仅供热身)

  • Task0: Hello World!
      打印出Hello world即可,这应该是所有编程语言入门的第一步了。
//Task0.java
//TODO:Make this program output "Hello world!".
class Task0 {
    public static void main(String[] args) {
        System.out.println("Hello world");
    }
}

  IDEA可以使用sout快捷键迅速地打出System.out.println();这句语句。如果开启了省电模式,将无法使用快捷键。类似地,主函数也可以使用psvm迅速打出。

  • Task 1: Catch the exception
      这个task的关键要点在于错误处理,难点在于如何优雅地打印出要求的格式。建议对这个task感到束手无策的同学仔细查看错误处理相关的API,所有答案也源自这里。
//Task1.java
    public static void foo2(int value) throws NewException {
        // TODO: How to handler exception to get target output?
        try {
            foo1(value);
        } catch (NewException666 e) {
            NewException newException = new NewException("You got a 666 Exception");
            newException.initCause(e);
            throw newException;
        } catch (NewException999 e) {
            NewException newException = new NewException("You got a 999 Exception");
            newException.initCause(e);
            throw newException;
        } finally {
            System.out.println("foo2 finished!");
        }
    }

  关键在于这里的iniCause()函数的调用。

  • Task 2: Thread Collaboration
      这个task的问题是在于如何解决多线程中的并发读写引起的问题。关于这个解决方案,在另一门课程ICS(CS:APP)中会涉及,不过好像我们这一届是最后开设这门课程的了……
//Add.java
    // TODO: How to make add stable?
    public synchronized void add(int i){
        sum+=i;
    }

  关键在于synchronized关键字。大家可以查阅相关的文档寻求进一步的帮助,这里就不多阐述其原理了。(加锁)

  • Task 3: Callback Methods
      关于回调函数,简单地来构造一个情境:A类的a()方法去调用B类的b()方法,b()方法在结束后再调用A类的callback()方法,这就是一次回调。特别地,这里是当callback()方法不是静态方法的一次特例。
//App.java
public class App implements CSCallBack {
    // You need to modify this class.
    // TODO: How to set callback?
    private PhoneSystem system;
    public App(PhoneSystem system) {
        this.system = system;
    }

    public void click(){
        System.out.println("Button clicked");
        system.performOnClick(this);
    }

    @Override
    public void OnClick() {
        System.out.println("You click this button, so I will do ...");
    }
}
//PhoneSystem.java
public class PhoneSystem {
    // You need to modify this class.
    // TODO: How to set callback?
    public void performOnClick(App app) {
        System.out.println("performOnClick clicked");
        app.OnClick();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

  这里的回调机制,需要通过修改原先java文件中的两个关键函数的参数实现。如果不理解的话,可以试图模拟一下这个Task的操作的流程,应该就比较清楚回调的作用了。

  • Task 4: Simple Java Program
      这个Task的目标是实现一个栈(stack)。如果之前没有修过《数据结构》的同学,可以简单地将栈理解为一个先进后出的容器。我们需要实现一些栈的基本操作,并结合数据验证结果。
//Task4.java
import java.util.ArrayList;
public class MyStack<T> {
    // TODO: Finish it!
    private ArrayList<T> list = new ArrayList<T>();
    public boolean isEmpty(){
        return list.isEmpty();
    }
    public int getSize(){
        return list.size();
    }
    public T peek(){
        return list.get(list.size()-1);
    }
    public T pop(){
        T temp=list.get(list.size()-1);
        list.remove(list.size()-1);
        return temp;
    }
    public void push(T o){
        list.add(o);
    }
    @Override
    public String toString() {
        return "stack:"+list.toString();
    }
}

  这里的几个操作也和C++中实现栈的方法差不多。不一样的是,这里还简化了模型,只需要调用List相关的方法就可以管理数据的储存。(我也不记得最初始的代码里是否有ArrayList了)

写在最后

  1. 这个Lab的难度不大,但大家想要通过三节课就能学会一门编程语言,这不太现实。不过有C++基础的话,在了解相关机制时就很清楚了。这个Lab及Java编程的知识,对后面的一些Lab还是有作用的,尤其是Android Programming。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Matlab孔隙网络(pore network)是一种数值模拟方法,用于研究多孔介质中的流动和传输现象。该方法通过将多孔介质看作是由连接的孔隙和喉道组成的网络,来描述多孔介质的结构和性质。 Matlab作为一种编程语言和环境,为研究者提供了开发孔隙网络模型和分析数据的强大工具。使用Matlab进行孔隙网络研究,可以方便地实现各种计算和分析操作,如网络生成、几何参数计算、渗流模拟、流体传输分析等。 对于孔隙网络的生成,Matlab提供了丰富的绘图和图像处理函数,可以根据物理模型或实际图像进行网络的构建和可视化。通过几何参数的计算,可以获得孔隙网络的尺寸和形状特征,如孔隙体积分布、孔隙直径分布、孔隙连通率等。 在渗流模拟方面,Matlab可以通过各种数值方法,如有限元法、有限差分法等,计算流体在孔隙网络中的传输行为。借助Matlab的计算和优化功能,可以对孔隙网络的渗透率、渗流速度、渗透曲线等关键参数进行预测和优化。 此外,Matlab还提供了用于处理和分析实验或模拟得到的数据的函数和工具包。通过数据处理和统计分析,可以揭示孔隙网络中流体和物质传输的特性,并通过可视化工具将分析结果进行可视化展示。 总之,使用Matlab进行孔隙网络研究,能够帮助研究者更深入地理解多孔介质的结构和性质,揭示流体和物质在多孔介质中的传输行为,为相关领域的科研工作提供有效支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值