主頁 > 軟體工程 > 對于多人游戲,只有一個客戶端在多執行緒服務器中接收訊息

對于多人游戲,只有一個客戶端在多執行緒服務器中接收訊息

2021-11-02 09:11:14 軟體工程

我的目標是result在客戶端螢屏上列印來自函式的訊息但是只有一個客戶端可以收到訊息我認為問題是關于socket.recv,但我不知道如何處理它。


client.py 在這里

    #!/usr/bin/python3


#   *********************************************************   #
#
#   Function: Authentication
#   get user input
#   pass to server to check that the input is valid or not.
#
#   *********************************************************   #
def Authentication(clientSocket):
    user_name = input("Please input your user name: ")
    password = input("Please input your password: ")
    username_with_password = str("/login "   user_name   " "   password)
    clientSocket.send(username_with_password.encode())
    back_msg = clientSocket.recv(1024).decode()
    print(back_msg)
    if(back_msg == "1001 Authentication successful"):
        clientSocket.send("Yes".encode())
        return True
    else:
        clientSocket.send("NO".encode())
        return False

#   *********************************************************   #
#
#   Function: List_request
#   call when user input /list
#   print the room list
#
#   *********************************************************   #
def List_request(clientSocket):
    clientSocket.send("list".encode())
    back_msg = pickle.loads(clientSocket.recv(1024))
    for i in back_msg:
        print(i, end=' ')
    print("")

#   *********************************************************   #
#
#   Function: exit_request
#   call when user input /exit
#   print the exit message
#
#   *********************************************************   #
def exit_request(clientSocket):
    clientSocket.send("exit".encode())
    back_msg = clientSocket.recv(1024).decode()
    print(back_msg)

#   *********************************************************   #
#
#   Function: enter_request
#   call when user input /enter
#   first split /enter and x, where x is the room number
#
#   *********************************************************   #
def enter_request(clientSocket, num):
    willsend = "enter " str(num)
    clientSocket.send(willsend.encode())
    back_msg_1 = clientSocket.recv(1024).decode()

    print(back_msg_1)
    if(back_msg_1 == '3011 Wait'):
        back_msg_2 = clientSocket.recv(1024).decode()
        print(back_msg_2)
        return 'wait2'
    elif(back_msg_1 == "3012 Game started. Please guess true or false"):
        return 'wait'
    else:
        return '2'

#   *********************************************************   #
#
#   Function: OtherMsg
#   call when user invalid input
#
#   *********************************************************   #
def OtherMsg(clientSocket):
    msg = "other"
    clientSocket.send(msg.encode())
    msg_back = clientSocket.recv(1024).decode()
    print(msg_back)

#   *********************************************************   #
#
#   Function: GrabCommand_Game_Hall
#   Call when user go into game hall
#   handle different command by different function
#
#   *********************************************************   #
def GrabCommand_Game_Hall(command, num, clientSocket):
    if(command == "/list"):
        List_request(clientSocket)

    elif(command == "/exit"):
        exit_request(clientSocket)
        return '1'

    elif(command == "/enter"):
        c = enter_request(clientSocket, num)
        return str(c)

    else:
        OtherMsg(clientSocket)
        return '2'

#   *********************************************************   #
#
#   Function: PlayGame
#   call when user in the game
#   split the /guess true_false command to true / false
#   determine the input is valid or invalid
#
#   *********************************************************   #
def PlayGame(clientSocket, msg):
    invalid = "NO!"
    if ("/guess " in msg):
        msg1 = msg.split(" ")[1]
        if msg1 == "true" or msg1 == "false":
            clientSocket.send(msg1.encode())
            print(clientSocket.recv(2048).decode())
            return '1'

        else:
            clientSocket.send(invalid.encode())
            print(clientSocket.recv(1024).decode())
            return '2'
    elif msg == "":
        return '2'
    else:
        clientSocket.send(invalid.encode())
        print(clientSocket.recv(1024).decode())
        return '2'


