天天看點

惡意短信與僞基站資料可視化畢業設計

1、前言

很近沒有認真寫文章了,都是遇到一些問題簡單記錄一下才

被迫

發表部落格,這次準備把之前做的幾套可視化分析大屏系統總結并分享出來,但暫時不開源(因為都是一些畢業設計,有這畢業設計方面的需求可以聯系我

86377220

,其中包括了論文以及各種資料)。

這次介紹的系統主題是

基于惡意短信的可視分析系統

,資料來源是ChinaVIS 2017年挑戰賽一,資料背景如下介紹:

以上是這次系統設計的基調和背景,圍繞這一背景,利用所學知識,将官方所給的資料轉換為互動式的可視化圖形,在系統運作過程中發現資料之間的聯系以及找到題目所要求答案。這是我大學期間的畢業設計,基于此設計所拽寫的畢業論文也被評為優秀論文,有需要的可私聊。

後面會對為什麼選擇這個主題作為畢業設計,開發中遇到的困難,系統采用到的技術重難點分析,通過系統發現的規律,以及論文的一些寫作技巧(相同的語句如何降低重複率)進行說明。

先來一張系統效果圖,有個概念:

惡意短信與僞基站資料可視化畢業設計
惡意短信與僞基站資料可視化畢業設計

總共分為兩個大的子產品,一個是全部垃圾短信的宏觀分布規律,另外一個是分類垃圾短信的分布規律。這兩個界面完成了題目所要求85%的答案,如果17年能有這個水準參加可視化大賽,估計也能拿個

優秀獎

(每年的參賽隊伍将近100支,獲獎比例才30%左右,含金量可謂是比較重了,2020年參加的疫情可視化很幸運的拿到了優秀獎,後期會對這套系統進行介紹)吧?

2、選題背景

廢話不多說,直接奔向正題!

為什麼會選擇這個主題作為畢業論文呢?回答這個問題之前,還得把大學的經曆先簡單的介紹一番,我學的是電子類專業,就業方向走軟體類也可以走硬體類方向,對電路懵逼的我毫不猶豫的選擇了軟體,然後在衆多語言中稀裡糊塗的選擇了前端(别問為什麼,問就是不知道!(╹▽╹))。

想必大家在大學期間可能都參加過很多比賽,也完成過很多的項目,

大學生創新創業訓練計劃項目

應該都聽說過吧,含金量雖然沒多重,但能很好的鍛煉的自己的動手和學習能力,更重要的是,學校會撥經費下來作為對項目的孵化,這樣大學期間不就省了很大一筆學習資料費嗎?(插播一句,有想了解

大學生創新創業訓練計劃項目

的,歡迎騷擾!兩次國家級立項和一次校級立項的經驗足以幫助你從衆多申請項目中脫穎而出)。

也就是通過參加比賽,選擇了前端,然後碰到一個很好的指導老師(可視化方向的),就一直跟着她從事可視化分析,然後帶領學生團隊參加各類比賽。也就是說選

資料可視化

作為畢業設計方向已經有了将近三年的基礎。

那為什麼會選擇ChinaVIS作為資料來源和選題呢?起初從指導老師那裡得知這個領域含金量比較重的比賽包括ChinaVIS和阿裡的天池大資料競賽等,因為老師對ChinaVIS比較了解,是以就沒有選擇其他的參賽平台。

2019年參加了第一次ChinaVIS,四個人組成一個團隊,什麼都不會,連簡單的HTML文法都不知道,一群懵懂的小白就此開啟了填坑之路。因為比賽隻有兩個月時間,結果可想而知,做出了一堆自己都不想去看的亂七八糟圖形。還天天呆在辦公室,基本上沒有休息時間,到最後,連自己都不想去看這個代碼了,就團隊的每個人都很煩躁,因為失去了方向,做出來的東西和預想的天壤之别。

然後接下來的一年,就開始學各類技術,但2020年疫情爆發了,本以為組委會不會舉辦今年的比賽,後面又開放了開放式選題,疫情可視化,分析疫情對我國社會所産生的影響。然後皇天不負有心人,獲得了優秀獎,但參賽隊伍90%以上都是研究所學生隊伍,是以取得這個成績還是很滿意。

