主頁 > 軟體工程 > 2個節點碰撞的時間

2個節點碰撞的時間

2021-12-07 04:59:58 軟體工程

我們得到了一個N節點(1-N),其中每個節點都有1指向某個節點的精確定向邊(該節點可以是同一個節點)。

我們需要回答: 型別查詢A, B,它詢問兩個物件碰撞所需的時間,如果一個從 開始,A另一個從 開始B兩個動作都11秒為單位。如果他們不可能發生碰撞,時間將是-1.

時間:從X-> 到Y:1 跳 = 1 秒。

約束

N, Q <= 10^5 (number of nodes, number of queries).

示例:對于給定的圖形

   A -> B -> C -> D -> E
                  ^    |
                  K <- F

Query(A, E) : 3 seconds, as at time t = 3 secs they both will be on node D.
Query(C, D) : -1 seconds, as they will never collide.

回答每個查詢的最佳方式是什么?

蠻力方法:時間 - O(Q * N)

使用二元提升技術改進的解決方案:時間 -O(Q * log(N))

private static int[] collisionTime(int N, int Q, int[] A, int[][] queries) {

    // ancestor matrix : creation time- O(n * log(n))
    int M = (int) (Math.ceil(Math.log10(N) / Math.log10(2)))   1;
    int[][] ancestor = new int[N   1][M];
    for(int i = 1; i <= N; i  ) {
        ancestor[i][0] = A[i]; // 2^0-th ancestor. 
    }
    for(int j = 1; j < M; j  ) {
        for(int i = 1; i <= N; i  ) {
            ancestor[i][j] = ancestor[ancestor[i][j-1]][j-1];
        }
    }

    int[] answer = new int[Q];
    for(int i = 0; i < Q; i  ) { 
        int u = queries[i][0];
        int v = queries[i][1];
        answer[i] = timeToCollide(u, v, ancestor);
    }

    return answer;
}

// using binary lifting: time- O(log(n))
private static int timeToCollide(int u, int v, int[][] ancestor) {
    int m = ancestor[0].length;

    // edge cases
    if(u == v)                              // already in collision state
        return 0;              
    if(ancestor[u][m-1] != ancestor[v][m-1]) // their top most ancestor is not the same means they cannot collide at all.
        return -1;

    int t = 0;
    for(int j = m - 1; j >=0; j--) {
        if(ancestor[u][j] != ancestor[v][j]) {
            u = ancestor[u][j];
            v = ancestor[v][j];
            t  = Math.pow(2, j);
        }
    }
    return t   1;
}

uj5u.com熱心網友回復:

只有在有 1 個以上鏈接的節點上才會發生沖突。您的示例中的節點 D。

讓我們稱這些節點為“崩潰站點”

因此,您可以將圖形修剪為僅崩潰站點節點。通向崩潰站點節點的節點成為崩潰站點節點的屬性。

像這樣為你的例子:

D : { A,B,C }, { E,F,K }

只有當起始節點位于同一崩潰站點節點的兩個不同屬性串列上時,才會發生沖突。

一旦確定可能發生崩潰,您就可以檢查兩個起始節點與崩潰地點的距離是否相同。

演算法:

Prune graph to crash site nodes
LOOP over questions
Get 2 start nodes
LOOP over crash sites
   IF start nodes on two different attributes of crash site
        IF start nodes are equi-distant from crash site
             report crash time
             BREAK from crash site loop

這是一個隨機生成的圖,有 50 個節點,其中每個節點都有一個外邊連接到另一個隨機選擇的節點

2個節點碰撞的時間

碰撞地點是

5 7 8 9 10 11 18 19 23 25 31 33 36 37 39

所以演算法最多只需要回圈15個節點,而不是50個。

“兩個特定節點會發生碰撞嗎?”這個問題的答案 幾乎總是“不”。這樣有點無聊。所以讓我們問一個稍微不同的問題:“對于一個特定的圖,哪對節點會導致碰撞?” 這需要相同的演算法(應用于每對節點),但總是會產生一個有趣的答案。

