主頁 >  其他 > 漫談socket-io的基本原理

漫談socket-io的基本原理

2021-04-02 07:54:21 其他

大綱

    • 前言
    • 沒有阻塞的代價
    • 阻塞的代價
    • 多執行緒模式-緩解IO處理能力方式之一
    • 基于IO通知的多路復用 - Polling 原理
    • 提升Polling的效率-epoll原理

前言

socket-io 是服務端高性能通信的基石,只有徹底弄清楚socket-io原理,才能真正理解一些高性能框架如rocketmq、netty、以及web容器的底層到底做了什么,

整個socket的知識體系很大,包括計算機網路協議、計算機組成原理(網卡、DMA)、作業系統的IO機制等,沒辦法一次性的全部展開,本文的切入點是解釋清楚 socket 場景下,作業系統對 io 的處理程序,為了降低理解成本,將穿插一個現實場景下的例子闡述,辦好小板凳,開始了~

注:本文只是介紹宏觀的基本概念,具體技術細節將通過另外博客闡述,敬請關注后續內容,公眾號: louluan_note(亦山札記)

本主要介紹socket-io的基本原理,如果想了解具體底層實作邏輯,請看我的另外一個博文 《socket-io的底層實作設計原理》


沒有阻塞的代價

大齡程式員 亦山 因年齡過大,體力不行沒機會繼續修福報,被公司想社會輸出人才,就這樣失業了,但是總歸要養家呀,于是乎就找了個檔口,開了一家小餐館,名為:“程式員再就業餐廳”,
由于資金有限,只能請得起 一名服務員Amy一個后廚 Tony,就這樣,"程式員再就業餐廳"正式營業了,

老板亦山 規定了 服務員Amy的作業內容:

  1. 去前臺接待顧客;
  2. 如果接待到顧客,則安排顧客就坐;
  3. 去每個就餐的餐桌上,看是否需要服務,服務內容有兩項:
    3.1. 查看顧客是否已經下好單;如果已下單,則交給后廚tony 準備;
    3.2. 如果有菜已經準備好,并且餐桌還放得下,則給顧客上菜;
  4. 重復1、2、3
    (請注意: 這里描述的步驟轉換成程式描述的語言,每個步驟都是非阻塞的,)

服務員Amy 的作業內容用流程圖表示如下圖:
服務員Amy的作業
再來看下餐廳里的情況:
在這里插入圖片描述
將服務員Amy 的作業轉換成代碼,大致是這樣的:

package org.luanlouis.socket.noblocking;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * 服務員抽象
 */
public abstract class AbstractWaiter {


    /**
     * 服務的餐桌串列
     */
    private List<Table> servedTableList = new ArrayList<>();

    /**
     * 前臺接待顧客
     * 如果回傳為空,表示 沒有接待到
     * 此方法不阻塞
     * @return 顧客
     */
    public abstract Customer accept();


    /**
     * 取某個餐桌上的下單串列
     * 如果用戶沒有點好,或者沒有加菜,則回傳為空,
     * 此方法不阻塞
     *
     * @param table 餐桌
     * @return 下單串列
     */
    public abstract OrderList fetchOrderList(Table table);

    /**
     * 上菜
     * 此方法不阻塞,如果餐桌上有空余位置,則上菜,否則不上菜
     *
     * @param table 餐桌
     */
    public abstract Boolean serveDishes(Table table);


    /**
     * 服務入口
     * 主要作業項:
     >  1. 去前臺接待顧客;
     >  2. 如果接待到顧客,則安排顧客就坐;
     >  3. 去每個就餐的餐桌上,看是否需要服務,服務內容有兩項:
     >  3.1. 查看顧客是否已經下好單;如果已下單,則交給后廚`tony` 準備;
     >  3.2. 如果有菜已經準備好,并且餐桌還放得下,則給顧客上菜;
     >  4. 重復1、2、3
     */
    public void serve(){
        while(true){
            //前臺接待顧客
            Customer customer = accept();
            if(null != customer){
                Table table = assignAvailableTable(customer);
                servedTableList.add(table);
                System.out.println("前臺 接到顧客: " + customer.customerNo + ",分配到餐桌: "+table.getNumber());
            }else{
                System.out.println("前臺尚未接待到顧客...");
            }
            //依次遍歷服務的餐桌
            servedTableList.forEach(table-> {
                // 查看是否餐桌是否點好餐
                OrderList orderList = fetchOrderList(table);
                if(null == orderList || orderList.isEmpty()){
                    System.out.println("餐桌 " + table.getNumber() +" 顧客還沒點好餐... ");
                }else{
                    System.out.println("餐桌 "+ table.getNumber() +" 已經點好餐:" + orderList +",交給后廚... ");
                }
                // 上菜
                serveDishes(table);
            });
        }
    }

    /**
     * 給用戶分配餐桌
     * @param customer
     * @return
     */
    private Table assignAvailableTable(Customer customer) {
        String number = "A"+System.currentTimeMillis();
        return new Table(number,customer);
    }
}

呼叫方式:

package org.luanlouis.socket.noblocking;

/**
 * 服務入口
 */
public class Boostrap {
    public static void main(String[] args) {
        AbstractWaiter waiter = new Waiter();
        waiter.serve();
    }
}

就這樣,服務員Amy 干了半天(6個小時),就哭著跑到老板亦山那里吵著說不干了,問其原因,她說:

第一:我一直在前臺和各個餐桌上來回穿梭,一刻都沒有停歇過啊;
第二:雖然我沒歇著,感覺做的很多無用功啊!這半天里,總共就來了20個顧客,每個顧客平均從接待、點餐、到上菜花的時間是3分鐘,占上午的 (20*3)/(6*60) = 1/6; 其余 5/6 的時間都浪費在前臺和各個餐桌上來回穿梭
我又不是神奇女俠,干不了了,給我結錢走人!

服務員Amy作業模式的問題,轉換成計算機表達的問題是:

一段代碼在沒有阻塞的情況下,持續讓CPU在執行回圈,而絕大部分的時間都是花在了驗證執行條件是否滿足上,這會導致CPU的利用率一直是100%,這本身是非常大的機器損耗;如果是在多執行緒作業模式下,還會影響到其他執行緒的執行時間(作業系統的執行緒時間片分配),

聽著 Amy 的哭訴,老板 亦山 覺得很有道理,這叫誰誰都扛不住,趕忙安慰安慰,這樣下去肯定不是辦法,老板亦山思考了片刻之后,說我給你換個作業方式吧,

阻塞的代價

老板 亦山 調整了服務員Amy 的作業方式:

  1. 在前臺必須接待到顧客,如果沒接到顧客,就一直等待,直到接到顧客;
  2. 依次去每一個顧客的餐桌上服務,服務內容不變,但是策略調整了:
    2.1 等待顧客下單,如果沒有下單,就一直等待
    2.2 給顧客上菜,如果餐桌沒有沒有空余空間,就一直等待,直到顧客吃完其他的菜騰出空間來,

Amy 聽后,非常高興,只要條件不滿足,她就一直等待,不用做沒有意義的空跑了,作業模式如下圖:
在這里插入圖片描述
就這樣作業了沒多會兒,顧客就開始投訴了,說服務員的服務效率慢,老板 亦山一看,確實慢!來看看服務員Amy 慢在什么地方:

場景一前臺阻塞服務員Amy 在前臺等待顧客,但是顧客遲遲沒有來;而之前接待好的入座的顧客,有的顧客點好菜下單了,但是遲遲沒有交給后廚Tony 去做;還有的顧客是 后廚Tony的菜已經準備好了,但是遲遲沒有服務員上菜;
在這里插入圖片描述
場景二: 顧客點菜時阻塞服務員Amy 在等 A1餐桌的顧客點菜下單,但是顧客考慮了很久都沒點好;而這時前臺已經排了很長的隊伍等待接待;另外A2,A3桌的顧客還在當著服務(點菜下單或上菜)
在這里插入圖片描述

場景三: 上菜時阻塞服務員Amy 在給A2餐桌上菜,但是A2桌 之前已經上滿了,沒有多余空間了,所以Amy 在等待;而這時前臺已經排了很長的隊伍等待接待;另外A1,A3桌的顧客還在當著服務(點菜下單或上菜)
在這里插入圖片描述
根據上述的幾個阻塞場景可以看出,任何一個環節阻塞,將會導致其他顧客都得不到任何服務!
還有一個致命的問題是:任何一個阻塞場景是沒有阻塞時間限制,有無限等待阻塞的可能:如前臺等待,可能一直等不到任何顧客;等待顧客點餐,但是顧客可能就是遲遲不能下決定,甚至顧客還在等人;顧客吃的非常慢,桌子上一直沒有空余出來空間能夠上新的菜…

老板亦山 這么一分析,這可不行,這樣的話,我這一天接待不了多少顧客,要血虧的… 轉念一想,既然前臺、和每個接待的餐桌都可能阻塞,我多招些服務員,每個人負責一個餐桌不就可以緩解了嗎?