完成項目後,就基本上确定了畢業論文選題的方向,資料來源從以往ChinaVIS中選,最後發現僞基站和垃圾短信資料比較貼近現實,做起來比較有意義,一拍即合,就這樣完成了自己的選題之路!(PS:很多學校都是老師給課題,然後學生從這幾個課題裡面去選,因為論文指導老師和之前的指導老師都是同一個,就自己選然後告訴她就行,這樣就可以做自己想要做的事情)。後面項目組的學弟根據這套系統和論文也申請了

大學生創新創業訓練計劃項目

,不出意外的又獲得了國家級立項,連續三年,同一個指導老師和項目組,都是國家級項目,這在學校中的二級學院裡面還是第一次!

3、環境依賴

1、Node.js(前端Vue和後端node都依賴該環境)

2、開發工具:Git,vscode,Hbuilder,pycharm

3、開發語言:Python,HTML+CSS+JavaScript

4、重點依賴庫:echarts,bootstrap,jQuery

4、可視化分析

以下可視化分析直接從複制來源于本人的畢業論文。

本次垃圾短信的記錄數大約有330萬條,時間跨度為63天,平均每天的垃圾短信為5萬2千條,但受到節假日和兩會召開的影響,每天的分布顯得極不均勻。如圖4.1所示,不同日期的垃圾短信資料有大于25萬條的,也有将近1萬條的記錄。根據平均值計算,當天垃圾短信大于5萬條且小于10萬條的則可以推斷出較為活躍;數量大于10萬條的則為非常活躍。但受到外部因素的影響,3月6号到15号的兩會召開期間不活躍,4月2号到5号受假期影響也表現為不活躍,假期恢複之後則迅速回到平均活躍水準。

惡意短信與僞基站資料可視化畢業設計

​ 圖4.1 不同日期垃圾短信活躍趨勢圖

在圖4.2中,将垃圾短信按照每小時進行統計,可以看出從早6點開始,一直持續到晚9點,是每天垃圾短信分布最為密集的時間段。而從晚9點到次日早六點期間,垃圾短信的數量分布非常少。再結合4.3的a、b、c三幅極坐标柱形圖也可以分析出垃圾短信的時間段基本上和上述分析的一緻。

惡意短信與僞基站資料可視化畢業設計
圖4.2 垃圾短信頻繁分布時間段圖           
惡意短信與僞基站資料可視化畢業設計

​ 圖4.3 極坐标圖

利用多圖互動式可視化的方法将時間次元和空間次元進行結合分析,有利于探索更加深層次的隐蔽資訊。如圖4.4互動式圖形所示,點選折線圖可以更新地圖和極坐标柱形圖的資料,地圖顯示目前日期的垃圾短信分布位置資料,極坐标顯示目前日期不同時間段的垃圾短信數量;然後再次點選極坐标柱形圖,可以得到如圖4.5所示的每小時垃圾短信分布圖。圖4.5的四幅小圖分别展示的是10、13、17和22時的資料,經過對比,可以發現基本上所有的垃圾短信都集中分布在北京四環以内,并且主要分布在朝陽區和東城區兩個位置。從時間上對比,白天其他地方的垃圾短信相對較多,但到了晚上,垃圾短信幾乎值分布在市區東部,其他地方基本為0。

惡意短信與僞基站資料可視化畢業設計

​ 圖4.4 多元互動式圖形

惡意短信與僞基站資料可視化畢業設計

​ 圖4.5 每小時垃圾短信分布

可視分析大概就分析這兩個點,篇幅寫太多了也不好!

5、部分代碼分析

5.1 、後端代碼

之前對Java後端開發并不是很熟悉,而且是在畢業設計期間,又外出實習,就更沒有時間用Java來寫了。是以采用JavaScript文法的node.js作為後端,記得剛開始入門node的時候,完全不知道怎麼實作,網上看了很多的資料,非常的零散,連最基本的demo都沒有搭建出來,找了半天模闆,也沒用直接可以使用的,小白完成很懵逼!

然後經過幾天的探索,根據零散的資料一步一步完成了《Node後端模闆代碼(附源碼)》,根據這套代碼,可以直接拿來開發使用,更多詳細的點可以通過博文進行學習。當然,這是一套很基本的模闆代碼,隻是實作了整個流程的最基本點,适合剛入門node的人作為參考!

其實後端的做的事情并不多,僅僅相當于一個前端和資料庫連接配接的一個橋梁,基本上所有的資料處理都放在了前端完成,這導緻目前系統運作起來有一點點的卡,後續打算用Java去實作,并将資料處理部分都放到後端,前端隻做資料的渲染。