對于這個圖

2個節點碰撞的時間

I get this answer

0 and 29 collide at 41
1 and 5 collide at 40
2 and 23 collide at 13
8 and 16 collide at 34
8 and 22 collide at 34
8 and 39 collide at 34
9 and 30 collide at 37
10 and 31 collide at 25
11 and 47 collide at 23
12 and 28 collide at 25
12 and 35 collide at 25
12 and 49 collide at 25
13 and 38 collide at 27
14 and 44 collide at 1
15 and 17 collide at 0
15 and 18 collide at 0
15 and 37 collide at 0
16 and 22 collide at 34
16 and 39 collide at 34
17 and 18 collide at 0
17 and 37 collide at 0
18 and 37 collide at 0
20 and 26 collide at 9
20 and 42 collide at 9
20 and 43 collide at 9
21 and 45 collide at 24
22 and 39 collide at 34
25 and 34 collide at 3
26 and 42 collide at 9
26 and 43 collide at 9
28 and 35 collide at 25
28 and 49 collide at 25
32 and 48 collide at 34
33 and 36 collide at 7
35 and 49 collide at 25
42 and 43 collide at 9

Some timing results

Node Count Crash Sites
millisecs
Question Count Question mean
microsecs
50 0.4 1225 0.02
500 50 124750 0.02
5000 5500 ~12M 0.02
10000 30000 ~50M 0.03
30000 181000 ~450M 0.6

Notes:

  • The mean time for a question is the average of checking every possible pair of nodes for a possible collision.
  • Answering a single question is extremely fast, about 20 nanoseconds for moderately sized graphs ( < 10,000 nodes ) [ A previous timing report included outputting the results when a collision was found, which takes much longer than detecting the collision. These results were taken with all output to the console commented out. ]
  • Setting up the crash sites and their tributaries gets slow with moderately sized graphs ( > 5,000 nodes ). It is only worth doing if a lot of questions are going to be asked.

此代碼可在https://github.com/JamesBremner/PathFinder 獲得

uj5u.com熱心網友回復:

  1. 找出所有終止回圈并指定每個終止回圈中的任意頂點作為回圈根(O(N))
  2. 對于每個頂點,記錄其終止回圈的長度、進入終止回圈的距離以及到終止回圈根的距離 (O(N))。
  3. 切斷每個回圈根的傳出鏈接。這將圖形變成了森林。
  4. 對于每個查詢,找到此林中兩個查詢節點的最近(最低)共同祖先。
  5. 從保存的每個查詢節點和最低共同祖先的資訊中,您可以計算出恒定時間內發生碰撞的時間。

步驟 (4),即最低公共祖先查詢,是一個經過充分研究的問題最好的演算法只需要線性處理時間并提供恒定的查詢時間,導致這個問題的時間復雜度為 O(N Q)。

uj5u.com熱心網友回復:

我相信以下方法在技術上實作了O(N Q)時間復雜度。

public static int[] collisionTime(int N, int Q, int[] A, int[,] queries)
{
    // create the graph and fill-in the mapping attributes for all nodes
    var graph = new MPDGraph(A);
    graph.MapAllNodes();

    int[] answers = new int[queries.GetLength(0)];
    for (int i = 0; i < answers.Length; i  )
    {
        answers[i] = graph.FindCollision(queries[i, 0], queries[i, 1]);
    }

    return answers;
}

這使用了以下類,

MPDGraph 類:

// MPDG: Mono-Pointing, Directed Graph 
//  An MPDG is a directed graph where every node has exactly one out-edge.
//  (MPDG is my own term, I don't know the real name for these)
class MPDGraph
{
    public Node[] Nodes;
    Dictionary<(Node, Node), int> cachedDistances = new Dictionary<(Node, Node), int>();

    // constructor
    public MPDGraph(int[] Pointers)
    {
        Nodes = new Node[Pointers.Length];

        // first fill the array with objects
        for (int i = 0; i < Nodes.Length; i  ) { Nodes[i] = new Node(i); }

        // apply their pointers
        for(int i = 0; i < Nodes.Length; i  ) { Nodes[i].toNode = Nodes[Pointers[i]]; }
    }


    // map all of the nodes by filling their mapping properties
    public void MapAllNodes()
    {
        for(int i=0; i<Nodes.Length; i  )
        {
            if (!Nodes[i].isMapped)
                MapPath(Nodes[i], 1);
        }
    }

    // recursively map a path of unmapped nodes, starting from curr
    //  returns true if curr is in a cycle, false otherwise
    public Boolean MapPath(Node curr, int pathNo)
    {
        Boolean inCycle = false;
        curr.pathNo = pathNo;

        Node next = curr.toNode;

        if (next.IsInPath)
        {
            // we have found a new cycle
            Cycle Cycle = new Cycle(this, next, curr.pathNo - next.pathNo   1);
            curr.Map(Cycle);
            return true;
        }
        else if (next.isMapped)
        {
            // we are joining an already partially mapped tree
            if (next.IsInCycle)
            {
                // next is a tree-Base, the top of our tree and also in the cycle
                curr.Map(next.Cycle, false, next, 1);
            }
            else
            {
                // next is a normal tree-node
                curr.Map(next.Cycle, false, next.BaseNode, next.Distance   1);
            }
            return false;
        }
        else
        {
            // continue forward on the path, recurse to the next node
            inCycle = MapPath(next, pathNo 1);

            if (inCycle)
            {
                if (next.Cycle.Base == next || next.Distance == 0)
                {
                    //we have returned from the cycleBase, which is also a treeBase
                    // so, switch from Cycle to Tree
                    curr.Map(next.Cycle, false, next, 1);
                    return false;
                }
                else
                {
                    // still in the cycle
                    curr.Map(next.Cycle);
                }
            }
            else
            {
                //returned in tree
                curr.Map(next.Cycle, false, next.BaseNode, next.Distance   1);
            }

            return inCycle;
        }

    }


    // Given two starting nodes, determine how many steps it takes until their
    //  paths collide. Returns -1 if they will never collide.
    public int FindCollision(int index1, int index2)
    {
        Node node1 = Nodes[index1];
        Node node2 = Nodes[index2];

        // eliminate trivial cases
        if (node1.Cycle != node2.Cycle)
            return -1;      // cant collide if they're in different subgraphs
        else if (node1 == node2)
            return 0;       // if they're the same node, then distance = 0
        else if (node1.IsInCycle && node2.IsInCycle)
            return -1;      // different nodes in a cycle never collide
        
        else
        {  // they're both in the same subgraph, use math to tell if they collide

            // get their distances to the cycle base
            int dist1 = node1.Distance   (node1.IsInCycle ? 0 : node1.BaseNode.Distance);
            int dist2 = node2.Distance   (node2.IsInCycle ? 0 : node2.BaseNode.Distance);
            int cycleLen = node1.Cycle.Length;

            // use math:  modulo(cycle length)
            if ((dist1 % cycleLen) != (dist2 % cycleLen))
            {
                return -1;      // incompatible distances: cannot possibly collide
            }
            else
            {
                // they must collide somewhere, figure out how far that is
                if (node1.IsInCycle || node2.IsInCycle)
                {
                    // if one is in the cycle, they will collide when
                    // the other one reaches the cycle (it's treeBase)
                    return (!node1.IsInCycle ? node1.Distance : node2.Distance);
                }
                else if (node1.BaseNode != node2.BaseNode)
                {
                    // They are in different trees:  they will collide at
                    //  the treeBase of the node that is farther
                    return Math.Max(node1.Distance, node2.Distance);
                }
                else
                {
                    // They are in the same tree:
                    if (node1.Distance != node2.Distance)
                    {
                        //if they are in the same tree, but have different distances
                        //  to the treeBase, then they will collide at the treeBase
                        //  when the farther one arrives at the treeBase
                        return Math.Max(node1.Distance, node2.Distance);
                    }
                    else
                    {
                        //  the hard case, have to walk down their paths
                        //  to find their LCA (Lowest Common Ancestor)
                        return findTreeDistance(node1, node2);
                    }
                }
            }
        }
    }


    int findTreeDistance(Node node1, Node node2)
    {
        if (node1 == node2) return 0;

        // normalize their order
        if (node1.index > node2.index)
        {
            var tmp = node1;
            node1 = node2;
            node2 = tmp;
        }

        // check the cache
        int dist;
        if (cachedDistances.ContainsKey((node1,node2)))
        {
            dist = cachedDistances[(node1, node2)];
        }
        else
        {
            // keep recursing to find where they meet
            dist = findTreeDistance(node1.toNode, node2.toNode)   1;
            // cache this new distance
            cachedDistances.Add((node1, node2), dist);
        }
        return dist;
    }
}

節點類:

// Represents a node in the MPDG (Mono-Pointing Directed Graph) with the constraint
//  that all nodes have exactly one out-edge ("toNode").
class Node
{
    // Primary properties (from input)
    public int index { get; set; }      // this node's unique index (to the original array)
    public Node toNode { get; set; }    // what our single out-edge is pointing to


    public Node(int Index_) { this.index = Index_; }


    // Mapping properties
    // (these must be filled-in to finish mapping the node)

    //  The unique cycle of this node's subgraph (all MPDG-subgraphs have exactly one)
    public Cycle Cycle;

    //  Every node is either in their subgraphs cycle or in one of the inverted
    // trees whose apex (base) is attached to it.  Only valid when BaseNode is set.
    // (tree base nodes are counted as being in the cycle)
    public Boolean IsInCycle = false;

    // The base node of the tree or cycle that this node is in.
    //  If (IsInCycle) then it points to this cycle's base node (cycleBase)
    //  Else it points to base node of this node's tree (treeBase)
    public Node BaseNode;

    //  The distance (hops) from this node to the BaseNode
    public int Distance = -1;    // -1 if not yet mapped

    // Total distance from this node to the cycleBase
    public int TotalDistance { get { return Distance   (IsInCycle ? 0 : BaseNode.Distance); } }


    // housekeeping for mapping nodes
    public int pathNo = -1;          // order in our working path

    // Derived (implicit) properties
    public Boolean isMapped { get { return Cycle != null; } }
    public Boolean IsInPath { get { return (pathNo >= 0); } }


    public void Map(Cycle Cycle, bool InCycle = true, Node BaseNode = null, int distance_ = -1)
    {
        this.Cycle = Cycle; 
        IsInCycle = InCycle;

        if (InCycle)
        {
            this.BaseNode = Cycle.Base;
            Distance = (Cycle.Length   (Cycle.Base.pathNo - pathNo)) % Cycle.Length;
        }
        else
        {
            this.BaseNode = BaseNode;
            Distance = distance_;
        }

        pathNo = -1;    // clean-up the path once we're done
    }
}

回圈類:

// represents the cycle of a unique MPDG-subgraph
//  (should have one of these for each subgraph)
class Cycle
{
    public MPDGraph Graph; // the MPDG that contains this cycle
    public Node Base;      // the base node of a subgraph's cycle
    public int Length;     // the length of this cycle

    public Cycle(MPDGraph graph_, Node base_, int length_)
    {
        Graph = graph_;
        Base = base_;
        Length = length_;
    }
}

性能測量:

節點數 構建和映射圖
平均微秒
問題數 所有問題都
意味著微秒
問題平均
微秒
總平均
微秒
50 0.9 1225 26 0.0212 26.9
500 10.1 124750 2267 0.0182 2277.1
1000 23.4 499500 8720 0.0175 8743.4
5000 159.6 12497500 229000 0.0183 229159.6
10000 345.3 49995000 793212 0.0159 793557.3

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

標籤:算法 数学 数据结构 图形

上一篇:如何使用貪婪演算法為這個問題獲得O(mlogn)的復雜度

下一篇:二進制表示中的最長公共前綴

標籤雲
其他(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