利用机器学习进行恶意代码分类-冠军队方法分析

2023-10-30

本文转自https://bindog.github.io/blog/2015/08/20/microsoft-malware-classification/
原作者:宾狗

1. 前言

最近在Kaggle上微软发起了一个恶意代码分类的比赛,并提供了超过500G的数据(解压后)。有意思的是,取得第一名的队伍三个人都不是搞安全出身的,所采用的方法与我们常见的方法存在很大不同,展现了机器学习在安全领域的巨大潜力。在仔细读完他们的代码和相关的论文后,我简单的进行了一些总结与大家分享。

需要指出的是,(1)比赛的主题是恶意代码的分类,不是病毒查杀(2)比赛采用的方法是纯静态分析的方法,不涉及行为分析等动态分析方法。

因此这不意味着这个方法能够取代现有的方法,但是了解它能够为安全研究人员提供一个崭新的思路,至于能否在工业界应用仍待进一步研究。

2. 总览

2.1. 背景

80年代末期,随着恶意代码的诞生,反恶意代码软件(或称反病毒软件)随之诞生。这个时期的恶意代码所采用的技术较为简单,这使得对应的检测技术也较为容易,早期的反病毒软件大都单一的采用特征匹配的方法,简单的利用特征串完成检测。随着恶意代码技术的发展,恶意代码开始在传播过程中进行变形以躲避查杀,此时同一个恶意代码的变种数量急剧提升,形态较本体也发生了较大的变化,反病毒软件已经很难提取出一段代码作为恶意代码的特征码。在这种情况下,广谱特征码随之诞生,广谱特征码将特征码进行了分段,通过掩码字节对需要进行比较的和不需要进行比较的区段进行划分。然而无论是特征码扫描还是广谱特征,都需要在获得恶意代码样本后,进行特征的提取,随后才能进行检测,这使得对恶意代码的查杀具有一定的滞后性,始终走在恶意代码的后面。为了针对变种病毒和未知病毒,启发式扫描应运而生,启发式扫描利用已有的经验和知识对未知的二进制代码进行检测,这种技术抓住了恶意代码具有普通二进制文件所不具有的恶意行为,例如非常规读写文件,终结自身,非常规切入零环等等。启发式扫描的重点和难点在于如何对恶意代码的恶意行为特征进行提取。特征码扫描、查找广谱特征、启发式扫描,这三种查杀方式均没有实际运行二进制文件,因此均可归为恶意代码静态检测的方法。随着反恶意代码技术的逐步发展,主动防御技术、云查杀技术已越来越多的被安全厂商使用,但恶意代码静态检测的方法仍是效率最高,被运用最广泛的恶意代码查杀技术。

2.2. 数据格式

微软提供的数据包括训练集、测试集和训练集的标注。其中每个恶意代码样本(去除了PE头)包含两个文件,一个是十六进制表示的.bytes文件,另一个是利用IDA反汇编工具生成的.asm文件。如下图所示
数据格式

2.3. 方法简述

Kaggle比赛中最重要的环节就是特征工程,特征的好坏直接决定了比赛成绩。在这次Kaggle的比赛中冠军队伍选取了三个“黄金”特征:恶意代码图像、OpCode n-gram和Headers个数,其他一些特征包括ByteCode n-gram,指令频数等。机器学习部分采用了随机森林算法,并用到了xgboost和pypy加快训练速度。

本文主要关注恶意代码图像和OpCode n-gram,以及随机森林算法的应用。

3. 恶意代码图像

这个概念最早是2011年由加利福尼亚大学的Nataraj和Karthikeyan在他们的论文 Malware Images: Visualization and Automatic Classification 中提出来的,思路非常新颖,把一个二进制文件以灰度图的形式展现出来,利用图像中的纹理特征对恶意代码进行聚类。此后,有许多研究人员在这个思路基础上进行了改进和探索。就目前发表的文章来看,恶意代码图像的形式并不固定,研究人员可根据实际情况进行调整和创新。