這裡簡單對後端的模闆代碼進行分析:

  • 封裝處理請求和和SQL查詢以及響應的模闆代碼,有了這個模闆代碼,後端寫的就非常非常簡單了,基本上兩三行代碼就是一個接口,不過後面經過驗證,友善是友善,但是擴充性不高,隻能做一些簡單的查詢,如果後端想進行資料處理,就有點麻煩了。
    /*
     * @Description  : 封裝操作資料庫的代碼,因為一些代碼高度相似,其他檔案要使用這些子產品的時候,直接用require導入即可
     */
    
    // 導入url子產品
    var url = require('url');
    // 導入mysql子產品 
    var mysql = require('mysql');
    // 導入資料庫配置資訊
    var dbconfig = require('@/config/DBConfig');
    // 使用DBConfig.js的配置資訊建立一個MySQL連接配接池。
    var pool = mysql.createPool(dbconfig.mysql);
    var logger = require('log4js').getLogger("index");
    
    /**
     * 封裝對資料庫的增删改查代碼,傳回的結果code為0表示失敗,為1表示成功
     * @param {*} res 伺服器的響應,也就是伺服器把查詢到的資料傳回給前端
     * @param {String} sql SQL語句
     * @param {String} querySuccessMsg 操作資料庫成功時的提示資訊
     * @param {String} queryErrMsg 操作資料庫失敗時的提示資訊
     * @returns {*} 失敗就直接傳回,成功就傳回資料
     */
    var baseApi = function (res, sql, querySuccessMsg, queryErrMsg) {
        // 對傳入的各類資訊進行比較,當沒有傳入的時候,就預設為'',防止出現出錯
        var querySuccessMsg_ = querySuccessMsg || '';
        var queryErrMsg_ = queryErrMsg || '';
    
        pool.getConnection(function (err, connection) {
            /**
             * 這個錯誤是資料庫連接配接時抛出的錯誤,比如MySQL服務未開啟、主機錯誤、密碼錯誤、端口錯誤、資料庫不存在等等,
             * 如果連接配接的時候出錯了,就會傳回錯誤的資訊,最好寫上,到時候可以排查錯誤
             * 如果出現錯誤,那麼err這個回調函數就不為null,如果連接配接正常,就為null
             */
            if (err !== null) {
                logger.error({
                    code: 0,
                    err: err,
                    msg: "資料庫連接配接錯誤!請檢查資料庫服務是否開啟、使用者名和密碼是否正确、主機位址和端口是否正确、資料庫存不存在!"
                });
                res.send({
                    code: 0,
                    err: err,
                    msg: "資料庫連接配接錯誤!請檢查資料庫服務是否開啟、使用者名和密碼是否正确、主機位址和端口是否正确、資料庫存不存在!"
                });
                return;
            }
    
            // 執行資料庫操作語句
            connection.query(sql, function (err, results) {
                /**
                 * 這個錯誤是執行MySQL語句時可能會出現的錯誤,和上面的道理一樣,還是要寫上,友善檢查錯誤
                 */
                logger.info(sql)
                if (err !== null) {
                    logger.error(err)
                    res.send({
                        code: 0,
                        err: err,
                        msg: "請檢查SQL語句是否正确!"
                    });
                    return;
                }
    
                if (results != [] && results != "") {
                    logger.info('查詢成功')
                    res.send({
                        code: 1,
                        data:  results,
                        msg: querySuccessMsg_
                    });
                } else {
                    logger.error({
                        code: 0,
                        data: {
                            results: results,
                            err: err
                        },
                        msg: queryErrMsg_
                    })
                    res.send({
                        code: 0,
                        data: {
                            results: results,
                            err: err
                        },
                        msg: queryErrMsg_
                    })
                }
            });
            connection.release(); //釋放這個連接配接池
        })
    };
    
    module.exports = {
        baseApi
    };           
  • 關于這套node模闆代碼還有其他的知識點,可以移步到《Node後端模闆代碼(附源碼)》進行檢視,有更加詳細的子產品說明和使用。

5.2、前端代碼