def main(argv):
    serverName = str(sys.argv[1])
    serverPort = int(sys.argv[2])
    try:
        clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        clientSocket.connect((serverName, serverPort))
    except socket.error as err:
        print("Socket error: ", err)
        sys.exit(1)

    # Authentication until successes
    while( Authentication(clientSocket) != True):
        {}


    Input = ""
    num = 0
    #   In the game hall, only leave when user input /exit.
    while(Input != '/exit' ):

        Input = input()
        if(" " in Input):   #   used to split /enter command
            Input, num = Input.split(" ")[0], Input.split(" ")[1]

        var = GrabCommand_Game_Hall(Input, num, clientSocket)
        if(var == '1'): #   terminae
            Input = '/exit'

        elif(var == '2'):
            {}

        elif (var == 'wait'):   #   the "3001" command printed, wait for other player
            msg = ""
            while (PlayGame(clientSocket, msg) != '1'):
                msg = input()

        elif (var == 'wait2'):  # the "3002 command printed, go to play game.
            msg = ""
            while (PlayGame(clientSocket, msg) != '1'):
                msg = input()
        else:
            {}

    print("Client ends")
    clientSocket.close()
    exit(1)

if __name__ == '__main__':
    main(sys.argv)

server.py 在那里

#   *********************************************************   #
#
#   Function: ReadUserInfo
#   Read and split the username and password from UserInfo.txt
#   store the username and password in the list
#
#   *********************************************************   #
def ReadUserInfo(filepath,username, password):
    with open(str(filepath)) as f:
        lines = f.readlines()
        for line in lines:
            username.append((str(line).split(':')[0]))
            password.append(str(line).split(':')[1].rstrip('\n'))

#   *********************************************************   #
#
#   Function: authenticates
#   Check whether username, password is correct or not.
#
#   *********************************************************   #
def authenticates(username, password, username_list, password_list):
    if username in username_list:
        if password in password_list:
            if username_list.index(str(username)) != password_list.index(str(password)):
                return "1002 Authentication failed"
            else:
                return "1001 Authentication successful"
        else:
            return "1002 Authentication failed"
    else:
        return "1002 Authentication failed"

#   *********************************************************   #
#   
#   Initialize the variable
#
#   *********************************************************   #

NUM_OF_ROOM = 10
serverPort = int(sys.argv[1])
UserInfo_path = str(sys.argv[2])
username = []   #store all username
password = []   #store all password
addr_l = []     #store all address
name_list = []
current_rm_num = []

guess_box = []
guess = bool(random.randint(0, 1))

room = [NUM_OF_ROOM]   [0] * 10 #There 10 rooms
room[0] = NUM_OF_ROOM   #the first element of room list is 10 (num of room).
print(room)
ReadUserInfo(UserInfo_path, username, password)
state = [0] * len(username)

#   *********************************************************   #
#
#   Function: RecevFromClient
#   get client message (input)
#   use for auth. users
#   Check the input is valid or not
#
#   *********************************************************   #
def RecvFromClient(connectionSocket):
    message1 = connectionSocket.recv(2048).decode()
    name_list.append(str(message1).split(" ")[1])
    msg_return = authenticates(str(message1).split(" ")[1], str(message1).split(" ")[2], username, password)
    connectionSocket.send(msg_return.encode())
    message = connectionSocket.recv(2048).decode()
    if message == 'Yes':
        state[username.index(str(message1).split(" ")[1])] =1
    return str(message)

#   *********************************************************   #
#
#   GameHallMsg
#   Receive command in game hall
#
#   *********************************************************   #

