主頁 > 軟體工程 > 函式內部的函式與主體一起運行

函式內部的函式與主體一起運行

2022-01-18 21:34:29 軟體工程

下面是凱爾·辛普森 (Kyle Simpson) 的“異步與性能”一書中的一個示例。

試圖理解下面的代碼,但我有問題 1) 傳入 fetchX 和 fetchY 有什么意義?2) getX 和 getY 如何運行?我可以想象使用 getX() 和 getY() 運行,但代碼有 getX(){} 和 getY(){},這看起來更像函式宣告?我在這里錯了嗎?

function add(getX,getY,cb) {
  var x, y;
  getX( function(xVal){
    x = xVal;
    if (y != undefined) {
       cb(x   y );
    }
  });
  getY( function(yVal){
    y = yVal;
    if (x != undefined) {
         cb(x   y);
    }
  })
}

// fetchX() and fetch() are sync or async functions
add(fetchX, fetchY, function(sum) {
   console.log(sum);
});

uj5u.com熱心網友回復:

要回答您的問題,我們可以分析代碼示例。如果我們從上到下和從左到右閱讀代碼(請注意,盡管這是決議代碼的方式,但這不是執行代碼的方式,但我們會回到那個),我們首先看到

function add(getX,getY,cb) {
  var x, y;
  // ...
}

這是一個名為 的函式的宣告add,有 3 個引數getX,分別為getYcb

函式體內的第一行是

  var x, y;

var函式體內的關鍵字意味著這是一個函式范圍的變數宣告這只是意味著xand是從函式體y的開始到結尾宣告的(關鍵字也可以用于全域范圍的變數宣告,還有塊范圍的變數宣告的關鍵字)。addvarlet

下一個代碼部分是

  getX( function(xVal){
    x = xVal;
    if (y != undefined) {
       cb(x   y );
    }
  });

這從呼叫開始getX(...);(記住getX是我們所在函式的第一個引數add)。所以getX必須是我們可以呼叫的東西,即一個函式,否則我們會得到一個運行時錯誤。

getX傳遞給呼叫的第一個(也是唯一的)輸入引數是

  function(xVal){
    x = xVal;
    if (y != undefined) {
       cb(x   y );
    }
  }

這是一個函式運算式

function 關鍵字可用于在運算式中定義函式。

以這種方式使用function關鍵字(或使用箭頭函式運算式)而不指定名稱,定義了一個匿名函式。您可能會聽到其他人將它們(取決于背景關系)稱為callbacks/lambdas/closures

所以這告訴我們該getX函式應該接受一個函式作為第一個引數,并可能將其作為其內部邏輯的一部分來呼叫。

我們還注意到這個匿名函式function(xVal){ ... }接受一個引數xVal這告訴我們,getX當(如果)它呼叫這個函式時,函式應該傳遞一些值作為第一個引數。

因此,如果該getX函式曾經回呼我們作為其第一個引數傳遞的這個匿名函式,那么這個匿名函式的主體將被執行。如果getX函式從不呼叫它,那么這個匿名函式的主體將永遠不會被執行。

匿名函式的主體是

    x = xVal;
    if (y != undefined) {
       cb(x   y );
    }

它只是分配xValx并有條件地呼叫cb(x y),即add函式的第三個引數,這里仍然是外部函式范圍。

我們可以對getY通話進行類似的細分。唯一的區別是它呼叫getY函式引數并且匿名函式的主體分配yVal給 y (但它仍然有條件地呼叫cb(x y))。

代碼示例的最后幾行是

// fetchX() and fetch() are sync or async functions
add(fetchX, fetchY, function(sum) {
  console.log(sum);
});

So this is a call of the previously declared named function function add(getX, getY, cb) { ... }.

When this code line is executed it will call add with

  • 1st parameter: fetchX
  • 2nd parameter: fetchY
  • 3rd parameter: an anonymous function function(sum) { console.log(sum); }. This anonymous function accepts a single parameter sum and only when (if) called it logs it to the console.

  1. what is the point of passing in fetchX and fetchY?

As we see from the breakdown above, fetchX and fetchY are passed into the add function call in order for them to serve as "replacements" for calls to getX and getY inside the function body. You can think of it that the call to getX(...) calls fetchX(...) and the call to getY(...) calls fetchY(...).

They will be "called back" from inside the function, that's why in such cases we call them callbacks, they are functions passed as parameters into another function, and said other function might call them based on its internal logic. In your example they are called once each (assuming no errors happen during runtime).


  1. How does getX and getY run? I can imagine running w/ getX() and getY() but code has getX(){} and getY(){} and that looks more like function declaration?

As mentioned earlier the code is not always executed from top to bottom and from left to right. So after parsing the code from the example, the code interpreter will execute the add call first (because the rest is just a declaration for the add function) and it will pass fetchX, fetchY and function(sum){ console.log(sum); } as the parameters. Right after the call happens the execution continues with the add function body.

Right from the getX call inside the add function body there are different possible flows, depending on what the logic inside the getX and getY is (specifically fetchX and fetchY in your case). Since we don't have a documentation for fetchX and fetchY nor their source code, we cannot know how the code will execute from here on. But we can explore some of the possible flows.

I added a few console.log statements to your original code example. In that way we can see the order of the execution. Another way to do this, without the need to add extra log statements, is to use the debugger, place a breakpoint somewhere inside the function and then use the step commands to step through the code as it executes.

Option 1: If both fetchX and fetchY call their first parameter (the callback they receive) always exactly once synchronously then the flow is (run the code snippet)

// These two callbacks could be defined elsewhere, maybe even in code not under our control, such as in a library...
fetchX = function(callback) {
  callback(2); // unconditional single synchronous call
};
fetchY = function(callback) {
  callback(3); // unconditional single synchronous call
};

console.log("Entering the code example scope");

function add(getX,getY,cb) {
  console.log("Called: function add(getX,getY,cb)");
  var x, y;
  getX( function(xVal){
console.log("Called: function(xVal) xVal =", xVal);
x = xVal;
if (y != undefined) {
   cb(x   y);
}
  });
  getY( function(yVal){
console.log("Called: function(yVal) yVal =", yVal);
y = yVal;
if (x != undefined) {
   cb(x   y);
}
  });
  console.log("Returning from: function add(getX,getY,cb)");
}

add(fetchX, fetchY, function(sum) {
  console.log("Called: function(sum)");
  console.log(sum);
  console.log("Returning from: function(sum)");
});
console.log("Leaving the code example scope");

Option 2: If fetchX calls its callback always exactly once synchronously and fetchY calls its callback parameter always exactly once asynchronously, then the flow is (run the code snippet)

fetchX = function(callback) {
  callback(2); // unconditional single synchronous call
};
fetchY = function(callback) {
  setTimeout(function() { callback(3); }, 0); // unconditional single asynchronous call
};

console.log("Entering the code example scope");

// add function is same as before, just in one line for space purposes
function add(getX,getY,cb) {
  console.log("Called: function add(getX,getY,cb)");
  var x, y; getX( function(xVal){ console.log("Called: function(xVal) xVal =", xVal); x = xVal; if (y != undefined) { cb(x   y); } }); getY( function(yVal){  console.log("Called: function(yVal) yVal =", yVal); y = yVal; if (x != undefined) { cb(x   y); } });
  console.log("Returning from: function add(getX,getY,cb)");
}

add(fetchX, fetchY, function(sum) {
  console.log("Called: function(sum)");
  console.log(sum);
  console.log("Returning from: function(sum)");
});
console.log("Leaving the code example scope");

Option 3: If fetchX calls its callback always exactly once asynchronously and fetchY calls its callback parameter always exactly once synchronously, then the flow is (run the code snippet)

fetchX = function(callback) {
  setTimeout(function() { callback(2); }, 0); // unconditional single asynchronous call
};
fetchY = function(callback) {
  callback(3); // unconditional single synchronous call
};

console.log("Entering the code example scope");

// add function is same as before, just in one line for space purposes
function add(getX,getY,cb) {
  console.log("Called: function add(getX,getY,cb)");
  var x, y; getX( function(xVal){ console.log("Called: function(xVal) xVal =", xVal); x = xVal; if (y != undefined) { cb(x   y); } }); getY( function(yVal){  console.log("Called: function(yVal) yVal =", yVal); y = yVal; if (x != undefined) { cb(x   y); } });
  console.log("Returning from: function add(getX,getY,cb)");
}

add(fetchX, fetchY, function(sum) {
  console.log("Called: function(sum)");
  console.log(sum);
  console.log("Returning from: function(sum)");
});
console.log("Leaving the code example scope");

Option 4: If both fetchX and fetchY call their callback always exactly once asynchronously and fetchX calls it sooner, then the flow is (run the code snippet)

fetchX = function(callback) {
  setTimeout(function() { callback(2); }, 0); // unconditional single asynchronous call
};
fetchY = function(callback) {
  setTimeout(function() { callback(3); }, 50); // unconditional single asynchronous call (further delayed)
};

console.log("Entering the code example scope");

// add function is same as before, just in one line for space purposes
function add(getX,getY,cb) {
  console.log("Called: function add(getX,getY,cb)");
  var x, y; getX( function(xVal){ console.log("Called: function(xVal) xVal =", xVal); x = xVal; if (y != undefined) { cb(x   y); } }); getY( function(yVal){  console.log("Called: function(yVal) yVal =", yVal); y = yVal; if (x != undefined) { cb(x   y); } });
  console.log("Returning from: function add(getX,getY,cb)");
}

add(fetchX, fetchY, function(sum) {
  console.log("Called: function(sum)");
  console.log(sum);
  console.log("Returning from: function(sum)");
});
console.log("Leaving the code example scope");

Option 5: If both fetchX and fetchY call their callback always exactly once asynchronously and fetchY calls it sooner, then the flow is (run the code snippet)

fetchX = function(callback) {
  setTimeout(function() { callback(2); }, 50); // unconditional single asynchronous call (further delayed)
};
fetchY = function(callback) {
  setTimeout(function() { callback(3); }, 0); // unconditional single asynchronous call
};

console.log("Entering the code example scope");

// add function is same as before, just in one line for space purposes
function add(getX,getY,cb) {
  console.log("Called: function add(getX,getY,cb)");
  var x, y; getX( function(xVal){ console.log("Called: function(xVal) xVal =", xVal); x = xVal; if (y != undefined) { cb(x   y); } }); getY( function(yVal){  console.log("Called: function(yVal) yVal =", yVal); y = yVal; if (x != undefined) { cb(x   y); } });
  console.log("Returning from: function add(getX,getY,cb)");
}

add(fetchX, fetchY, function(sum) {
  console.log("Called: function(sum)");
  console.log(sum);
  console.log("Returning from: function(sum)");
});
console.log("Leaving the code example scope");

Option 6: If fetchX calls its callback exactly three times asynchronously on an interval of 30ms with values 10, 20, 30 and fetchY calls its callback exactly three times asynchronously on an interval of 50ms with values 1, 2, 3, then the flow is (run the code snippet)

fetchX = function(callback) {
  setTimeout(function() { callback(10); }, 30);
  setTimeout(function() { callback(20); }, 60);
  setTimeout(function() { callback(30); }, 90);
};
fetchY = function(callback) {
  setTimeout(function() { callback(1); },  50);
  setTimeout(function() { callback(2); }, 100);
  setTimeout(function() { callback(3); }, 150);
};

console.log("Entering the code example scope");

// add function is same as before, just in one line for space purposes
function add(getX,getY,cb) {
  console.log("Called: function add(getX,getY,cb)");
  var x, y; getX( function(xVal){ console.log("Called: function(xVal) xVal =", xVal); x = xVal; if (y != undefined) { cb(x   y); } }); getY( function(yVal){  console.log("Called: function(yVal) yVal =", yVal); y = yVal; if (x != undefined) { cb(x   y); } });
  console.log("Returning from: function add(getX,getY,cb)");
}

add(fetchX, fetchY, function(sum) {
  console.log("Called: function(sum)");
  console.log(sum);
  console.log("Returning from: function(sum)");
});
console.log("Leaving the code example scope");

Here are the outputs of the above options

Option 1:

Entering the code example scope
Called: function add(getX,getY,cb)
Called: function(xVal) xVal = 2
Called: function(yVal) yVal = 3
Called: function(sum)
5
Returning from: function(sum)
Returning from: function add(getX,getY,cb)
Leaving the code example scope

Option 2:

Entering the code example scope
Called: function add(getX,getY,cb)
Called: function(xVal) xVal = 2
Returning from: function add(getX,getY,cb)
Leaving the code example scope
Called: function(yVal) yVal = 3
Called: function(sum)
5
Returning from: function(sum)

Option 3:

Entering the code example scope
Called: function add(getX,getY,cb)
Called: function(yVal) yVal = 3
Returning from: function add(getX,getY,cb)
Leaving the code example scope
Called: function(xVal) xVal = 2
Called: function(sum)
5
Returning from: function(sum)

Option 4:

Entering the code example scope
Called: function add(getX,getY,cb)
Returning from: function add(getX,getY,cb)
Leaving the code example scope
Called: function(xVal) xVal = 2
Called: function(yVal) yVal = 3
Called: function(sum)
5
Returning from: function(sum)

Option 5:

Entering the code example scope
Called: function add(getX,getY,cb)
Returning from: function add(getX,getY,cb)
Leaving the code example scope
Called: function(yVal) yVal = 3
Called: function(xVal) xVal = 2
Called: function(sum)
5
Returning from: function(sum)

Option 6:

Entering the code example scope
Called: function add(getX,getY,cb)
Returning from: function add(getX,getY,cb)
Leaving the code example scope
Called: function(xVal) xVal = 10
Called: function(yVal) yVal = 1
Called: function(sum)
11
Returning from: function(sum)
Called: function(xVal) xVal = 20
Called: function(sum)
21
Returning from: function(sum)
Called: function(xVal) xVal = 30
Called: function(sum)
31
Returning from: function(sum)
Called: function(yVal) yVal = 2
Called: function(sum)
32
Returning from: function(sum)
Called: function(yVal) yVal = 3
Called: function(sum)
33
Returning from: function(sum)

當然還有更多可能的流量。任何一個函式都可以同步或異步多次呼叫它的回呼(不僅僅是一次),或者它可以在一個間隔上永遠呼叫它,或者它可以有條件地呼叫它——所以有時甚至一次都不會。

從上面的所有可能性中可以看出,如果沒有函式的檔案或源代碼fetchXfetchY就不可能確定流程是什么。此外,流程將根據傳入的函式動態變化。

您可以復制上面的任何代碼片段并更改其中的邏輯fetchXfetchY然后自己探索您感興趣的其他流程。

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/414260.html

標籤:

上一篇:Async函式在.then之后回傳Promise

下一篇:未來的catchError函式在未立即鏈接時不會捕獲錯誤

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more