前端用了Vue架構,但沒有用到Vue的精華,隻是比較膚淺的使用了Vue。這套系統也稍微算有一點點大,元件之間的通信很頻繁,但居然沒有使用Vue的狀态過濾器vuex;其二,在前面介紹重點依賴庫的時候可以發現,用到了jQuery,Vue最核心的部分是雙向資料綁定,資料變化就會自動重新渲染視圖,不需要我們自己去操縱DOM節點,但很遺憾,這套系統中絕大多數都是用jQuery在操縱DOM,這也使得本就卡的系統更加卡了。

當然,這也是之前不懂事,以為自己會使用了,結果是剛剛入門都還差點意思。後續也有可能對前端代碼進行優化,盡可能的提升系統響應速度和渲染速度。

既然都寫了,那也不怕拿出來丢醜了!

  • AJAX;前後端互動技術,基于jQuery的Ajax,并對其進一步進行封裝,至于好壞,自行把握,我覺得用起來還是比較舒服的。
    /*
     * @Description  : 封裝請求的代碼,不需要每次請求都時候都寫上一長串的代碼,直接調用這個函數就可以了
     */
    
    /**
     * @param {*} url 發送請求的位址
     * @param {*} type 請求方式("POST" 或 "GET"), 預設為 "GET"
     * @param {*} data 發送到伺服器的資料,數組存儲,如:{"date": new Date().getTime(), "state": 1}
     * @param {*} async 預設值: true。預設設定下,所有請求均為異步請求。如果需要發送同步請求,請将此選項設定為 false。注意,同步請求将鎖住浏覽器,使用者其它操作必須等待請求完成才可以執行。
     * @param {*} dataType 預期伺服器傳回的資料類型,常用的如:xml、html、json、text
     * 
     * @returns 傳回一個異步對象promise,這個對象有兩個狀态,分别為成功和失敗,用法如下:
     *          //------------先聲明一個變量來接收這個函數的傳回值------------------
     *          var promise = ajax(url, type, data, async, dataType);
     *          //------------如果失敗的話,就會進入fail裡面,執行失敗的代碼---------
     *          promise.fail(function (jqXHR, textStatus, err) {
                    console.log("錯誤碼"+jqXHR.status+":"+err)
                });
                //------------如果成功的話,就會執行done代碼,res會傳回的結果---------
                promise.done(function (res) {
                    console.log(res)
                    });
     */
    
    function ajax(url, type, data, async, dataType) {
      var baseURL = process.env.VUE_APP_BASE_API;
      var url_ = baseURL + url;
      async = (async==null || async=="" || typeof(async)=="undefined")? "true" : async;
      type = (type==null || type=="" || typeof(type)=="undefined")? "get" : type;
      dataType = (dataType==null || dataType=="" || typeof(dataType)=="undefined")? "json" : dataType;
      data = (data==null || data=="" || typeof(data)=="undefined")? '' : data;
      var promise = $.ajax({
          type: type,
          async: async,
          data: data,
          url: url_,
          dataType: dataType,
          error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.error("ERROR - URLManager.ajax() - Unable to retrieve URL: " + url_ + ", [" + XMLHttpRequest.status + "]" + errorThrown);
        }
      });
      return promise;
    };
    
    export default ajax           
  • 封裝栅格;自适應的栅格,基于bootstrap,不需要每次去化邊框了,直接調用這個Vue元件,然後傳入寬高就可以實作代碼複用。
    <!--
     * @Description  : 邊框元件,把邊框封裝成一個元件,要用邊框的時候直接調用這個元件就可以了,不需要每次都寫邊框
    -->
    <template>
    <div class="card border-0 p-0" :class="getBorderStyle()">
        <div class="main_left fl">
            <!--左上邊框-->
            <div class="t_line_box">
                <i class="t_l_line"></i>
                <i class="l_t_line"></i>
            </div>
            <!--右上邊框-->
            <div class="t_line_box">
                <i class="t_r_line"></i>
                <i class="r_t_line"></i>
            </div>
            <!--左下邊框-->
            <div class="t_line_box">
                <i class="l_b_line"></i>
                <i class="b_l_line"></i>
            </div>
            <!--右下邊框-->
            <div class="t_line_box">
                <i class="r_b_line"></i>
                <i class="b_r_line"></i>
            </div>
            <!-- <div class="main_title">
                <i class="fa" :class="getTitleIcon()"></i>
                {{title}}
            </div> -->
            <!-- slot vue中的插槽,意思是預留一個位置,到時候父元件調用的時候就可以顯示在這個位置了 -->
            <slot></slot>
        </div>
    </div>
    </template>
    
    <script>
    export default {
        name: 'border',
        props: {
            item: String,
            // title: String, //标題文字
            titleIcon: String //标題圖示的屬性值
        },
        methods: {
            /**
             * 标題圖示的屬性
             */
            getTitleIcon() {
                return setBorderStyle(this.titleIcon)
            },
            /**
             * 邊框的屬性
             */
            getBorderStyle() {
                return setBorderStyle(this.item)
            }
        },
    }
    
    function setBorderStyle(param) {
        if (param !== undefined) {
            var itemArr = (param).split(' ');
            var style = [];
            for (let i = 0; i < itemArr.length; i++) {
                style.push(eval("(" + "{'" + itemArr[i] + "': true}" + ")"));
            }
            return style
        } else {
            return;
        }
    }
    </script>
    
    <style>
    @import '../../assets/css/bootstrap_plugins.css';
    
    [class*="col"] {
        padding: 0px !important;
    }
    
    .main_left {
        background: url('../../assets/img/background.png') no-repeat;
        background-size: 110% 110%;
        box-sizing: border-box;
        border: 2px solid rgba(100, 75, 245, 0.8);
        position: relative;
        box-shadow: 0 0 10px rgba(100, 75, 245, 0.8);
    }
    
    .fl {
        float: left;
    }
    
    .main_title {
        width: 180px;
        height: 35px;
        line-height: 33px;
        background-color: #2C58A6;
        border-radius: 18px;
        position: absolute;
        top: -17px;
        left: 50%;
        margin-left: -90px;
        color: #fff;
        font-size: 18px;
        font-weight: 600;
        box-sizing: border-box;
        padding-left: 45px;
        z-index: 1000;
    }
    
    .main_title i {
        position: absolute;
        top: 8px;
        left: 10px;
    }
    
    .l_t_line {
        width: 3px;
        height: 40px;
        left: -3px;
        top: -3px;
    }
    
    .t_l_line {
        height: 3px;
        width: 120px;
        left: -3px;
        top: -3px;
    }
    
    .t_line_box {
        position: absolute;
        width: 100%;
        height: 100%;
    }
    
    .t_line_box i {
        background-color: rgb(3, 245, 213);
        box-shadow: 0px 0px 10px rgb(3, 245, 213);
        position: absolute;
    }
    
    .t_r_line {
        height: 3px;
        width: 26px;
        right: -3px;
        top: -3px;
    }
    
    .r_t_line {
        width: 3px;
        height: 24px;
        right: -3px;
        top: -3px;
    }
    
    .l_b_line {
        width: 3px;
        height: 24px;
        left: -3px;
        bottom: -3px;
    }
    
    .b_l_line {
        height: 3px;
        width: 26px;
        left: -3px;
        bottom: -3px;
    }
    
    .r_b_line {
        width: 3px;
        height: 40px;
        right: -3px;
        bottom: -3px;
    }
    
    .b_r_line {
        height: 3px;
        width: 120px;
        right: -3px;
        bottom: -3px;
    }
    </style>
               

