python分词_Python 结巴分词实现关键词抽取分析

1 简介

关键词抽取就是从文本里面把跟这篇文档意义最相关的一些词抽取出来。这个可以追溯到文献检索初期,当时还不支持全文搜索的时候,关键词就可以作为搜索这篇论文的词语。因此,目前依然可以在论文中看到关键词这一项。

除了这些,关键词还可以在文本聚类、分类、自动摘要等领域中有着重要的作用。比如在聚类时将关键词相似的几篇文档看成一个团簇,可以大大提高聚类算法的收敛速度;从某天所有的新闻中提取出这些新闻的关键词,就可以大致了解那天发生了什么事情;或者将某段时间内几个人的微博拼成一篇长文本,然后抽取关键词就可以知道他们主要在讨论什么话题。

总之,关键词就是最能够反映出文本主题或者意思的词语。但是网络上写文章的人不会像写论文那样告诉你本文的关键词是什么,这个时候就需要利用计算机自动抽取出关键词,算法的好坏直接决定了后续步骤的效果。

关键词抽取从方法来说大致有两种:

第一种是关键词分配,就是有一个给定的关键词库,然后新来一篇文档,从词库里面找出几个词语作为这篇文档的关键词;

第二种是关键词抽取,就是新来一篇文档,从文档中抽取一些词语作为这篇文档的关键词;

目前大多数领域无关的关键词抽取算法(领域无关算法的意思就是无论什么主题或者领域的文本都可以抽取关键词的算法)和它对应的库都是基于后者的。从逻辑上说,后者比前着在实际使用中更有意义。

从算法的角度来看,关键词抽取算法主要有两类:

有监督学习算法,将关键词抽取过程视为二分类问题,先抽取出候选词,然后对于每个候选词划定标签,要么是关键词,要么不是关键词,然后训练关键词抽取分类器。当新来一篇文档时,抽取出所有的候选词,然后利用训练好的关键词抽取分类器,对各个候选词进行分类,最终将标签为关键词的候选词作为关键词;

无监督学习算法,先抽取出候选词,然后对各个候选词进行打分,然后输出topK个分值最高的候选词作为关键词。根据打分的策略不同,有不同的算法,例如TF-IDF,TextRank等算法;

jieba分词系统中实现了两种关键词抽取算法,分别是基于TF-IDF关键词抽取算法和基于TextRank关键词抽取算法,两类算法均是无监督学习的算法,下面将会通过实例讲解介绍如何使用jieba分词的关键词抽取接口以及通过源码讲解其实现的原理。

2 示例

下面将会依次介绍利用jieba分词系统中的TF-IDF及TextRank接口抽取关键词的过程。

2.1 基于TF-IDF算法进行关键词抽取

基于TF-IDF算法进行关键词抽取的示例代码如下所示,

from jieba import analyse

# 引入TF-IDF关键词抽取接口

tfidf = analyse.extract_tags

# 原始文本

text = "线程是程序执行时的最小单位,它是进程的一个执行流,\

是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,\

线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。\

线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。\

同样多线程也可以实现并发操作,每个请求分配一个线程来处理。"

# 基于TF-IDF算法进行关键词抽取

keywords = tfidf(text)

print "keywords by tfidf:"

# 输出抽取出的关键词

for keyword in keywords:

print keyword + "/",

控制台输出,

keywords by tfidf:

线程/ CPU/ 进程/ 调度/ 多线程/ 程序执行/ 每个/ 执行/ 堆栈/ 局部变量/ 单位/ 并发/ 分派/ 一个/ 共享/ 请求/ 最小/ 可以/ 允许/ 分配/

2.2 基于TextRank算法进行关键词抽取

基于TextRank算法进行关键词抽取的示例代码如下所示,

from jieba import analyse

# 引入TextRank关键词抽取接口

textrank = analyse.textrank

# 原始文本

text = "线程是程序执行时的最小单位,它是进程的一个执行流,\

是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,\

线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。\

线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。\