多執行緒模式-緩解IO處理能力方式之一

基于上述的慘痛的代價,老板亦山 決定多雇點員工,保證前臺和每個餐桌上都有一個服務員可接待,大概的作業模式如下圖所示:
在這里插入圖片描述
這里對服務員做了簡單的區分:

  • 前臺接待服務員:作業內容是在前臺接待顧客(沒有顧客上門時阻塞),安排到一個座位上,然后指定服務員負責接待
  • 餐桌服務員:作業內容是 接待顧客,等顧客點餐(未拿到點餐串列時阻塞),拿到訂餐串列交給后廚;給顧客上菜(餐桌已滿沒地方放時阻塞)

在代碼層面職能描述如下:

/**
 * 前臺服務員
 */
public class Receptionist extends AbstractWaiter {

    ExecutorService tableWaiterPool = Executors.newFixedThreadPool(20);

    /**
     * 前臺接待顧客
     * 如果回傳為空,表示 沒有接待到
     * 此方法不阻塞
     * @return 顧客
     */
    public Customer accept(){
        //模擬沒有接待到的場景
        if( new Random(10).nextInt(3) ==2){
            return null;
        }
        return new Customer("Customer_"+System.currentTimeMillis());
    }
    
    @Override
    public Table assignAvailableTable(Customer customer) {
        return null;
    }

    /**
     * 服務內容:
     * 1. 前臺接待
     * 2. 給接待的顧客安排座位并且指定服務員
     */
    @Override
    public void serve() {
        while(true){
            //前臺接待顧客,可能阻塞
            Customer customer = accept();
            if(null != customer){
                final Table table = assignAvailableTable(customer);
                servedTableList.add(table);
                System.out.println("前臺 接到顧客: " + customer.customerNo + ",分配到餐桌: "+table.getNumber());

                //分配服務員
                tableWaiterPool.submit(new Runnable() {
                    public void run() {
                        new TableWaiter(table).serve();
                    }
                });
            }else{
                System.out.println("前臺尚未接待到顧客...");
            }
        }
    }
}

而餐桌服務員的作業內容如下:

/**
 * 餐桌服務員
 */
public class TableWaiter extends Waiter {

    public Table table;
    public TableWaiter(Table table) {
        this.table = table;
    }

    /**
     * 主要做兩件事:
     * 1. 等待顧客下單(如果顧客遲遲沒有下單,在一直等待)
     * 2. 上菜,如果餐桌已滿,則可能阻塞等待
     */
    @Override
    public void serve() {
        while(true){
            // 查看是否餐桌是否點好餐,可能阻塞
            OrderList orderList = fetchOrderList(table);
            if(null == orderList || orderList.isEmpty()){
                System.out.println("餐桌 " + table.getNumber() +" 顧客還沒點好餐... ");
            }else{
                System.out.println("餐桌 "+ table.getNumber() +" 已經點好餐:" + orderList +",交給后廚... ");
            }
            // 上菜,可能阻塞
            serveDishes(table);
        }

    }
}

每個餐桌一個服務員的模式,乍一看是緩解了一個只有一個服務員處理處理不過來接待和服務的問題,但是老板亦山 月底做結算的時候發現:

  • 不得了,店面的收入遠遠不及員工工資的!
  • 另外雖然每個餐桌配備了服務員,實際上服務員真正作業的時間(下單和上菜)非常短,其他時間都在做無謂的等待

這個代價太大了!這種模式轉換成計算機語言表述是:

多執行緒模式下的socket-io 能夠有效地緩解了 當系統中io過多中,io因阻塞問題來不及處理的吞吐問題;但是引入了多執行緒模式, 會導致執行緒數量會隨著請求數直線膨脹;作業系統內執行緒數過多會導致CPU時間片分配會被嚴重打散,每個執行緒的處理請求所需要的時間會被大幅延長,另外由于執行緒過多,導致作業系統要分配大量的記憶體來維護執行緒背景關系,也增加了空間成本,
所以可以得出一個結論:靠分配獨立執行緒的模式無法解決多IO操作的問題,

最終,迫于無奈,老板亦山 還是辭退和其他的服務員,就只留下了 服務員Amy廚師Tony

基于IO通知的多路復用 - Polling 原理

老板亦山 再回頭思考了三種阻塞場景:

  • 前臺接待顧客(如果沒有等到,就一直阻塞)
  • 餐桌服務,獲取顧客下單串列(如果沒下單,就一直阻塞)
  • 餐桌服務,給顧客上菜(如果餐桌沒有空余位置,就一直阻塞)