def GameHallMsg(connectionSocket, addr, addr_l):
    message1 = connectionSocket.recv(1024).decode()

    if(message1 == 'list'):
        room_1 = ["3001"]   room
        data = pickle.dumps(room_1)
        connectionSocket.send(data)
        return 'ok'

    elif(message1 == 'exit'):
        rtn_msg = "4001 Bye bye"
        connectionSocket.send(rtn_msg.encode())
        state[addr_l.index(addr)-1] -= 1
        return 'bye'

    elif(message1.split(" ")[0] == 'enter'):
        num = int(message1.split(" ")[1])
        if(num > len(room)-1 or num == 0):
            msg = "Please input the /enter command again! "
            connectionSocket.send(msg.encode())
            return 'ok'


        elif (room[num] == 0):
            rtn_msg_1 = "3011 Wait"
            room[int(num)]  = 1
            state[addr_l.index(addr)] = int(num)
            current_rm_num.append(num)
            print("Player name:",name_list[addr_l.index(addr)],"joined room", num)

            connectionSocket.send(rtn_msg_1.encode())
            return 'wait'

        elif (room[int(num)] == 1):
            room[int(num)]  = 1
            state[addr_l.index(addr)]  = 1
            rtn_msg_2 = "3012 Game started. Please guess true or false"
            current_rm_num.append(num)
            print("Player name:", name_list[addr_l.index(addr)], "joined room", num)
            connectionSocket.send(rtn_msg_2.encode())
            return 'jump'


        elif (room[int(num)] >= 2):
            rtn_msg_3 = "3013 The room is full"
            connectionSocket.send(rtn_msg_3.encode())
            return 'ok'


    else:
        return 'NO'

#   *********************************************************   #
#
#   Function: result
#   check the result.. i.e. win / lose / tie
#
#   *********************************************************   #

def result(connectionSocket, guess_box, addr, addr_l):
    a = 0
    c = addr[1]
    print(addr)
    print(addr_l)
    if(guess_box[0] == guess_box[1]):
        msg = "Tie!!"
        connectionSocket.sendto(msg.encode(), addr)
        return '2'

    elif(guess_box[addr_l.index(c)] == guess):
        msg1 = "You are Winner!"
        a =1
        connectionSocket.sendto(msg1.encode(), addr)
        return '2'
    elif(guess_box[addr_l.index(c)] != guess):
        msg2 = "You lose the game."
        a =1
        connectionSocket.sendto(msg2.encode(), addr)
        return '2'

#   *********************************************************   #
#
#   Function: TF
#   convert the /guess true or /guess false --> true or false
#
#   *********************************************************   #

def TF(connectionSocket, var, guess_box):
    msg = connectionSocket.recv(1024).decode()
    print("recv:",msg)
    if(msg == 'true'):
        msg = 'True'
        var = str(var)
        msg = bool(msg == var)
        guess_box.append(msg)
        return 'ok'
    elif(msg == 'false'):
        msg = 'False'
        var = str(var)
        msg = bool(msg == var)
        guess_box.append(msg)
        return 'ok'
    else:
        print(msg)
        statement = "4002 Unrecognized message!!"
        connectionSocket.send(statement.encode())
        return 'again'

#   *********************************************************   #
#
#   Thread
#   for every client
#
#   *********************************************************   #

class ServerThread(threading.Thread):
    def __init__(self, client):
        threading.Thread.__init__(self)
        self.client = client

    def run(self):
        connectionSocket, addr = self.client
        addr_l.append(addr[1])
        while(RecvFromClient(connectionSocket) == "NO"):
            {}
        print(addr_l)
        a = ''
        while(a != 'ex'):
            var = GameHallMsg(connectionSocket, addr[1], addr_l)
            if var == 'bye':
                break
            elif (var == 'wait'):
                while(a != 'b' ):
                    if(len(current_rm_num) == 2):
                        rtn_msg_2 = "3012 Game started. Please guess true or false"
                        connectionSocket.send(rtn_msg_2.encode())
                        print("guess is:", guess)
                        while (len(guess_box) != 2):
                            print(guess_box)
                            TF(connectionSocket, guess, guess_box)

                        a = 'b'

                        result(connectionSocket, guess_box, addr, addr_l)


            elif (var == 'NO'):
                rtn_msg_4 = "4002 Unrecognized message"
                connectionSocket.send(rtn_msg_4.encode())
            elif(var == 'ok'):
                {}
            elif(var == 'jump'):
                while (a != 'b'):
                    if (len(current_rm_num) == 2):
                        while (len(guess_box) != 2):
                            print(guess_box)
                            TF(connectionSocket, guess, guess_box)
                        result(connectionSocket, guess_box, addr, addr_l)

                        a = 'b'