同样多线程也可以实现并发操作,每个请求分配一个线程来处理。"

print "\nkeywords by textrank:"

# 基于TextRank算法进行关键词抽取

keywords = textrank(text)

# 输出抽取出的关键词

for keyword in keywords:

print keyword + "/",

控制台输出,

keywords by textrank:

线程/ 进程/ 调度/ 单位/ 操作/ 请求/ 分配/ 允许/ 基本/ 共享/ 并发/ 堆栈/ 独立/ 执行/ 分派/ 组成/ 资源/ 实现/ 运行/ 处理/

3 理论分析

下面将会依次分析TF-IDF算法及TextRank算法的原理。

3.1 TF-IDF算法分析

在信息检索理论中,TF-IDF是Term Frequency - Inverse Document Frequency的简写。TF-IDF是一种数值统计,用于反映一个词对于语料中某篇文档的重要性。在信息检索和文本挖掘领域,它经常用于因子加权。

TF-IDF的主要思想就是:如果某个词在一篇文档中出现的频率高,也即TF高;并且在语料库中其他文档中很少出现,即DF的低,也即IDF高,则认为这个词具有很好的类别区分能力。

TF-IDF在实际中主要是将二者相乘,也即TF * IDF,TF为词频(Term Frequency),表示词t在文档d中出现的频率;IDF为反文档频率(Inverse Document Frequency),表示语料库中包含词t的文档的数目的倒数。

TF公式:

TF计算公式为,

20171021110215651.png?201792111232式中,

count(t)表示文档di中包含词t的个数;

count(di)表示文档di的词的总数;

IDF公式:

IDF计算公式为,

20171021110305366.png?201792111318式中,

num(corpus)表示语料库corpus中文档的总数;

num(t)表示语料库corpus中包含t的文档的数目;

应用到关键词抽取:

1. 预处理,首先进行分词和词性标注,将满足指定词性的词作为候选词;

2. 分别计算每个词的TF-IDF值;

3. 根据每个词的TF-IDF值降序排列,并输出指定个数的词汇作为可能的关键词;

3.2 TextRank算法分析

类似于PageRank的思想,将文本中的语法单元视作图中的节点,如果两个语法单元存在一定语法关系(例如共现),则这两个语法单元在图中就会有一条边相互连接,通过一定的迭代次数,最终不同的节点会有不同的权重,权重高的语法单元可以作为关键词。

节点的权重不仅依赖于它的入度结点,还依赖于这些入度结点的权重,入度结点越多,入度结点的权重越大,说明这个结点的权重越高;

TextRank迭代计算公式为,

WS(Vi)=(1−d)+d∗∑Vj∈In(Vi)wji∑Vk∈Out(Vj)wjk∗WS(Vj)

节点i的权重取决于节点i的邻居节点中i-j这条边的权重 / j的所有出度的边的权重 * 节点j的权重,将这些邻居节点计算的权重相加,再乘上一定的阻尼系数,就是节点i的权重;

阻尼系数 d 一般取0.85;

算法通用流程:

1. 标识文本单元,并将其作为顶点加入到图中;

2. 标识文本单元之间的关系,使用这些关系作为图中顶点之间的边,边可以是有向或者无向,加权或者无权;

3. 基于上述公式,迭代直至收敛;

4. 按照顶点的分数降序排列;

本模型使用co-occurrence关系,如果两个顶点相应的语义单元共同出现在一个窗口中(窗口大小从2-10不等),那么就连接这两个顶点;

添加顶点到图中时,需要考虑语法过滤,例如只保留特定词性(如形容词和名词)的词;

应用到关键短语抽取:

1. 预处理,首先进行分词和词性标注,将单个word作为结点添加到图中;

2. 设置语法过滤器,将通过语法过滤器的词汇添加到图中;出现在一个窗口中的词汇之间相互形成一条边;

3. 基于上述公式,迭代直至收敛;一般迭代20-30次,迭代阈值设置为0.0001;