如果讓服務員服務,每個環節都有可能阻塞,實際上阻塞的原因是因為顧客的需求還沒準備好,那能不能換個思路呢?如果是顧客需要服務的時候,通知 服務員Amy 一下,然后Amy在到前臺或者各個餐桌上,(如前臺顧客已到達、餐桌上顧客選單點好、餐桌上已經空出空余空間) 那基本上就不存在等待阻塞的情況了!

于是乎,老板亦山 對店面做了升級,并對服務員Amy的服務方式做了調整:

  • 在前臺和每個餐桌上安排了一個鬧鈴,如果需要服務,顧客就按下鬧鈴,鬧鈴通知接收器會發出聲響;
  • 服務員Amy 身上安裝一個鬧鈴通知接收器,如果接收到了通知,則表示需要服務了,否則就一直等待,但是這個接收器功能有個限制:不知道是具體前臺或者哪個餐桌具體發出的,需要到前臺和餐桌一個個遍歷一遍去查看到底是哪些滿足條件(詢問的程序是非阻塞的),找到后再提供服務,

在這里插入圖片描述
在這種作業模式下,服務員Amy 的作業模式就變成了:

  1. 等待鬧鈴(如果沒接收到,一直阻塞);
  2. 如果鬧鈴響了,則依次遍歷前臺和所有的餐桌,看哪些需要服務(詢問的程序是非阻塞的),然后提供服務
/**
 * 基于鬧鈴通知作業模式的服務員
 */
public abstract class MultiWaiter extends AbstractWaiter {


    /**
     * 如果沒有觸發,則一直等待
     * @return true
     */
    public abstract boolean alarmTriggered();

    /**
     * 是否 下好單
     * @return
     */
    public abstract boolean isOrderListReady(Table table);

    /**
     * 餐桌上是否有空余空間
     * @return
     */
    public abstract boolean isTableAvailable(Table table);

    /**
     * 服務入口
     */
    public void serve(){
        //等待鬧鈴觸發,如果沒有,則一直等待
        while(alarmTriggered()){
            servedTableList.forEach(item->{
                //判斷是否已經下好單,非阻塞
                if(isOrderListReady(item)){
                    //TODO:  選單串列交給后廚做菜
                }
                //判斷是否有空余空間,非阻塞
                if(isTableAvailable(item)){
                    //TODO:  上菜
                }
            });
        }
    }
}

上述服務員Amy 可以監聽前臺和所有餐桌的鬧鈴通知的模式,在計算機語言中,被稱為多路復用-multiplexor,接收到鬧鈴通知后,然后逐次遍歷前臺和各個餐桌的程序,在計算機語言中,稱為Polling -輪詢模式

這種Polling-IO 模式 是 Windows 和早期Linux 2.6 之前的主要支持模式,Polling 的主要問題是 如果 socket 連接過多,而基于這種通知模式,需要依次輪詢每個socket 查看狀態,這個勢必造成極大的性能損耗,

這種模式下,老板亦山 發現服務員Amy 的服務顧客數顯著增加,并且也沒有這么疲勞了,開了一段時間之后,發現收入非常可觀,想擴大店面,之前是10個餐桌,現在擴大到100個,

服務員Amy 有不開心了她說:老板,現在100個餐桌+一個前臺,只要有一個按了鬧鈴,我要把所有的餐桌都要遍歷一遍,這個效率太低了啊,我跑了太多的冤枉路,能不能升級下你的鬧鈴,鬧鈴響的時候,顯示下是哪個餐桌或前臺按的?

老板亦山 想了想,說:“好,雖然升級鬧鈴需要額外成本,為了你的健康和效率,必須升級”,

提升Polling的效率-epoll原理

升級后的餐館,變成了這個樣子:
在這里插入圖片描述
前臺和餐桌的真正觸發了通知,會被記錄在一個訊息佇列中,在服務員Amy 從鬧鈴等待恢復的程序中,遍歷的串列是真正觸發通知的,這樣,Amy 的服務能力又能提升很多倍!

這種模式在計算機語言中,被稱為epoll 模式,在Linux 2.6 及以后的內核得到了支持,

本主要介紹socket-io的基本原理,如果想了解具體底層實作邏輯,請看我的另外一個博文 《socket-io的底層實作設計原理》


注:本文只是介紹宏觀的基本概念,具體技術細節將通過另外博客闡述,敬請關注后續內容,公眾號: louluan_note(亦山札記)

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

標籤:AI

上一篇:Python函式的引數型別和使用技巧

下一篇:演算法面試記錄-某集團公司

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

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more