class ServerMain:
    def server_run(self):
        serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            serverSocket.bind(("localhost", serverPort))
        except socket.error as err:
            print("Binding error: ", err)
            sys.exit(1)
        serverSocket.listen(len(username))


        while True:
            client = serverSocket.accept()
            t = ServerThread(client)
            t.start()


if __name__ == '__main__':
    server = ServerMain()
    server.server_run()

UserInfo.txt 的內容是用戶名和密碼,格式 Username:password


預期的輸入 - 輸出是:

對于服務器終端

 % python3 server.py 12345 [path_of_userinfo.txt]

對于 Client_1 的終端(輸入以“*”開頭)

% python3 client.py localhost 12345
Please input your user name:*username
Please input your password:* password
1001 Authentication successful
*/enter room_num
3011 Wait
3012 Game started. Please guess true or false
*/guess true
You are the loser! # If the random variable is false, not equal to true

對于 Client_2 的終端(輸入以“*”開頭)

   % python3 client.py localhost 12345
    Please input your user name: *username_2
    Please input your password: *password_2
    1001 Authentication successful
    */enter room_num
    3012 Game started. Please guess true or false 
    */guess false
    You are winner! # If the random variable is false

uj5u.com熱心網友回復:

僅關于您解決的一個問題:

在客戶端螢屏上列印來自函式結果的訊息。但是只有一個客戶端可以收到訊息

問題來自為每個客戶端使用不同的執行緒。首先接收猜測的執行緒停留在其

                        while (len(guess_box) != 2):
                            print(guess_box)
                            TF(connectionSocket, guess, guess_box)

回圈并等待另一條訊息,該訊息沒有出現。作為第二個接收猜測的執行緒只將結果發送給它自己的客戶端。

我認為在保持這種d執行緒方法的同時,沒有一種明智的方法可以解決這個問題

我可以使用我實作的那些函式來更改我的代碼結構嗎?

下面是在一個替代while True的回圈server_run,不需要在改變這些功能比其他server_run

        from select import select
        connections = []
        room_connection = {}
        for reads in iter(lambda: select([serverSocket] connections, [], [])[0], []):
            for ready in reads: # for each socket which select reports is readable
                if ready == serverSocket:   # it's the server socket, accept new client
                    connectionSocket, addr = serverSocket.accept()
                    connections.append(connectionSocket)# store the connection socket
                    while RecvFromClient(connectionSocket) == "NO": pass
                else:           # message (or disconnect) from a client
                    try: var = GameHallMsg(ready, ready, connections)
                    except socket.error: var = 'bye'
                    if var == 'bye':    # client finished, remove from list
                        connections.remove(ready)
                        ready.close()
                    elif var == 'wait': # store first player's connection
                        room_connection[current_rm_num.pop()] = ready
                    elif var == 'NO':
                        rtn_msg_4 = "4002 Unrecognized message"
                        ready.send(rtn_msg_4.encode())
                    elif var == 'jump':
                        readyroom = current_rm_num.pop()
                        # find and notify other player in the room
                        other = room_connection.pop(readyroom)
                        rtn_msg_2 = "3012 Game started. Please guess true or false"
                        other.send(rtn_msg_2.encode())
                        print("guess is:", guess)
                        # query and inform both players
                        guess_box = []
                        while TF(ready, True, guess_box) != 'ok': pass
                        while TF(other, True, guess_box) != 'ok': pass
                        result(ready, guess_box, ('', 0), [0])
                        result(other, guess_box, ('', 1), [0, 1])
                        room[readyroom] = 0

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

標籤:Python 插座 联网 服务器 客户

上一篇:撰寫GET請求以回傳HTTP1.1而不是1.0

下一篇:IOBluetooth塊通過沙箱訪問

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