4. 根据顶点的分数降序排列,并输出指定个数的词汇作为可能的关键词;

5. 后处理,如果两个词汇在文本中前后连接,那么就将这两个词汇连接在一起,作为关键短语;

4 源码分析

jieba分词的关键词抽取功能,是在jieba/analyse目录下实现的。

其中,__init__.py主要用于封装jieba分词的关键词抽取接口;

tfidf.py实现了基于TF-IDF算法抽取关键词;

textrank.py实现了基于TextRank算法抽取关键词;

4.1 TF-IDF算法抽取关键词源码分析

基于TF-IDF算法抽取关键词的主调函数是TFIDF.extract_tags函数,主要是在jieba/analyse/tfidf.py中实现。

其中TFIDF是为TF-IDF算法抽取关键词所定义的类。类在初始化时,默认加载了分词函数tokenizer = jieba.dt、词性标注函数postokenizer = jieba.posseg.dt、停用词stop_words = self.STOP_WORDS.copy()、idf词典idf_loader = IDFLoader(idf_path or DEFAULT_IDF)等,并获取idf词典及idf中值(如果某个词没有出现在idf词典中,则将idf中值作为这个词的idf值)。

def __init__(self, idf_path=None):

# 加载

self.tokenizer = jieba.dt

self.postokenizer = jieba.posseg.dt

self.stop_words = self.STOP_WORDS.copy()

self.idf_loader = IDFLoader(idf_path or DEFAULT_IDF)

self.idf_freq, self.median_idf = self.idf_loader.get_idf()

然后开始通过TF-IDF算法进行关键词抽取。

首先根据是否传入了词性限制集合,来决定是调用词性标注接口还是调用分词接口。例如,词性限制集合为["ns", "n", "vn", "v", "nr"],表示只能从词性为地名、名词、动名词、动词、人名这些词性的词中抽取关键词。

1) 如果传入了词性限制集合,首先调用词性标注接口,对输入句子进行词性标注,得到分词及对应的词性;依次遍历分词结果,如果该词的词性不在词性限制集合中,则跳过;如果词的长度小于2,或者词为停用词,则跳过;最后将满足条件的词添加到词频词典中,出现的次数加1;然后遍历词频词典,根据idf词典得到每个词的idf值,并除以词频词典中的次数总和,得到每个词的tf * idf值;如果设置了权重标志位,则根据tf-idf值对词频词典中的词进行降序排序,然后输出topK个词作为关键词;

2) 如果没有传入词性限制集合,首先调用分词接口,对输入句子进行分词,得到分词;依次遍历分词结果,如果词的长度小于2,或者词为停用词,则跳过;最后将满足条件的词添加到词频词典中,出现的次数加1;然后遍历词频词典,根据idf词典得到每个词的idf值,并除以词频词典中的次数总和,得到每个词的tf * idf值;如果设置了权重标志位,则根据tf-idf值对词频词典中的词进行降序排序,然后输出topK个词作为关键词;

def extract_tags(self, sentence, topK=20, withWeight=False, allowPOS=(), withFlag=False):

# 传入了词性限制集合

if allowPOS:

allowPOS = frozenset(allowPOS)

# 调用词性标注接口

words = self.postokenizer.cut(sentence)

# 没有传入词性限制集合

else:

# 调用分词接口

words = self.tokenizer.cut(sentence)

freq = {}

for w in words:

if allowPOS:

if w.flag not in allowPOS:

continue

elif not withFlag:

w = w.word

wc = w.word if allowPOS and withFlag else w

# 判断词的长度是否小于2,或者词是否为停用词

if len(wc.strip()) < 2 or wc.lower() in self.stop_words:

continue

# 将其添加到词频词典中,次数加1

freq[w] = freq.get(w, 0.0) + 1.0

# 统计词频词典中的总次数

total = sum(freq.values())

for k in freq:

kw = k.word if allowPOS and withFlag else k

# 计算每个词的tf-idf值

freq[k] *= self.idf_freq.get(kw, self.median_idf) / total

# 根据tf-idf值进行排序

if withWeight:

tags = sorted(freq.items(), key=itemgetter(1), reverse=True)

else:

tags = sorted(freq, key=freq.__getitem__, reverse=True)

# 输出topK个词作为关键词

if topK:

return tags[:topK]

else:

return tags

4.2 TextRank算法抽取关键词源码分析

基于TextRank算法抽取关键词的主调函数是TextRank.textrank函数,主要是在jieba/analyse/textrank.py中实现。

其中,TextRank是为TextRank算法抽取关键词所定义的类。类在初始化时,默认加载了分词函数和词性标注函数tokenizer = postokenizer = jieba.posseg.dt、停用词表stop_words = self.STOP_WORDS.copy()、词性过滤集合pos_filt = frozenset(('ns', 'n', 'vn', 'v')),窗口span = 5,(("ns", "n", "vn", "v"))表示词性为地名、名词、动名词、动词。

首先定义一个无向有权图,然后对句子进行分词;依次遍历分词结果,如果某个词i满足过滤条件(词性在词性过滤集合中,并且词的长度大于等于2,并且词不是停用词),然后将这个词之后窗口范围内的词j(这些词也需要满足过滤条件),将它们两两(词i和词j)作为key,出现的次数作为value,添加到共现词典中;

然后,依次遍历共现词典,将词典中的每个元素,key = (词i,词j),value = 词i和词j出现的次数,其中词i,词j作为一条边起始点和终止点,共现的次数作为边的权重,添加到之前定义的无向有权图中。

然后对这个无向有权图进行迭代运算textrank算法,最终经过若干次迭代后,算法收敛,每个词都对应一个指标值;

如果设置了权重标志位,则根据指标值值对无向有权图中的词进行降序排序,最后输出topK个词作为关键词;

def textrank(self, sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'), withFlag=False):

self.pos_filt = frozenset(allowPOS)

# 定义无向有权图

g = UndirectWeightedGraph()

# 定义共现词典

cm = defaultdict(int)

# 分词

words = tuple(self.tokenizer.cut(sentence))

# 依次遍历每个词

for i, wp in enumerate(words):

# 词i 满足过滤条件

if self.pairfilter(wp):

# 依次遍历词i 之后窗口范围内的词

for j in xrange(i + 1, i + self.span):

# 词j 不能超出整个句子

if j >= len(words):

break

# 词j不满足过滤条件,则跳过

if not self.pairfilter(words[j]):

continue

# 将词i和词j作为key,出现的次数作为value,添加到共现词典中

if allowPOS and withFlag:

cm[(wp, words[j])] += 1

else:

cm[(wp.word, words[j].word)] += 1

# 依次遍历共现词典的每个元素,将词i,词j作为一条边起始点和终止点,共现的次数作为边的权重

for terms, w in cm.items():

g.addEdge(terms[0], terms[1], w)

# 运行textrank算法

nodes_rank = g.rank()

# 根据指标值进行排序

if withWeight:

tags = sorted(nodes_rank.items(), key=itemgetter(1), reverse=True)

else:

tags = sorted(nodes_rank, key=nodes_rank.__getitem__, reverse=True)

# 输出topK个词作为关键词

if topK:

return tags[:topK]

else:

return tags

其中,无向有权图的的定义及实现是在UndirectWeightedGraph类中实现的。根据UndirectWeightedGraph类的初始化函数__init__,我们可以发现,所谓的无向有权图就是一个词典,词典的key是后续要添加的词,词典的value,则是一个由(起始点,终止点,边的权重)构成的三元组所组成的列表,表示以这个词作为起始点的所有的边。

无向有权图添加边的操作是在addEdge函数中完成的,因为是无向图,所以我们需要依次将start作为起始点,end作为终止点,然后再将start作为终止点,end作为起始点,这两条边的权重是相同的。

def addEdge(self, start, end, weight):

# use a tuple (start, end, weight) instead of a Edge object

self.graph[start].append((start, end, weight))

self.graph[end].append((end, start, weight))

执行textrank算法迭代是在rank函数中完成的。

首先对每个结点赋予相同的权重,以及计算出该结点的所有出度的次数之和;

然后迭代若干次,以确保得到稳定的结果;

在每一次迭代中,依次遍历每个结点;对于结点n,首先根据无向有权图得到结点n的所有入度结点(对于无向有权图,入度结点与出度结点是相同的,都是与结点n相连的结点),在前面我们已经计算出这个入度结点的所有出度的次数,而它对于结点n的权值的贡献等于它本身的权值 乘以 它与结点n的共现次数 / 这个结点的所有出度的次数 ,将各个入度结点得到的权值相加,再乘以一定的阻尼系数,即可得到结点n的权值;

迭代完成后,对权值进行归一化,并返回各个结点及其对应的权值。

def rank(self):

ws = defaultdict(float)

outSum = defaultdict(float)

wsdef = 1.0 / (len(self.graph) or 1.0)

# 初始化各个结点的权值

# 统计各个结点的出度的次数之和

for n, out in self.graph.items():

ws[n] = wsdef

outSum[n] = sum((e[2] for e in out), 0.0)

# this line for build stable iteration

sorted_keys = sorted(self.graph.keys())

# 遍历若干次

for x in xrange(10): # 10 iters

# 遍历各个结点

for n in sorted_keys:

s = 0

# 遍历结点的入度结点

for e in self.graph[n]:

# 将这些入度结点贡献后的权值相加

# 贡献率 = 入度结点与结点n的共现次数 / 入度结点的所有出度的次数

s += e[2] / outSum[e[1]] * ws[e[1]]

# 更新结点n的权值

ws[n] = (1 - self.d) + self.d * s

(min_rank, max_rank) = (sys.float_info[0], sys.float_info[3])

# 获取权值的最大值和最小值

for w in itervalues(ws):

if w < min_rank:

min_rank = w

if w > max_rank:

max_rank = w

# 对权值进行归一化

for n, w in ws.items():

# to unify the weights, don't *100.

ws[n] = (w - min_rank / 10.0) / (max_rank - min_rank / 10.0)

return ws

4.3 使用自定义停用词集合

jieba分词中基于TF-IDF算法抽取关键词以及基于TextRank算法抽取关键词均需要利用停用词对候选词进行过滤。实现TF-IDF算法抽取关键词的类TFIDF和实现TextRank算法抽取关键词的类TextRank都是类KeywordExtractor的子类。而在类KeywordExtractor,实现了一个方法,可以根据用户指定的路径,加载用户提供的停用词集合。

类KeywordExtractor是在jieba/analyse/tfidf.py中实现。

类KeywordExtractor首先提供了一个默认的名为STOP_WORDS的停用词集合。

然后,类KeywordExtractor实现了一个方法set_stop_words,可以根据用户指定的路径,加载用户提供的停用词集合。

可以将extra_dict/stop_words.txt拷贝出来,并在文件末尾两行分别加入“一个”和“每个”这两个词,作为用户提供的停用词文件,使用用户提供的停用词集合进行关键词抽取的实例代码如下,

from jieba import analyse

# 引入TF-IDF关键词抽取接口

tfidf = analyse.extract_tags

# 使用自定义停用词集合

analyse.set_stop_words("stop_words.txt")

# 原始文本

text = "线程是程序执行时的最小单位,它是进程的一个执行流,\

是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,\

线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。\

线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。\

同样多线程也可以实现并发操作,每个请求分配一个线程来处理。"

# 基于TF-IDF算法进行关键词抽取

keywords = tfidf(text)

print "keywords by tfidf:"

# 输出抽取出的关键词

for keyword in keywords:

print keyword + "/",

关键词结果为,

keywords by tfidf:

线程/ CPU/ 进程/ 调度/ 多线程/ 程序执行/ 执行/ 堆栈/ 局部变量/ 单位/ 并发/ 分派/ 共享/ 请求/ 最小/ 可以/ 允许/ 分配/ 多个/ 运行/

对比章节2.1中的关键词抽取结果,可以发现“一个”和“每个”这两个词没有抽取出来。

keywords by tfidf:

线程/ CPU/ 进程/ 调度/ 多线程/ 程序执行/ 每个/ 执行/ 堆栈/ 局部变量/ 单位/ 并发/ 分派/ 一个/ 共享/ 请求/ 最小/ 可以/ 允许/ 分配/

实现原理 ,这里仍然以基于TF-IDF算法抽取关键词为例。

前面已经介绍了,jieba/analyse/__init__.py主要用于封装jieba分词的关键词抽取接口,在__init__.py首先将类TFIDF实例化为对象default_tfidf,而类TFIDF在初始化时会设置停用词表,我们知道类TFIDF是类KeywordExtractor的子类,而类KeywordExtractor中提供了一个名为STOP_WORDS的停用词集合,因此类TFIDF在初始化时先将类KeywordExtractor中的STOP_WORDS拷贝过来,作为自己的停用词集合stop_words。

# 实例化TFIDF类

default_tfidf = TFIDF()

# 实例化TextRank类

default_textrank = TextRank()

extract_tags = tfidf = default_tfidf.extract_tags

set_idf_path = default_tfidf.set_idf_path

textrank = default_textrank.extract_tags

# 用户设置停用词集合接口

def set_stop_words(stop_words_path):

# 更新对象default_tfidf中的停用词集合

default_tfidf.set_stop_words(stop_words_path)

# 更新对象default_textrank中的停用词集合

default_textrank.set_stop_words(stop_words_path)

如果用户需要使用自己提供的停用词集合,则需要调用analyse.set_stop_words(stop_words_path)这个函数,set_stop_words函数是在类KeywordExtractor实现的。set_stop_words函数执行时,会更新对象default_tfidf中的停用词集合stop_words,当set_stop_words函数执行完毕时,stop_words也就是更新后的停用词集合。我们可以做个实验,验证在调用analyse.set_stop_words(stop_words_path)函数前后,停用词集合是否发生改变。

from jieba import analyse

import copy

# 将STOP_WORDS集合深度拷贝出来

stopwords0 = copy.deepcopy(analyse.default_tfidf.STOP_WORDS)

# 设置用户自定停用词集合之前,将停用词集合深度拷贝出来

stopwords1 = copy.deepcopy(analyse.default_tfidf.stop_words)

print stopwords0 == stopwords1

print stopwords1 - stopwords0

# 设置用户自定停用词集合

analyse.set_stop_words("stop_words.txt")

# 设置用户自定停用词集合之后,将停用词集合深度拷贝出来

stopwords2 = copy.deepcopy(analyse.default_tfidf.stop_words)

print stopwords1 == stopwords2

print stopwords2 - stopwords1

结果如下所示,

True

set([])

False

set([u'\u6bcf\u4e2a', u'\u8207', u'\u4e86', u'\u4e00\u500b', u'\u800c', u'\u4ed6\u5011', u'\u6216', u'\u7684', u'\u4e00\u4e2a', u'\u662f', u'\u5c31', u'\u4f60\u5011', u'\u5979\u5011', u'\u6c92\u6709', u'\u57fa\u672c', u'\u59b3\u5011', u'\u53ca', u'\u548c', u'\u8457', u'\u6211\u5011', u'\u662f\u5426', u'\u90fd'])

说明:

没有加载用户提供的停用词集合之前,停用词集合就是类KeywordExtractor中的STOP_WORDS拷贝过来的;

加载用户提供的停用词集合之后,停用词集合在原有的基础上进行了扩;

证明了我们的想法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis 如何 mysql_Redis 如何保持和 MySQL 数据一致

一、需求起因在高并发的业务场景下&#xff0c;数据库大多数情况都是用户并发访问最薄弱的环节。所以&#xff0c;就需要使用redis做一个缓冲操作&#xff0c;让请求先访问到redis&#xff0c;而不是直接访问MySQL等数据库。这个业务场景&#xff0c;主要是解决读数据从Redis缓…

iframe 跨域_【梯云纵】搞定前端跨域

韦陀掌法,难陀时间善恶&#xff1b;梯云纵,难纵过乱世纷扰。现在开始写代码o(╯□╰)o什么是跨域1.跨域的定义广义的跨域是指一个域下对的文档或者脚本试图去请求另外一个域下的资源。a链接、重定向、表单提交、、、等标签background:url()、font-face()ajax 跨域请求……狭义的…

java中exception_Java中的异常 Exceptions

1. 概念exception是“exceptional event”的缩写&#xff0c;是指执行程序中发生的事件&#xff0c;破坏了程序的正常执行流程。Java 异常处理机制使程序更加健壮易于调试&#xff0c;它可以告诉程序员三个问题&#xff1a;错误的类型、位置、原因&#xff0c;帮助程序员解决错…

python异步asy_Python 异步编程之asyncio【转载】

一、协程的认识 协程&#xff08;Coroutine&#xff09;&#xff0c;也可以被称为微线程&#xff0c;是一种用户态内的上下文切换技术。 简而言之&#xff0c;其实就是通过一个线程实现代码块相互切换执行。例如&#xff1a;deffunc1():print(1) ...print(2)deffunc2():print(3…

bitcount java_Java源码解释之Integer.bitCount

Java中的Integer.bitCount(i)的返回值是i的二进制表示中1的个数。源码如下&#xff1a;public static int bitCount(int i) {// HD, Figure 5-2i i - ((i >>> 1) & 0x55555555);i (i & 0x33333333) ((i >>> 2) & 0x33333333);i (i (i >&…

git merge 冲突_卧槽!小姐姐用动画图解 Git 命令,这也太秀了吧?!

公众号关注 “GitHubDaily”设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01;大家好&#xff0c;我是小 G。在座的各位应该都知道&#xff0c;Git 作为居家必备、团队协作之利器&#xff0c;自从 Linus Torvalds 发布这款工具后&#xff0c;便一直受到各路开发者的喜爱…

android 删除文件 代码_代码审计之某系统后台存在任意删除文件

本文作者&#xff1a;霾团队交流群&#xff1a;673441920-----------------------------------------------------------前言POC镇楼&#xff01;&#xff01;&#xff01;POST 漏洞演示过程&#xff1a;首先我们利用D盾监听下我们的项目以外的目录。这里刚刚我们创建了这个文件…

ubuntu java8 java9_在Ubuntu/Debian系统上安装Java 9的方法

本文介绍在Ubuntu/Debian系统上安装Oracle Java 9的方法&#xff1a;使用webupd8team/java PPA&#xff0c;相同的PPA提供了Java 8和Java 7等旧版Java的软件包&#xff0c;如果你的应用程序需要这个&#xff0c;可以随意安装它们。要安装新版本可参考在Ubuntu 18.04系统上安装J…

websocket 压力测试_打造最强移动测试平台

笔者今年换掉了服役N年的旧手机&#xff0c;新手机12G的RAM&#xff0c;比自用的本子内存都大&#xff0c;如果只是玩游戏感觉不能完全发挥出全部机能&#xff0c;但又因为怕影响日常使用没有进行root&#xff0c;经过一番折腾&#xff0c;发现即使不root也不影响把它变成一款测…

python银行系统模拟演练_python多线程实现代码(模拟银行服务操作流程)

1.模拟银行服务完成程序代码目前&#xff0c;在以银行营业大厅为代表的窗口行业中大量使用排队(叫号)系统&#xff0c;该系统完全模拟了人群排队全过程&#xff0c;通过取票进队、排队等待、叫号服务等功能&#xff0c;代替了人们站队的辛苦。排队叫号软件的具体操作流程为&…

字符串左侧补0_(48)C++面试之最长不含重复字符的子字符串(动态规划)

// 面试题48&#xff1a;最长不含重复字符的子字符串// 题目&#xff1a;请从字符串中找出一个最长的不包含重复字符的子字符串&#xff0c;计算该最长子// 字符串的长度。假设字符串中只包含从a到z的字符。#include <vector> #include <string> #include <iost…

java udp 同一个端口实现收发_Java网络编程之UDP协议

伙伴们注意了&#xff01;小编在这里给大家送上关注福利&#xff1a;搜索微信公众号“速学Java”关注即可领取小编精心准备的资料一份&#xff01;今天我们来聊聊网络编程这部分的内容网络编程1)计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0…

java 多态_Java面向对象 —— 多态

前两天已经相继介绍了Java面向对象的三大特性之中的封装、继承&#xff0c;所以今天就介绍Java面向对象的三大特性的最后一项&#xff0c;多态~首先讲一下什么是多态&#xff0c;以及多态需要注意的细节 什么是多态&#xff1a;一个对象具备多种形态&#xff0c;也可以理解为事…

vb6 方法‘ ’作用于对象 失败_JS基础入门-对象的使用

今日背诵小纸条对象是一组属性方法的组合&#xff0c;其中可包含基本值、对象和函数对象的定义1 对象字面量var hero{name: ‘产品小姐姐’&#xff0c;age: 16&#xff0c;weapon: [ ‘头盔’, ‘靴子’, ‘盔甲 ]&#xff0c;sayHi: function ( ) {console.log( this.name ’…

无法从套接字读取更多的数据 oracle_小伙面试时被追问数据库优化,面试前如何埋点反杀?

前言周五的早高峰, 各地软件园地铁站里中出现了不少穿着长袖加绒格子衫, 背双肩电脑包的年轻码农, 现在节气正值 [ 小雪 ] , 11月的全国性突然降温 , 让经历过996摧残的猿们一出地铁站就冻的打了个激灵 , 很庆幸的告诉大家距离放年假还剩不到 37 个工作日, 要买火车票的赶紧预约…

qlineedit限制输入数字_Excel单元格限制录入,实用小技巧

在填写资料表格的时候&#xff0c;为了不防止出错&#xff0c;会在单元格中设置一些技巧&#xff0c;限制对方输入内容&#xff0c;这样可以更好的预防输入错误。那么单元格限制输入技巧是如何实现的呢&#xff1f;1、限制只能录入数字比如单元格是我们要用来填写年龄数据等数字…

java二维数组 内存分配_java中二维数组内存分配

区分三种初始化方式&#xff1a;格式一&#xff1a;数据类型[][] 数组名 new 数据类型[m][n];m:表示这个二维数组有多少个一维数组。n:表示每一个一维数组的元素有多少个。//例&#xff1a;int arr[][]new int[3][2];如下图格式二&#xff1a;数据类型[][] 数组名 new 数据类…

word公式插件_如何快速输入复杂的数学公式?这里有 3 个实用技巧

不管你是不是科研狗&#xff0c;都可能遇到过在文章中插入公式。而我们最常用的就是使用 Word 自带的公式编辑器输入&#xff0c;Word 公式可以很好地匹配文章的格式&#xff0c;自然地插入文中。有时候处理一个公式简单&#xff0c;但如果你要输入大量公式&#xff0c;键盘、鼠…

java观察者模式本质_6.[研磨设计模式笔记]观察者模式

1.定义定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并自动更新。2.解决问题——订阅报纸看起来订阅者是直接根有据打交道&#xff0c;但实际上&#xff0c;订阅者的订阅数据是被邮寄传递到报社&#xff0…

粒子群算法tsp java_粒子群算法解决TSP问题

1. 粒子群算法简介粒子群算法(particle swarm optimization&#xff0c;PSO)由Kennedy和Eberhart在1995年提出&#xff0c;属于进化算法的一种&#xff0c;是通过对模拟鸟群扑食行为设计的。基本思想&#xff1a;从随机解出发&#xff0c;通过迭代寻找最优解&#xff0c;通过适…