国内这方面的研究较少,去年在通信学报上有一篇《基于纹理指纹的恶意代码变种检测方法研究》,是由北京科技大学的韩晓光博士和北京启明星辰研究院等合作发表的,目测也是仅有的一篇。

本节介绍最简单的一种恶意代码图像绘制方法。对一个二进制文件,每个字节范围在00FF之间,刚好对应灰度图0255(0为黑色,255为白色)。将一个二进制文件转换为一个矩阵(矩阵元素对应文件中的每一个字节,矩阵的大小可根据实际情况进行调整),该矩阵又可以非常方便的转换为一张灰度图。

python代码如下

import numpy
from PIL import Image
import binascii

def getMatrixfrom_bin(filename,width):
    with open(filename, 'rb') as f:
        content = f.read()
    hexst = binascii.hexlify(content)  #将二进制文件转换为十六进制字符串
    fh = numpy.array([int(hexst[i:i+2],16) for i in range(0, len(hexst), 2)])  #按字节分割
    rn = len(fh)/width
    fh = numpy.reshape(fh[:rn*width],(-1,width))  #根据设定的宽度生成矩阵
    fh = numpy.uint8(fh)
    return fh

filename = "your_bin_filename"
im = Image.fromarray(getMatrixfrom_bin(filename,512)) #转换为图像
im.save("your_img_filename.png")

利用该代码生成的几种病毒样本图像如下所示
恶意代码图像
用肉眼可看出,同一个家族的恶意代码图像在纹理上存在一定的相似性,不同的恶意代码家族是有一定区别的。如何用计算机发现和提取这些纹理的相似特征用以分类呢?这就需要用到计算机视觉里的一些技术了。在Nataraj和Karthikeyan的论文中采用的是GIST特征,GIST特征常用于场景分类任务(如城市、森林、公路和海滩等),用一个五维的感知维度来代表一个场景的主要内容(详情请参考文献[xx])。简单来说,输入图像,输出为对应的GIST描述符,如下图所示
gist descriptor
在matlab实现里面每个图像的GIST描述符都用一个向量表示,最后用SVM完成分类训练。

插句题外话,基于深度学习的图像识别技术近几年突猛进,下图截取自Feifei Li老师的TED演讲
深度学习图像识别

这已经远远超出了场景识别所能做的。不过,国外有学者利用一些类似前文生成那种不规则图像来欺骗深度学习模型,如下图所示
欺骗深度学习
详情请参考@王威廉老师的微博。当然,二者并没有什么直接关联,因为基于深度学习的图像识别系统的训练数据是一些有意义的图像。但这是一个非常有意思的巧合,至于基于深度学习的图像识别能否用于恶意代码图像的特征提取和分类,我认为是一个潜在的研究点,所能做的也不局限于此,如果有做深度学习的朋友可以伙同做安全的朋友一起研究交流。

4. OpCode n-gram

n-gram是自然语言处理领域的概念,早期的语音识别技术和统计语言模型与它密不可分。n-gram基于一个简单的假设,即认为一个词出现的概率仅与它之前的n-1个词有关,这个概率可从大量语料中统计得到。例如“吃”的后面出现“苹果”或“披萨”的概率就会比“公路”的概率大(正常的语料中基本不会出现“吃公路”这种组合),可以看出n-gram在一定程度上包含了部分语言特征。

将n-gram应用于恶意代码识别的想法最早由Tony等人在2004年的论文N-gram-based Detection of New Malicious Code 中提出,不过他们的方法是基于ByteCode的。2008年Moskovitch等人的论文Unknown Malcode Detection Using OPCODE Representation 中提出利用OpCode代替ByteCode更加科学。

具体来说,一个二进制文件的OpCode n-gram如下图所示
OpCode n-gram

针对这次Kaggle比赛提供的数据,用python提取出其n-gram特征

