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])); } } }
图解:
图片来源: