笔试题:
java堆和栈的区别
Java把内存划分成两种:一种是堆内存,一种是栈内存。
堆:主要用于存储实例化的对象,数组。由JVM动态分配内存空间。一个JVM只有一个堆内存,线程是可以共享数据的。
栈:主要用于存储局部变量和对象的引用变量,每个线程都会有一个独立的栈空间,所以线程之间是不共享数据的。
在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
堆内存用来存放由new创建的对象和数组。
在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
volatile关键字的作用和注意事项
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
可视性:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
有序性:禁止进行指令重排序。
原子性:volatile无法保证对变量的任何操作都是原子性的。(无法保证非原子操作的多线程操作正确性)
多线程转账实现
建立一个银行的类,里面主要包含三个方法,一个是转账,一个是得到现有银行存款总数,一个是得到如今存户数量
public class Bank {
private final double[] accounts;
public Bank(int n, double initialBalance) {
accounts = new double[n];
for (int i = 0; i < accounts.length; i++) {
accounts[i] = initialBalance;
}
}
//加了锁
public synchronized void transfer(int from, int to, double amount) {
if (accounts[from] < amount) {
return;
}
System.out.println(Thread.currentThread());
accounts[from] -= amount;
System.out.printf("%f from %d to %d ", amount, from, to);
accounts[to] += amount;
System.out.println("total:" + getTotalBalance());
}
public double getTotalBalance() {
double sum = 0d;
for (int i = 0; i < accounts.length; i++) {
sum += accounts[i];
}
return sum;
}
public int getAccountSize() {
return accounts.length;
}
}
以下是转账类
public class TransferRunnable implements Runnable {
private Bank bank;
private int fromAccount = 0;
private double maxAmount = 0;
public TransferRunnable(Bank b, int fromAccount, double maxAmount) {
this.bank = b;
this.fromAccount = fromAccount;
this.maxAmount = maxAmount;
}
@Override
public void run() {
double amount = maxAmount * Math.random();
int toAccount = (int) ((int) bank.getAccountSize() * Math.random());
bank.transfer(fromAccount, toAccount, amount);
try {
Thread.sleep((long) (100L * Math.random()));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ajax主要部分和回调函数
什么是 AJAX ?
AJAX = 异步 JavaScript 和 XML。
AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更