import re
from collections import *
# 从.asm文件获取Opcode序列
def getOpcodeSequence(filename):
    opcode_seq = []
    p = re.compile(r'\s([a-fA-F0-9]{2}\s)+\s*([a-z]+)')
    with open(filename) as f:
        for line in f:
            if line.startswith(".text"):
                m = re.findall(p,line)
                if m:
                    opc = m[0][1]
                    if opc != "align":
                        opcode_seq.append(opc)
    return opcode_seq
# 根据Opcode序列,统计对应的n-gram
def getOpcodeNgram(ops ,n = 3):
    opngramlist = [tuple(ops[i:i+n]) for i in range(len(ops)-n)]
    opngram = Counter(opngramlist)
    return opngram

file = "train/0A32eTdBKayjCWhZqDOQ.asm"
ops = getOpcodeSequence(file)
opngram = getOpcodeNgram(ops)
print opngram
# output
# Counter({('mov', 'mov', 'mov'): 164, ('xor', 'test', 'setnle'): 155...

5. 决策树和随机森林

5.1. 决策树

决策树在我们日常生活中无处不在,在众多机器学习的书籍中提到的一个例子(银行预测客户是否有能力偿还贷款)如下图所示
决策树例子
在这个在决策树中,非叶子结点如“拥有房产”、“是否结婚”就是所谓的特征,它们是依靠我们的知识人工提取出来的特征。但如果对某个领域不了解,特征数量又较多时,人工提取特征的方法就不可行了,需要依靠算法来寻找合适的特征构造决策树。

限于篇幅,决策树的构造等过程本文不进行展开,网上相关资源非常多。(只要能够充分理解熵和信息增益的概念,决策树其实非常简单)

5.2. 随机森林

随机森林是一个非常强大的机器学习方法,顾名思义,它是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,预测这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为那一类。

随机森林的思想与Adaboost里面的弱分类器组合成强分类器的思想类似,是一种“集体智慧”的体现。例如,屋子里面有n个人,每个人作出正确判断的概率为p(p略高于0.5,这时每个人可视为一个弱分类器),他们判断的过程独立互不影响,最终以多数人的判断为准。这里我们不从数学上来推导,类比抛硬币,对一枚均匀的硬币,抛n次的结果中,正面和反面的次数是差不多的。而对一枚不均匀的硬币,若出现正面的概率略大于反面,抛n次的结果中出现正面次数比反面次数多的概率就会很大。所以即使每个分类器的准确度不高,但是结合在一起时就可以变成一个强分类器。
随机森林
如图所示,将训练数据有放回的抽样出多个子集(即随机选择矩阵中的行),当然在特征选择上也可以进行随机化(即随机选择矩阵中的列,图中没有体现出来),分别在每个子集上生成对应的决策树
随机森林生成
决策过程如下图所示(忽略画风不一致的问题…)
决策过程

6. 冠军队伍的实现细节

6.1. ASM文件图像

但是在Kaggle比赛中冠军队伍采用的方法并不是从二进制文件生成的图像,也不是从.bytes文件,竟然是从.asm文件生成的图像,他们也没有使用GIST特征,而是使用了前800个像素值作为特征,让人非常费解。

我专门给队伍里的Jiwei Liu同学发了一封邮件进行咨询,他给我的答复是:GIST特征与其他特征综合使用时影响整体效果,所以他们放弃了GIST特征,另外使用.asm文件生成图像纯属意外发现…

至于为什么是前800个像素,他的解释是通过反复交叉验证得出的,具体原因不清楚。(在后文的分析中我会谈谈我的一些看法)

6.2. OpCode n-gram

这部分的实现不复杂,他们选取n=4,在具体的特征选择上通过计算信息增益选取每个分类与其他分类区分度最高的750个特征。

6.3. 其他特征

其他一些特征包括统计Headers,Bytecode n-gram(n=2,3,4),分析指令流(将每个循环固定展开5次)来统计指令频数,这些特征虽然不像前面提到的特征那么有效,但是确实可以在一定程度上提升最终成绩。

7. 实验

冠军队伍的代码是为了参加比赛而写的,时间仓促,又是多人合作完成,导致组织结构很乱,且基本没有注释,可读性较差。更重要的是自己想动手实践一下,所以按照他们的思路写了几个简单的程序,忽略了一些处理起来比较复杂或者难以理解的过程,代码可以在我的github上下载

由于只是做一些简单的试验,不需要太多的数据(否则速度会非常慢),我从微软提供的训练数据中抽取了大概1/10左右的训练子集,其中从每个分类的中都随机抽取了100个样本(9个分类,每个样本2个文件,共1800个文件),这样也不需要用到pypy和xgboost,只需要用到numpy、pandas、PIL和scikit-learn这些库即可

友情提示:要进行这个实验,首先确保有一个比较大的硬盘,推荐使用Linux系统。

7.1. 训练子集

这一步需要提前将完整训练集解压好,数量庞大,时间比较久。

import os
from random import *
import pandas as pd
import shutil

rs = Random()
# 读取微软提供的训练集标注
trainlabels = pd.read_csv('trainLabels.csv')
fids = []
opd = pd.DataFrame()
for clabel in range (1,10):
    # 筛选特定分类
    mids = trainlabels[trainlabels.Class == clabel]
    mids = mids.reset_index(drop=True)
    # 在该分类下随机抽取100个
    rchoice = [rs.randint(0,len(mids)-1) for i in range(100)]
    rids = [mids.loc[i].Id for i in rchoice]
    fids.extend(rids)
    opd = opd.append(mids.loc[rchoice])
    
opd = opd.reset_index(drop=True)
# 生成训练子集标注
opd.to_csv('subtrainLabels.csv', encoding='utf-8', index=False)

# 将训练子集拷贝出来(根据实际情况修改这个路径)
sbase = 'yourpath/train/'
tbase = 'yourpath/subtrain/'
for fid in fids:
    fnames = ['{0}.asm'.format(fid),'{0}.bytes'.format(fid)]
    for fname in fnames:
        cspath = sbase + fname
        ctpath = tbase + fname
        shutil.copy(cspath,ctpath)

7.2. 特征抽取

本实验中只用到了.asm文件,用到了.asm文件图像特征(前1500个像素)和OpCode n-gram特征(本实验取n=3,将总体出现频数大于500次的3-gram作为特征保留),实现代码与前文基本一致,具体细节可参考完整代码。

7.3. scikit-learn

因为scikit-learn的存在,将机器学习算法应用到其他领域变得非常方便快捷。例如我们已经抽取了这些恶意代码的OpCode n-gram特征(“3gramfeature.csv”),利用scikit-learn即可快速训练一个随机森林

from sklearn.ensemble import RandomForestClassifier as RF
from sklearn import cross_validation
from sklearn.metrics import confusion_matrix
import pandas as pd

subtrainLabel = pd.read_csv('subtrainLabels.csv')
subtrainfeature = pd.read_csv("3gramfeature.csv")
subtrain = pd.merge(subtrainLabel,subtrainfeature,on='Id')
labels = subtrain.Class
subtrain.drop(["Class","Id"], axis=1, inplace=True)
subtrain = subtrain.as_matrix()
# 将训练子集划分为训练集和测试集 其中测试集占40%
X_train, X_test, y_train, y_test = cross_validation.train_test_split(subtrain,labels,test_size=0.4)
# 构造随机森林 其中包含500棵决策树
srf = RF(n_estimators=500, n_jobs=-1)
srf.fit(X_train,y_train)  # 训练
print srf.score(X_test,y_test)  # 测试

7.4. 实验结果

这里只对预测的准确度做一个简单的评判。

在只应用.asm文件图像特征(firstrandomforest.py)或者Opcode n-gram特征(secondrandomforest.py)的情况下,以及二者相结合的情况(combine.py),准确率如下所示
结果
由于随机森林训练的过程中存在一定的随机性,因此每次结果不一定完全相同,但总的来说,二者结合的准确率通常要高出许多,基本可以达到98%以上的准确率,而且别忘了我们只用了不到1/10的数据

7.5. 为什么是前800像素

观察.asm文件的格式,开头部分其实是IDA生成的一些信息,如下图所示
IDA info
可以目测这个长度已经超出了800个像素(800个字节),实际上这800个像素和反汇编代码没有关系!完全就是IDA产生的一些信息,更进一步的说,实际上冠军队伍的方法压根与恶意代码图像没有关系,实际上是用到了IDA产生的信息。

但是仔细观察这些IDA信息,貌似长的都差不多,也没有什么有价值的信息,为什么可以有效区分恶意软件类型呢?

一个大胆的猜想是微软提前将这些恶意代码分好类,在调用IDA进行反汇编的时候是按照每个分类的顺序进行的,由于未知的原因可能导致了这些IDA信息在不同分类上有细微差别,恰好能作为一个非常有效的特征!

8. 其他

好的方法总是简单又好理解的。这次Kaggle比赛也是如此,冠军队伍的方法没有特别难理解的部分。但是请注意:面上的方法并不能体现背后难度和工作量,真正复杂和耗时的部分在于特征选择和交叉验证上。比如他们最终放弃GIST特征正是经过反复对比验证才做出的决定。
这次的Kaggle比赛归根结底还是比赛,最终目标是取得最好成绩,不代表这个方法在实际中一定好用。
放弃GIST特征告诉我们一个宝贵的经验,并不是某个特征好就一定要用,还要考虑它和其他特征综合之后的效果。
比赛的数据是去除了PE头的,而输入输出表对分析恶意代码是很有帮助的,假如微软提供的数据包含了PE头,将输入输出表作为特征,最终的结果应该还能进一步提升。
这个方法的能够发现一些静态方法发现不了的变种,但对于未知的新品种依然无能为力(没有数据,机器学习巧妇难为无米之炊…)
可以尝试将该方法应用到Android和IOS平台的恶意代码检测中。

9. 资源和参考资料

9.1. 比赛说明和原始数据

https://www.kaggle.com/c/malware-classification/

9.2. 冠军队伍相关资料

  • Kaggle采访
  • JiWei Liu的视频讲解
  • 代码和PDF

9.3. 本文代码

https://github.com/bindog/ToyMalwareClassification

9.4. 参考资料

  • Malware Images: Visualization and Automatic Classification
  • Detecting unknown malicious code by applying classification techniques on OpCode patterns(墙裂推荐)
  • 如何使用GIST+LIBLINEAR分类器提取CIFAR-10 dataset数据集中图像特征,并用测试数据进行实验
  • GIST特征描述符使用
  • 随机森林算法
  • How Random Forest algorithm works
  • Supervised Classification with k-fold Cross Validation on a Multi Family Malware Dataset

10. Similar Posts

  • 编码的妙用——GCTF2017中The X Sanitizer题解
  • 与前端工程师的较量——Chrome调试工具进阶技巧
  • 安全领域中机器学习的对抗和博弈
  • 利用硬件防御ROP:HA-CFI技术浅析
  • 从SNE到t-SNE再到LargeVis
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用机器学习进行恶意代码分类-冠军队方法分析 的相关文章

  • 如何避免使用 python 处理空的标准输入?

    The sys stdin readline 返回之前等待 EOF 或新行 所以如果我有控制台输入 readline 等待用户输入 相反 我想打印帮助并在没有需要处理的情况下退出并显示错误 而不是等待用户输入 原因 我正在寻找一个Pytho
  • 如何使用 Python 3 绕过 HTTP Error 403: Forbidden with urllib.request

    您好 不是每次都这样 但有时在尝试访问 LSE 代码时 我会收到每一个烦人的 HTTP 错误 403 禁止消息 任何人都知道我如何仅使用标准 python 模块来克服这个问题 遗憾的是没有漂亮的汤 import urllib request
  • 从文本文件中删除特定字符

    我对 Python 和编码都很陌生 我当时正在做一个小项目 但遇到了一个问题 44 1 6 23 2 7 49 2 3 53 2 1 68 1 6 71 2 7 我只需要从每行中删除第三个和第六个字符 或者更具体地说 从整个文件中删除 字符
  • 使用 django-rest-framework 设置对象级权限

    尝试使用 django rest framework 最干净 最规范地管理 django guardian 对象级权限 我想将对象的读取权限 module view object 分配给在执行 POST 时发出请求的用户 我的基于阶级的观点
  • 在python中将数据库表写入文件的最快方法

    我正在尝试从数据库中提取大量数据并将其写入 csv 文件 我正在尝试找出最快的方法来做到这一点 我发现在 fetchall 的结果上运行 writerows 比下面的代码慢 40 with open filename a as f writ
  • 如何过滤 Pandas GroupBy 对象并获取 GroupBy 对象?

    当对 Pandas groupby 操作的结果执行过滤时 它返回一个数据帧 但假设我想执行进一步的分组计算 我必须再次调用 groupby 这似乎有点绕 有更惯用的方法吗 EDIT 为了说明我在说什么 我们无耻地从 Pandas 文档中窃取
  • 协程从未被等待

    我正在使用一个简单的上下文管理器 其中包含一个异步循环 class Runner def init self self loop asyncio get event loop def enter self return self def e
  • Arcpy 模数在 Pycharm 中不显示

    如何将 Arcpy 集成到 Pycharm 中 我尝试通过导入模块但它没有显示 我确实知道该模块仅适用于 2 x python arcpy 在 PyPi Python 包索引 上不可用 因此无法通过 pip 安装 要使用 arcpy 您需要
  • python 中的 <> 运算符有什么作用?

    我刚刚遇到这个here http www feedparser org feedparser py 总是这样使用 if string1 find string2 lt gt 1 pass 什么是 lt gt 运算符这样做 为什么不使用通常的
  • 运行 Python 单元测试,以便成功时不打印任何内容,失败时仅打印 AssertionError()

    我有一个标准单元测试格式的测试模块 class my test unittest TestCase def test 1 self tests def test 2 self tests etc 我的公司有一个专有的测试工具 它将作为命令行
  • 两个不同长度的数据帧的列之间的余弦相似度?

    我在 df1 中有文本列 在 df2 中有文本列 df2 的长度将与 df1 的长度不同 我想计算 df1 text 中每个条目与 df2 text 中每个条目的余弦相似度 并为每场比赛给出分数 输入样本 df1 mahesh suresh
  • 查找 Pandas DF 行中的最短日期并创建新列

    我有一个包含多个日期的表 有些日期将为 NaN 我需要找到最旧的日期 所以一行可能有 DATE MODIFIED WITHDRAWN DATE SOLD DATE STATUS DATE 等 因此 对于每一行 一个或多个字段中都会有一个日期
  • 在骨架图像中查找线 OpenCV python

    我有以下图片 我想找到一些线来进行一些计算 平均长度等 我尝试使用HoughLinesP 但它找不到线 我能怎么做 这是我的代码 sk skeleton mask rows cols sk shape imgOut np zeros row
  • 如何给URL添加变量?

    我正在尝试从网站收集数据 我有一个 Excel 文件 其中包含该网站的所有不同扩展名 F i www example com example2 我有一个脚本可以成功从网站中提取 HTML 但现在我想为所有扩展自动执行此操作 然而 当我说 s
  • rpy2 无法加载外部库

    希望有人能帮忙解决这个问题 R版本 2 14 1rpy2版本 2 2 5蟒蛇版本 2 7 3 一直在尝试在 python 脚本中使用 rpy2 加载 R venneuler 包 该包以 rJava 作为依赖项 venneuler 和 rJa
  • 如何从namedtuple实例列表创建pandas DataFrame(带有索引或多索引)?

    简单的例子 from collections import namedtuple import pandas Price namedtuple Price ticker date price a Price GE 2010 01 01 30
  • 如何使用 python 定位和读取 Data Matrix 代码

    我正在尝试读取微管底部的数据矩阵条形码 我试过libdmtx http libdmtx sourceforge net 它有 python 绑定 当矩阵的点是方形时工作得相当好 但当矩阵的点是圆形时工作得更糟 如下所示 另一个复杂问题是在某
  • IndexError - 具有匀称形状的笛卡尔 PolygonPatch

    我曾经使用 shapely 制作一个圆圈并将其绘制在之前填充的图上 这曾经工作得很好 最近 我收到索引错误 我将代码分解为最简单的操作 但它甚至无法执行最简单的循环 import descartes import shapely geome
  • python从二进制文件中读取16字节长的双精度值

    我找到了蟒蛇struct unpack 读取其他程序生成的二进制数据非常方便 问题 如何阅读16 字节长双精度数出二进制文件 以下 C 代码将 1 01 写入二进制文件三次 分别使用 4 字节浮点型 8 字节双精度型和 16 字节长双精度型
  • 无法安装最新版本的 Numpy (1.22.3)

    我正在尝试安装最新版本的 numpy 即 1 22 3 但看起来 pip 无法找到最后一个版本 我知道我可以从源代码本地安装它 但我想了解为什么我无法使用 pip 安装它 PS 我有最新版本的pip 22 0 4 ERROR Could n

随机推荐

  • ubuntu vi/vim退出文件

    要退出 但是不保存 按esc先 然后输入 q 回车键即可退出 无法退出 则在 q 加入一个叹号回车键就行了 要退出保存的 则输入 wq 强制保存退出 则输入 wq 看到此时已经退出 在等待命令状态 以nano开头编辑文件的 则要退出 按 C
  • SQL Server学习之复合索引

    概要什么是单一索引 什么又是复合索引呢 何时新建复合索引 复合索引又需要注意些什么呢 本篇文章主要是对网上一些讨论的总结 一 概念单一索引是指索引列为一列的情况 即新建索引的语句只实施在一列上 用户可以在多个列上建立索引 这种索引叫做复合索
  • GPT系列模型技术路径演进

    目录 前言 Transformer GPT 1 BERT GPT 2 GPT 3 InstructGPT ChatGPT GPT 4 类ChatGPT产品 Google Bard 诗人 facebook LLaMA 羊驼 复旦 MOSS 清
  • 源码安装ODOO12

    要从源码安装 Odoo 我们首先要从 GitHub 上克隆一套 Odoo 源代码 mkdir home tderp conda envs odoo12 odoo dev 在odoo12虚环境下创建工作目录 cd home tderp con
  • linux怎么打开.o文件,Linux下文件I/O操作的相关知识

    Linux文件I O主要指的是文件的输入输出 很多初学者对文件的I O不是很了解 Linux文件I O的操作较多 下面小编就给大家详细介绍下Linux文件I O linux 文件I O教程 1 一 文件描述符 对内核而言 所以打开的文件都通
  • Android UI架构(十)--App请求切换帧率(1).md

    文章目录 参考资料 前言 背景 查看设备可支持的刷新率和分辨率 App设置设备帧率 Android Q及以下版本 Android R 参考资料 https zhuanlan zhihu com p 142212769 from voters
  • CC00041.bigdatajava——

    一 逻辑运算符概念使用 逻辑运算短路特性 逻辑运算符概念 gt 表示逻辑与运算符 相当于 并且 同真为真 一假为假 gt 表示逻辑或运算符 相当于 或者 一真为真 同假为假 gt 表示逻辑非运算符 相当于 取反 真为假 假为真 gt 逻辑运
  • ES(四)ES使用(基本查询、聚合查询)

    基本操作 操作索引 1 新建索引 curl XPUT localhost 9200 index01 2 查看索引 curl XGET http 192 168 168 101 9200 index01 settings curl XGET
  • Session和Cookie的用法及区别

    Session Cookie是什么 1 1 概念理解 要了解session和cookie是什么 先要了解以下几个概念 1 1 1 无状态的HTTP协议 协议 是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则 超文本传输协
  • 独立服务器和虚拟主机,浅谈独立服务器、云服务器、虚拟主机的区别

    当代的生活离不开网络的使用 不管是电商 游戏 还是视频行业 很多业务都需要依赖网络才得以开展 包括海外市场的推广与后期的联系巩固 真是巨大的市场需求 也使网络根据一些特性与使用衍生出了不同的类型 包括服务器 云服务器 虚拟主机等 那么 小编
  • 解决 k8s 集群1.26.3使用nfs时nfs provider selfLink was empty

    背景 1 使用1 26 3版本的集群 2 搭建nfs服务器 3 使用storageclass创建pvc时 一直pending 4 尝试修改vim etc kubernetes manifests kube apiserver yaml 文件
  • makefile工具的使用,编写一个或多个文件!(简单易上手)

    一 make 和 makefile 是什么 1 make 是一个 命令 2 makefile 是一个 文件 可以自动化的构建项目 3 编写 makefile 需要 1 依赖关系 2 依赖方法 二 什么是依赖关系 什么是依赖方法 下面我简单写
  • JUC学习系列五(ThreadLocal)

    该类提供了线程局部 thread local 变量 这些变量不同于它们的普通对应物 因为访问某个变量 通过其 get 或 set 方法 的每个线程都有自己的局部变量 它独立于变量的初始化副本 ThreadLocal 实例通常是类中的 pri
  • 删除oracle数据库用户

    如果在drop 后还提示ORA 01940 无法删除当前已链接的用户 说明还有连接的session 可以通过查看session的状态来确定该session是否被kill 了 用如下语句查看 select saddr sid serial p
  • selenium官方文档——2.入门

    2 1 简单用法 如果你已经安装了Selenium Python绑定 你可以像这样从Python开始使用它 from selenium import webdriver from selenium webdriver common keys
  • 新闻资讯CMS内容管理系统的设计与实现(一)

    新闻资讯CMS内容管理系统的设计与实现 一 目录 1 项目背景 2 项目规划 3 系统结构图 4 系统架构图 5 系统用例图 6 业务流程图 7 E R图 8 领域模型 9 数据字典 10 DDL建表语句 11 数据流图 1 项目背景 如标
  • 2021-1-9 吴恩达-C5 序列模型-w2 自然语言处理与词嵌(课后编程1-Operations on word vectors 词向量运算-含UnicodeDecodeError解决)

    原文链接 如果打不开 也可以复制链接到https nbviewer jupyter org中打开 自然语言处理与词嵌 Operations on word vectors 词向量运算 1 余弦相似度 2 词语类比任务 3 去除词向量中的偏见
  • 阿里巴巴Easyexcel无法追加写入Csv文件的问题

    版本为当前最新版本3 2 1
  • 【分享帖】LCD的MCU接口和SPI接口详解

    LCD Liquid Crystal Display 液晶屏 作为电子产品的重要组成部分 是终端用户与电子产品交互的重要载体 现在市场上的LCD 按照尺寸 功能 接口 用途等分为很多种 本文主要介绍如下两种LCD物理接口 1 MCU接口 8
  • 利用机器学习进行恶意代码分类-冠军队方法分析

    本文转自https bindog github io blog 2015 08 20 microsoft malware classification 原作者 宾狗 1 前言 最近在Kaggle上微软发起了一个恶意代码分类的比赛 并提供了超