金山前端笔试
单选题:20道
- js:call函数;promise:resolve, reject, .then, .catch;
- css: fixed,relative,absolute;
操作系统:LRU;不发生死锁的最小资源数
- LRU(Least Recently Used)是一种缓存淘汰策略,它会优先淘汰最近最少使用的数据,保留最近使用频率较高的数据。在操作系统中,LRU通常用于页面置换算法中,用于确定哪些页面应该被淘汰出内存以腾出空间给新的页面。
对于不发生死锁的最小资源数,这通常与资源分配图(Resource Allocation Graph)有关。在资源分配图中,如果不存在循环等待,即没有一个进程等待另一个进程持有的资源,那么系统中的资源就是足够的,不会发生死锁。因此,可以通过资源分配图来分析系统中是否存在死锁,并确定最小需要的资源数以确保不发生死锁。
一般而言,为了预防死锁,可以采取以下措施:
-
资源分配前知道请求的最大资源需求:在进程申请资源之前,需要知道该进程可能请求的最大资源数量,以便系统在分配资源时进行预判和调度。
-
资源顺序分配:资源分配时,尽量按照某种固定顺序分配资源,而不是让进程随意选择资源。这可以避免循环等待的情况。
-
资源分配可抢占:允许系统抢占进程当前占用的资源,将其分配给其他进程,以避免某些进程长期占用资源而导致其他进程无法获取资源的情况。
-
资源动态分配:在运行时根据系统负载情况动态调整资源分配策略,以保证系统的整体运行效率和稳定性。
以上措施可以有效预防死锁的发生,但在实际应用中需要根据具体情况选择合适的策略和方法。
数据结构:哈夫曼树最小加权路径
算法题:3道
js 哈夫曼树(Huffman Tree)是一种特殊的二叉树,用于数据编码中的无损数据压缩。哈夫曼树的构建基于最小堆(Min Heap)的概念,通过贪心算法实现。在构建哈夫曼树时,需要将频率较小的字符放在树的底层,频率较大的字符放在树的顶层,以实现最小加权路径。
构建哈夫曼树的步骤如下:
- 计算每个字符的频率,并将其存储在一个频率表中。
- 将频率表中的每个字符作为一个单独的节点,并根据频率构建一个最小堆。
- 从最小堆中选择两个频率最小的节点,并合并成一个新的节点,该节点的频率为两个节点的频率之和。新节点作为两个原始节点的父节点,放回最小堆中。
- 重复步骤3,直到最小堆中只剩下一个节点,即根节点,构建完成的哈夫曼树就是由这个根节点生成的。
构建完成的哈夫曼树可以用于数据编码,实现数据的高效压缩和解压缩。在哈夫曼树中,每个字符对应的编码路径即为从根节点到叶子节点的路径,其中0表示向左,1表示向右。根据字符在哈夫曼树中的路径,可以生成对应的编码表,用于压缩和解压缩数据。由于哈夫曼树的构建过程基于频率的贪心选择,保证了每个字符的编码路径长度最短,从而实现了最小加权路径的目标。
以下是使用JavaScript实现哈夫曼树的示例代码:
class Node {
constructor(value, freq) {
this.value = value;
this.freq = freq;
this.left = null;
this.right = null;
}
}
class MinHeap {
constructor() {
this.heap = [];
}
insert(node) {
this.heap.push(node);
this.heapifyUp(this.heap.length - 1);
}
heapifyUp(index) {
let parentIndex = Math.floor((index - 1) / 2);
while (parentIndex >= 0 && this.heap[parentIndex].freq > this.heap[index].freq) {
this.swap(parentIndex, index);
index = parentIndex;
parentIndex = Math.floor((index - 1) / 2);
}
}
extractMin() {
if (this.isEmpty()) return null;
if (this.heap.length === 1) return this.heap.pop();
const minNode = this.heap[0];
this.heap[0] = this.heap.pop();
this.heapifyDown(0);
return minNode;
}
heapifyDown(index) {
let leftChildIdx = 2 * index + 1;
let rightChildIdx = 2 * index + 2;
let smallest = index;
if (leftChildIdx < this.heap.length && this.heap[leftChildIdx].freq < this.heap[smallest].freq) {
smallest = leftChildIdx;
}
if (rightChildIdx < this.heap.length && this.heap[rightChildIdx].freq < this.heap[smallest].freq) {
smallest = rightChildIdx;
}
if (smallest !== index) {
this.swap(index, smallest);
this.heapifyDown(smallest);
}
}
swap(i, j) {
[this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
}
isEmpty() {
return this.heap.length === 0;
}
}
function buildHuffmanTree(charFreq) {
const minHeap = new MinHeap();
for (const [char, freq] of charFreq.entries()) {
if (freq > 0) {
minHeap.insert(new Node(char, freq));
}
}
while (minHeap.heap.length > 1) {
const leftNode = minHeap.extractMin();
const rightNode = minHeap.extractMin();
const mergedNode = new Node(null, leftNode.freq + rightNode.freq);
mergedNode.left = leftNode;
mergedNode.right = rightNode;
minHeap.insert(mergedNode);
}
return minHeap.extractMin();
}
function generateHuffmanCodes(root, prefix, codes) {
if (!root) return;
if (root.value !== null) {
codes[root.value] = prefix;
}
generateHuffmanCodes(root.left, prefix + '0', codes);
generateHuffmanCodes(root.right, prefix + '1', codes);
}
function huffmanEncoding(text) {
const charFreq = new Array(256).fill(0);
for (const char of text) {
const charCode = char.charCodeAt(0);
charFreq[charCode]++;
}
const huffmanTree = buildHuffmanTree(charFreq);
const huffmanCodes = {};
generateHuffmanCodes(huffmanTree, '', huffmanCodes);
let encodedText = '';
for (const char of text) {
const charCode = char.charCodeAt(0);
encodedText += huffmanCodes[charCode];
}
return { encodedText, huffmanTree };
}
function huffmanDecoding(encodedText, huffmanTree) {
let decodedText = '';
let current = huffmanTree;
for (const bit of encodedText) {
current = (bit === '0') ? current.left : current.right;
if (current.value !== null) {
decodedText += String.fromCharCode(current.value);
current = huffmanTree;
}
}
return decodedText;
}
// Example usage:
const text = 'Hello, World!';
const { encodedText, huffmanTree } = huffmanEncoding(text);
console.log('Encoded text:', encodedText);
console.log('Decoded text:', huffmanDecoding(encodedText, huffmanTree));
这段代码演示了如何使用哈夫曼树对文本进行编码和解码。它首先统计文本中每个字符的频率,然后根据频率构建哈夫曼树。接着,使用生成的哈夫曼树生成编码表,将文本编码为二进制字符串。最后,根据哈夫曼树对编码后的字符串进行解码,
作者:痴心的袋鼠在炒股
链接:www.nowcoder.com/discuss/593…
来源:牛客网