09年9月28日,参加东软高端就业笔试,专业笔试关于缓存调度算法,由于事先没有准备,仓惶作答,漏洞百出,今作以总结,以备后用。
FIFO
package Fifo;
//FIFO(Firt in First out)算法
class Page {
private int num;
public Page(int num) {
this.num = num;
}
public int getNum() {
return num;
}
}
class LinkNode {
Page page;
LinkNode next;
}
public class MyFiFo {
LinkNode first;
LinkNode last;
int maxSize = 10; // 缓存的尺寸
int currentSize = 0;
public MyFiFo(int maxSize) {
this.maxSize = maxSize;
}
public void changePage(Page p) {// FIFO 算法,每次读取新页都重新调整缓存结构
LinkNode newItem = new LinkNode();
newItem.page = p;
newItem.next = null;
if (first == null) {
first = newItem;
last = first;
currentSize++;
} else {
LinkNode current = first;
boolean isIn = false;
for (int i = 0; i < currentSize; i++) {// 查看所请求的页面是否在缓存中
if (current.page.getNum() == p.getNum()) {
isIn = true;
break;
}
current = current.next;
}
if (!isIn) { // 如果所请求页面不在缓存中,向缓存中添加数据
// 从数据库里读出数据放到newItem上
if (currentSize < maxSize) { // 缓存未满时,添加页面
last.next = newItem;
last = newItem;
currentSize++;
}else { // 缓存已满,先删除头部,再向尾部添加
first = first.next;
last.next = newItem;
last = newItem;
}
}
}
print();
}
public void print() {
LinkNode current = first;
System.out.println();
while (current != null) {
System.out.print(current.page.getNum() + ",");
current = current.next;
}
}
public static void main(String[] args) {
MyFiFo fifo = new MyFiFo(10);
int arr[] = { 2,2, 5,5, 3, 7, 2, 5, 4, 7, 4, 6, 9, 10, 3, 53, 45, 56,56, 5,67,
89, 23 };
for (int i = 0; i < arr.length; i++) {
fifo.changePage(new Page(arr[i]));
}
}
}
图解:
图片来源:
LRU
package Fifo;
//LRU最久未使用淘汰算法
public class MyLRU {
LinkNode first;
LinkNode last;
int maxSize = 10; // 缓存的尺寸
int currentSize = 0;
public MyLRU(int maxSize) {
this.maxSize = maxSize;
}
public void changePage(Page p) {// LRU 算法,每次读取新页都重新调整缓存结构
LinkNode newItem = new LinkNode();
newItem.page = p;
newItem.next = null;
if (first == null) {
first = newItem;
last = first;
currentSize++;
} else {
LinkNode current = first;
LinkNode trailCurrent = first;
for (int i = 0; i < currentSize; i++) {// 先判断缓存中有没有该页,有则删除
if (current.page.getNum() == p.getNum()) {
if (current == first) { //有该页且在队头
first = first.next;
if (first == null) //删除后,如果缓存为空,重设last
last = first;
} else {
trailCurrent.next = current.next;
if (current == last) { //如果删除的是最后一个,重设last指针
last = trailCurrent;
}
}
currentSize--;
break;
}
trailCurrent = current;
current = current.next;
}
//删除完后,在队尾添加
if (currentSize < maxSize) {//缓存未满时的插入
if (first == null) { //如果缓存为空,添加并重设first、last指针
first = newItem;
last = first;
} else { //如果缓存不为空添加到尾部
last.next = newItem;
last = newItem;
}
currentSize++;
} else { //缓存已满时,先删除队头,再向队尾插入
first = first.next;
currentSize--;
last.next = newItem;
last = newItem;
currentSize++;
}
}
print();
}
public void print() {
LinkNode current = first;
System.out.println();
while (current != null) {
System.out.print(current.page.getNum() + ",");
current = current.next;
}
}
public static void main(String[] args) {
MyLRU fifo = new MyLRU(10);
int arr[] = { 2, 2, 5, 3, 3, 7, 2, 5, 4, 7, 7, 4, 6, 9, 10, 3, 53, 45,
56, 67, 89, 23, 53 };
for (int i = 0; i < arr.length; i++) {
fifo.changePage(new Page(arr[i]));
}
}
}
图解:
图片来源: