前端筆記知識點整合之伺服器&Ajax(下)數據請求&解決跨域&三級聯動&session&堆棧

来源:https://www.cnblogs.com/rope/archive/2019/04/15/10704824.html
-Advertisement-
Play Games

一、請求後端的JSON數據 JSON是前後端通信的交互格式,JSON(JavaScript Object Notation, JS 對象標記) 是一種輕量級的數據交換格式。 JSON是互聯網各個後臺與前代溝通必備格式,取代了原來的XML。 XML數據格式特別“噁心”,現在市場上99%以上的數據格式都 ...


一、請求後端的JSON數據

JSON是前後端通信的交互格式,JSON(JavaScript Object Notation, JS 對象標記) 是一種輕量級的數據交換格式。

JSON是互聯網各個後臺與前代溝通必備格式,取代了原來的XML

XML數據格式特別“噁心”,現在市場上99%以上的數據格式都是JSON

工作中都是後端(JavaPHPNode)給我們提供JSON格式的數據,然後我們前端用Ajax去請求得到JSON數據,將JSON數據渲染在前端頁面中。但是伺服器給我們返回的數據是字元串JSON,因此沒辦法打點調用屬性,下麵我們要學習如何解析後端給我們返回的JSON


1.1 JSON解析方法1

獲取PHP中的JSON介面數據:

會發現伺服器給我們返回的數據是字元串JSON,因此沒辦法打點調用屬性

l PHP中可以將數組變為JSON,使用方法json_encode(數組)

 

json_db.php後端提供JSON數據:

<?php
    header("Content-type","application/json");

    //用數組模擬,然後給客戶端返回JSON格式的數據
    $arr = array("result"=> array(
            array("name" => "李白", "age" => 31, "sex"=>"男"),
            array("name" => "蘇軾", "age" => 32, "sex"=>"男"),
            array("name" => "王安石", "age" => 33, "sex"=>"男"),
            array("name" => "杜甫", "age" => 34, "sex"=>"男"),
            array("name" => "李清照", "age" => 35, "sex"=>"女")
        )
    );

    echo json_encode($arr); //將數組變為JSON
?>

 

 前端請求php提供的介面,得到數據渲染在頁面

 $.get("php/json_db.php", function(data){
var dataObj = JSON.parse(data); //將後端返回的字元串轉為JSON對象

//迴圈遍歷輸出
    for(var i = 0; i < dataObj.result.length;i++){
        var arr = dataObj.result[i];
        //上樹
        $("ul").append("<li>"+ arr.name + arr.age + arr.sex +"</li>")
        console.log(dataObj.result[i].age)
        console.log(dataObj.result[i].sex)
    }
 })

JSON.parse()        將JSON形式的字元串轉換為JSON對象
JSON.stringify()   將JSON對象轉換為字元串

 

獲取資料庫中的數據,以JSON的格式返回給前端

data_db.php後端提供JSON數據:

<?php
    //連接資料庫,參數:資料庫地址、用戶名、密碼
    mysql_connect('localhost', 'root', '123456');
    //選擇要操作的資料庫
    mysql_select_db("student");
    //設置編碼
    mysql_query("SET NAMES utf8");
    //寫執行插入的SQL語句,保存到資料庫的表中
    $sql = "SELECT * FROM gz0902";
    //執行SQL語句,會返回成功插入的結果(條數)
    $result = mysql_query($sql);

    $arr = array(); //空數組,迴圈遍歷添加進來的

    //迴圈遍歷賦值,添加到數組
    while($row = mysql_fetch_array($result)){
        array_push($arr, $row);
    }
    //輸出JSON
    $resultJSON = array("result" => $arr);
    echo json_encode($resultJSON);

?>

 

 前端解析JSON

$.get("php/data_db.php", function(data){
   //將JSON形式的字元串轉為真的JSON對象
   var dataObj = typeof data == "object" ? data : JSON.parse(data);
   for(var i = 0; i < dataObj.result.length;i++){
       var arr = dataObj.result[i];
       $("ul").append("<li>"+ arr.name + arr.age + arr.sex +"</li>")
       console.log(dataObj.result[i].age)
       console.log(dataObj.result[i].sex)
   }
})

 


1.2 JSON解析方法2

概述:eval()是系統預設的函數,是window對象方法,因此可以省略window直接使用。

      eval()函數可以將字元串變為語句,把它作為JavaScript代碼執行。

      eval()儘量少用,但是由於相容性好,所以該用的時候也要用

JavaScript為什麼不推薦使用eval

https://www.zhihu.com/question/20591877

var str = "alert(1+2+3)";
console.log(eval(str));

var data = "({a:100,b:200})";
var data = "{a:100,b:200}";
console.log(eval("("+ data +")"))

var fun = "function fun(){alert(1)};fun()";
console.log(eval(fun))

$.get("php/json_db.php", function(data){
    //將JSON形式的字元串轉為真的JSON對象
    var dataObj = eval("(" + data + ")");
})

1.3 JSON解析方法3

第三種方法:使用JS的內置構造函數new Function()

參數:從第一個開始到倒數第二個都是形參,最後一個參數是執行的程式。

Function()函數能把字元串變為語句:

var sum = new Function("a","b","c","return a+b+c");
console.log(sum(3,4,5));

// 等價於
function sum(a,b,c){
   return a+b+c;
}

$.get("php/json_db.php", function(data){
   //將JSON形式的字元串轉為真的JSON對象
   var dataObj = (new Function("return" + data)());
   console.log(dataObj)
})

 


 

二、B/S結構

 

概述:Ajax這門技術它遵循同源策略也就說Ajax不能跨域

同源策略:它是由Netscape提出的一個著名的安全策略現在所有支持JavaScript的瀏覽器都會使用這個策略。

所謂的同源策略:功能變數名稱、協議、埠相同

當一個瀏覽器的兩個tab頁分別打開:百度和谷歌的頁面

當瀏覽器的百度tab頁執行一個腳本的時候會檢查這個腳本是屬於哪個頁面的,

即檢查是否同源,只有和百度同源的腳本才會被執行。

如果非同源,那麼在請求數據時,瀏覽器會在控制臺中報一個異常,提示拒絕訪問。

跨域:其實就是訪問不在同一個伺服器上的數據,就形成了跨域。

比如:老師的伺服器IP192.168.1.100,但是訪問某同學的伺服器中的文件,造成了跨域,會報錯


2.1 Ajax不能跨域

概述:Ajax不能跨域,就比如我們的程式,不能獲取百度、淘寶、京東伺服器的數據。

<script type="text/javascript">
     $.get("http://127.0.0.88/result.txt", function(data){
        console.log(data)
     })
</script>

提示:剛纔模擬兩個伺服器之間請求數據,會發現Ajax不能跨域


 

2.2 JSONP跨域

跨域請求數據也是可以的,只不過Ajax這技術不行,而JSONP這種數據格式可以進行跨域。很多年前,瀏覽器是沒有跨域限制的,可以正常跨域,瀏覽器為了安全和隱私限制了Ajax跨域。

我們可以通過一些數據手段解決:

為什麼使用跨域?當請求不在同一個伺服器數據的時候就用跨域,或者偷數據的時候。

實現方式:HTML中用script標簽引用這個js文件,其實就是對引用文件的函數執行,此時函數定義在HTML中。

 

JSONP原理就是:將函數執行的部分,放到了伺服器上面。

<script type="text/javascript">
    function fun(data){
        console.log(data)
    }
</script>
<script src="http://127.0.0.88/fun_info.txt"></script>

提示:這是老師的本地靜態頁面,當訪問某個同學伺服器的時候,返回的數據來源於某同學伺服器。

將函數執行的部分放在伺服器上。當自己伺服器想獲取其他伺服器上面的數據,你必須聲明一個和其他伺服器上同名的函數。

 

這是http://127.0.0.88/fun_info.txt的數據

fun({"name":"陳雪凝","age":16, "sex":"女"});

提示:怎麼實現的?

答:script標簽當中的src屬性指向一個地址,發起了一次請求。

 

JSONP的優缺點:

優點:

與利用XHR對象發送Ajax請求不同,JSONP可以跨越同源策略;

l JSONP的相容性好,可以在眾多瀏覽器中運行。

缺點:

只支持GET一種類型的HTTP請求,應用場景有限;

l 調用失敗時缺少必要的提示信息,不方便排查問題;

存在一定的安全風險,但可以使用RefererToken校驗進行規避;

l 不便於控制;

l 沒有回調函數的功能。


2.3原生JSONP跨越請求數據

<body>
    <button id="btn">發起請求(JSONP)</button>
</body>
<script type="text/javascript">
     var btn = document.getElementById("btn");

     //函數的定義的
     function fun(data){
        console.log(data)
     }

     //發起請求,獲取到函數執行部分
     btn.onclick = function(){
        //創建script標簽,並指定請求數據地址
        var oscript = document.createElement('script');
        oscript.src = "http://127.0.0.88/fun_info.txt";
       
        //上樹
        document.body.appendChild(oscript);
        //過河拆橋,拿完下樹
        document.body.removeChild(oscript);
     }
</script>

提示:script標簽發起一次請求後,就可以獲取到數據,然後讓元素下樹,不影響返回的數據。

 

Url中的callback對應的是函數的名

提示:如果想獲取別人伺服器上的JSONP數據,你必須聲明一個和別人伺服器上的同名函數(也可以改名)

<script type="text/javascript">
    function fetchJSON_comment98(data){
        console.log(data)
    }
</script>
<!-- <script type="text/javascript" src="http://127.0.0.88/result.txt"></script> -->
<script src="http://127.0.0.88/fun_info.txt"></script>
<script src="https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=598283&score=1&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1"></script>

2.4原生JSONP函數封裝

概述:封裝一個函數,這個函數的作用就是跨域請求別人伺服器的數據,用戶只需要傳進來,url和函數名。

<script type="text/javascript">
     var btn = document.getElementById("btn");

     function JSONP(url, callback){
        //給傳進來的匿名函數起名,並定義在全局
        window.fun = callback;
        //創建DOM
        var oscript = document.createElement('script');
        oscript.src = url;
        //上樹
        document.body.appendChild(oscript);
        //過河拆橋,拿完下樹
        document.body.removeChild(oscript);
     }

     //發起請求
     btn.onclick = function(){
        JSONP("http://127.0.0.88/fun_info.txt", function(data){
            console.log(data);  //data數據是從函數執行部分傳過來的
        })
     }
</script>

2.5 jQueryJSONP跨域

概述:jQueryJSONP進行了封裝,jsonCallback就是傳進去的函數名字

 

獲取某個伺服器的JSON數據:

$.ajax({
   url:"http://127.0.0.88/fun_info.txt",
   dataType:"jsonp",
   jsonpCallback:"fun", //函數名
   success:function(data){
       console.log(data)
   }
})

 

獲取京東評論的數據:

$.ajax({
   url:"https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=598283&scor
e=1&sortType=5&page=0&pageSize=10",
   dataType:"jsonp",
   jsonpCallback:"fetchJSON_comment98",
   success:function(data){
       console.log(data)
   }
})

jQuery跨域的時候,url中的callback後面是函數的名稱,也可以自己修改函數名。

如果urlcallback後面是?號,不用寫jsonpCallback回調函數,jQuery會隨機的命名函數。

$.ajax({
  url:"https://sclub.jd.com/comment/
productPageComments.action?callback=?&productId=598283&score=1&sortType=5&page=0&pageSize=10",
  dataType:"jsonp",
  success:function(data){
      console.log(data)
  }
})

下麵就是jQuery隨機的函數名。

 


2.6三級聯動

<body>
    <select id="province"></select>
    <select id="city"></select>
    <select id="area"></select>
</body>
<script type="text/javascript" src="js/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
    $.get("data/city.txt",function(data){
        //轉JSON對象
        var dataObj = JSON.parse(data);
        //迴圈所有數據,讓省份上樹
        $.each(dataObj.all, function(key,value){
            // console.log(key,value);
            var $option = $("<option>"+ value.name +"</option>");
            $("#province").append($option);
        });

        //當省的數據發送變化時,執行以下方法
        var cityArr = [];
        $("#province").on("change", function(){
            //拿到當前選擇的省的名字
            var pro = $("#province option:selected").text();

            //遍歷省,得到市
            $.each(dataObj.all, function(item,val){
                if(val.name == pro){
                    for(var i = 0; i < val.city.length;i++){
                        $("<option>" + val.city[i].name + "</option>").appendTo('#city');
                    }
                    cityArr.push(val.city)

                    //遍歷得到區
                    $.each(val.city[0].area, function(index,val){
                        $("<option>" + val + "</option>").appendTo('#area');
                    })
                }

            })
        })

        //當市改變時觸發,改變區‘
        $("#city").on("change", function(){
            $("#area").empty(); //清空內容
            //獲取當前被選中的城市名字
            var city = $("#city option:selected").text();

            for(var i = 0; i < cityArr[0].length;i++){
                if(cityArr[0][i].name == city){
                    $.each(cityArr[0][i].area, function(index, val){
                        $("<option>" + val + "</option>").appendTo('#area');
                    })
                }
            }
        })

        //頁面載入初始化城市數據
        $("#province").triggerHandler('change');
    })
</script>

三、效果

3.1載入完畢顯示-原生的套路

<style type="text/css">
    div{
        width: 300px;
        height: 300px;
        background: url('./images/loading.gif') no-repeat;
    }
    img{display: none;}
</style>
<body>
    <div>
        <img src="./images/19.png" >
    </div>
</body>
<script type="text/javascript">
     var img = document.getElementsByTagName('img')[0];
     //當圖片載入完畢後,顯示
     img.onload = function(){
        img.style.display = 'block';
     }
</script>

3.2載入完畢顯示-jquery的套路

Image是系統當中內置的構造函數,因此可以直接使用,返回的是一個img元素對象;

<body>
    <div id="box"></div>
</body>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
    // var img = document.createElement('img');
    var img = new Image();
    img.src = "./images/18.png";

    //載入完畢上樹
    $(img).load(function(){
        $(this).appendTo($('#box'));
    })
</script>

四、聊天室

聊天室製作思路:

用戶點擊登錄把輸入的用戶名傳給Login.php,Login.php接收後正則驗證用戶名是否合法,如果不合法給前端返回一個-1,exit返回
前端接收到返回是-1就提醒用戶重新輸入,如果合法就開啟會話session_start(),並且存儲用戶名,$_SESSION[name]=$name;且返回一個1給前端,
前端收到是1就登錄成功,跳轉到聊天頁面(有中文記得聲明utf-8編碼),再開啟會話,讀取用戶名,判斷用戶按下回車時,將用戶名和輸入內容寫進資料庫,
資料庫再開會話接受數據,連接資料庫,插入數據,執行這條數據$result=mysql_query($sql);如果他是真就返回1,否則返回-1,
聊天頁面請求里的函數接受到時1就把輸入框清空,起初有滾動條且捲動值是自己的高,開一個定時器,清空聊天框的內容,向資料庫get請求JSON數據,資料庫連接,
讀取數據表且排序(記得聲明JSON)執行這個表,聲明一個數組,他有一個最大的鍵,迴圈拿去數據表中的項,存在一個變數,將這個變數push到我們聲明的數據最大的鍵里,
它的值就是一個數組,在pint_r輸出,記得把這個數組轉成JSON,聊天頁面接收返回值它最大的鍵再存一個變數,迴圈這個變數,並且打點取數據上樹,定時器間隔請求。

 

概述:HTTP超文本傳輸協議,屬於短輪詢鏈接,發起一次請求與一次響應之後就斷開鏈接

PHP session 變數用於存儲有關用戶會話的信息,或更改用戶會話的設置。Session 變數保存的信息是單一用戶的,並且可供應用程式中的所有頁面使用。

http://www.w3school.com.cn/php/php_sessions.asp

提示:session PHP有,JS也有,它是一個後臺給前端用戶發的一個‘信物’,可以分辨出誰是誰;

 

Session 的使用:

Session 不同於cookie,必須先啟動Session_start();

當第一次訪問網站的時候,Session_start()函數就會創建一個唯一的Session_ID。並自動通過HTTP的響應頭,將這個Session_ID保存到客戶端的coookie,同時,也在伺服器端創建了一個以Session_ID命名的文件,用於保存。

這個用戶的會話信息。當同一個用戶再次訪問這個網站的時候,也會自動的通過HTTP的請求頭將cookie中保存的session_ID再次的攜帶過來,這時,Session_start()函數就不會再次的分配一個新的Session_ID,而是在伺服器端的硬碟中去尋找個這個Session_ID同名的Session文件,將這之前的偽這個用戶保存的會話信息讀出來。在當前的腳本中應用,達到跟蹤用戶的目的。

 

提示:PHP中的正則方法preg_match(正則字元串,字元串)返回一個布爾值,exitPHPreturn語句。

免費API介面

https://www.zhihu.com/question/32225726

https://www.showapi.com/apiShow/apiMap

 


五、複習

5.1基本類型和引用類型

JavaScript語言有:語言核心、DOMBOM,複習語言核心部分。

JavaScript的數據類型有哪些:
    ● 基本類型值:number、string、boolean、undefined、null
    ● 引用類型值:Object、Array、Function、RegExp、Math、Date

為什麼要區分基本類型和引用類型?有以下兩點不一樣:

區分的方式是根據記憶體中存儲的位置而區分。

基本類型:在記憶體中占用的空間是固定大小的,它們的值保存在棧記憶體,通過值來訪問。

引用類型:大小不固定,棧記憶體中存放它們的地址指向的是堆記憶體中的對象,是按引用訪問。


5.2棧記憶體和堆記憶體

棧(stack)會自動的分配空間,會自動的釋放空間。

堆(heap)會動態的分配記憶體空間,大小不固定,也不會自動釋放空間。

電腦中存儲的媒介:

硬碟:文檔、音樂、視頻、文檔等(電腦斷電後,數據還保留),存儲空間【240G500G1T2T

記憶體:存儲的介質,讀取和寫入速度比硬碟快(電腦斷電後數據就沒了)。存儲空間【2G4G8G

CPU緩存(cache):是位於CPU與記憶體之間的臨時存儲器,電腦斷電後數據也沒了,存儲空間【256KB2M4M8M】。

 

記憶體有五大空間:堆、棧、自由存儲空間、全局、常量

區別1:基本類型在記憶體中都是“棧記憶體”存儲,引用類型值都是“堆記憶體”存儲。

先說說什麼是記憶體?

 

電腦的記憶體能存多少東西?

電腦系統有位數:32位、64

64位舉例:記憶體條一條內容有64位的2進位的值,就是8bytes

記憶體條4G空間等於 4 * 1024 * 1024 * 1024bytes,也等於4 * 1024 * 1024 * 1024 ÷ 8個位元組。536870912

記憶體條8G空間等於 8 * 1024 * 1024 * 1024bytes,也等於8 * 1024 * 1024 * 1024 ÷ 8個位元組。1073741824

 

記憶體中存儲的信息都有對應的地址。

 

基本類型值,都是記憶體中的一個小單元格中,字元串如果太長,此時會用“鏈表”的形式去規劃記憶體,此時就會認為在一個地址中。

什麼是“棧”,類似光碟架的結構、或羽毛球筒。先放進去的,一定是最後被取出來的,進出都在一端,屬於“first in last out”【FILO】

 

 

記憶體條叫做做“棧記憶體”,本質原因就是記憶體會維持一個“空白區域”的清單:

 

現在根據上圖,如果程式員要var a=1;此時這個1被寫入到45533地址上,因為目前它是棧頂,45533就“出棧”。

var b=2;此時b被寫入在45534上,因為此時的棧頂是45533,就“出棧”。

此時寫var a =“哈哈”,此時a被釋放,45533重新回到棧頂,被改寫為“哈哈”的時候,此時再次出棧。等於45533的小單元格從1變為“哈哈”。

 

引用類型值,此時記憶體處理辦法是堆記憶體:

 var arr=[1,2,3,"J","Q","小王"];

 

此時稱為堆記憶體。

區別2:基本類型在進行賦值的時候,此時會在記憶體中克隆一份;引用類型,只傳地址。

 

 var arr=[1,2,3,"J","Q","小王"];

 var b = a;

 

a的更改也會影響b

註意:基本類型在當執行環境結束時被銷毀,而引用類型不會隨著執行環境結束而銷毀,只有當所有引用它的變數不存在時,這個對象才被垃圾回收機制回收。

 


 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原理:通過動態生成canvas然後轉為base64格式 代碼Demo export const waterMark = (text) = { let _wm = document.createElement('canvas') _wm.setAttribute('width',150) _wm.se ...
  • 工作的越久,有些基礎知識我們可能就逐漸淡忘了,今天我們來回顧一下css的聖杯佈局和雙飛翼佈局, 這兩個名詞你可能不熟, 那三欄佈局你肯定就非常熟悉了, 就是兩邊定寬, 中間自適應 的 佈局 1 , 聖杯佈局 首先HTML結構是這樣的,因為要保證中間的結構先渲染, 所以 center 要放在 最前面 ...
  • 下麵是五個正則合到一起的一個正則表達式 this.options.formData[8].value = value.replace(/[^\d.]/g, '').replace(/\.{2,}/g, '.').replace('.', '$#$').replace(/\./g, '').repla ...
  • 1.標簽選擇器 div{} 2.類選擇器 .one class="one" 3.id選擇器(定義+調用) #one{} id="one" 4.通配符選擇器 *{} 5.後代選擇器 .one a {} 6.子代選擇器 .one>a{} 7.交集選擇器 p.one {} 8.並集選擇器 .one,.tw ...
  • 1.變數 var num=10; var num1,num2,num3; num1=10; num2=20; num3=30; var num1=10,num2=20,num3=30; 註意點: console.log(a); //報錯 var b; console.log(b); //undefi ...
  • table 表頭有時候需要加一些小樣式比如 必填項 這是我項目中遇到的需求 比例,產品, 部門為必填項,這個時候就需要在表頭加個紅色小星星。 首先在table中綁定:header-cell-class-name="must"事件 然後methods中寫must事件如下 must(obj) { if ...
  • 瀏覽器F5刷新的時候有一個刷新執行之前的事件,beforeunload 事件,這個事件可以提示用戶在刷新頁面之前有一個提示。 下麵是beforeunload的用法: 首先在methods中定義beforeunload事件 beforeunloadHandler(e) { // e.preventDe ...
  • 最近看了 "Dan Abramov" 的一些 "博客" ,學到了一些React的一些有趣的知識。決定結合自己的理解總結下。這些內容可能對你實際開發並沒有什麼幫助,不過這可以讓你瞭解到更多React底層實現的內容以及為什麼要怎樣實現。可以讓你跟別人有更多的談資,當然,也可以在某些場合裝一下逼。那麼接下 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...