上面幾段代碼是比較常用和核心點的子產品,其他的代碼就不一一列舉了,有需要的歡迎騷擾。

6、開發中遇到的困難

一個人把整套系統開發出來還是需要蠻長的時間,因為項目組有很多的新人,為了鍛煉他們,就分子產品的交給他們實作,雖然一些圖形達到了要求,但是代碼品質來說還是需要提高,前期主要是邊和他們說明代碼的問題,另一方面又自己改善他們的代碼,并根據他們的思路,引入最恰當的圖形,然後再送出到git上面去。

困難遇到的不算很多,因為沒有繼續用很新的技術,為了保守起見,先完成系統設計再說,很多的坑都是踩過了,遇到問題也能很快的解決。真正遇到瓶頸的是算法方面,這才是整套系統中遇到最大的難題,前面也提到隻完成了85%左右,因為還有一部分是這邊做動态路徑實時預覽跟蹤僞基站的移動規律,但這部分的資料如何從原始資料中提取出來,轉換成什麼格式,都不是很清楚,即使到最後完成了一點點demo,但也沒有達到預期,就砍掉了這部分。這需要算法去計算僞基站的移動路線經緯度,還需要和地圖上的道路經緯度想比對,才可以直覺的展示在圖形上,這部分因為時間和難度,完完全全就放棄了。

預期想做出類似的效果如下圖所示,這是當年其他參賽選手完成的圖形。

惡意短信與僞基站資料可視化畢業設計

對于大多數工科類的學生來說,畢業設計可能問題不是很大,真正的困難可能是系統完成後如何去寫畢業論文,如果降低重複率。一些人畢業設計唰唰唰幾下子就完成了,并且也實作的很好,但是在寫論文上面卻拖了很久,因為平常沒有訓練過,不知道如何下筆,思考半個小時都不知道如何寫起,最後實在迫不得已把别人文章裡面的段落複制過來,自己去改。但又發現,别人寫的實在是太好了,都不知道如何改起,隻能稍微改幾個字或者詞,這樣基本上是不能通過論文查重的。

之前有看過如果降低别人文章句子的重複率,如何根據這種方法,即使是同一個意思,所組成的字詞都不一樣,重複率自然而然就降低了,很幸運第一次查重就在2%以下(這裡不是自誇哈,隻是想分享一下如何掌握寫作的技巧,降低重複率)。

7、畢業論文降重寫作技巧

關于上述所說的如何降低論文的重複率,下面以自身寫論文的經驗進行分享一下。其中這套系統的畢業論文,知網第一次查重1.7%;另外還寫了一篇基于JavaEE的智能人事管理系統(OA辦公系統)畢業論文,維普第一次查重6.5%左右。

怎麼寫的才能使得重複率這麼低呢?首先,我覺得工科類的論文最好寫了,尤其是有畢業設計做支撐的,基本上很難超過學校的查重率标準線。相反,個人覺得如果寫金融等文科類的畢業論文,是比較難寫的。

為什麼這麼說呢,因為論文裡面有一個大的子產品,是系統設計與實作,光這一塊,就可以寫上全部論文的三分之一篇章了,自己按照系統的每一個功能子產品截圖,然後說明其使用方法以及達到的效果,然後把資料庫設計以及資料表以表格的形式插入到文章中,那些套話部分就差不多隻剩一半的篇幅了。

惡意短信與僞基站資料可視化畢業設計

重點不是介紹如何寫系統設計與實作這部分,因為這部分如果系統是自己做的,然後按照自己的思路闡述,必要時還可以貼上代碼,完成不需要這部分的查重率不會過。重點要講的是如何降低

選題背景,國内外研究現狀以及研究意義

等套話部分,這部分的内容必須要借鑒參考文獻,但是看論文是一件極其枯燥的事情,不可能把碩士論文全部看完一遍,然後提取一個中心思想寫在這裡,這對大部分的大學生來說還是有一點困難的,都是讀了一段往了一段,基本上記不住講的是什麼。有人說可以通過摘要來提取核心思想啊,但都不看論文,光摘要能了解透嗎。

一個投機取巧的辦法是在選取文獻的時候,可以先選擇幾篇品質較好的文章(為了區分,稱為A),然後通過A文章的國内外研究現狀部分引入的文獻,把這些适合自己論文主題的文獻都收集下來,再去知網收集下載下傳具體看某篇文章,根據這些人總結的核心思想,在自己閱讀完論文的前提下去改造語句,先按照自己對文章和語句的了解,對A文章中總結的核心思想按照自己想表達的意思轉化出來,估計大部分都會覺得語句不通順,可以嘗試着使用

有道翻譯

,先把中文翻譯成英文,然後把翻譯好的英文再翻譯為中文,可以發現,很多地方雖然是一個意思,但是使用到的字不一樣了,這也是降低重複率的嚴重方法。

好了,如何降低論文寫作的重複率寫分享這兩個方法,第一是參考别人寫好的核心思想,第二是有道翻譯。後期有需要的話可以分享更多降重小技巧。

對了,有很多人喜歡查重之前去淘寶或者其他的管道買查重的機會,無非就是兩種可能,一是查重率很高,然後不斷的修改;二是查重率低于學校要求标準線,以為自己沒事了,可等學校一查,涼涼!這些是不可信的,因為他們用的查重軟體和學校用的不一樣,論文資料庫也不一緻,根本沒有參考左右,相反,如果寫的比較好的文章,還非常有可能被别人竊取,然後賣出去,等自己再查論文的時候,發現全篇都是抄的,這就很尴尬。

8、結語

繼續閱讀