此论文主要是研究RDF图中异常数据的发现,通过定义一个基于图的条件函数依赖关系(GCFD),统一地表示RDF数据的属性值和语义结构依赖关系,然后提出了一个有效的框架和一些新的剪枝规则来发现大型RDF图中的GCFD。文中定义了复合属性、结合属性、结合属性的恒等、结合属性的相等以及图条件函数依赖,通过以上定义的概念和挖掘GCFDs的框架可以用于检测违反规则的异常数据,本文定义的规则跟之前学习的GFD中所定义的图形模式很相似,之前学习的GFD通过将规则抽象为对应的图形模式然后通过图匹配的方式获得满足图形模式的图,本文主要介绍了大概的框架,而具体的CFD发现算法则是引用了别的文章,

1、摘要

关系数据中的许多数据质量问题都得到了研究,如数据一致性、重复数据删除、数据准确性、数据完整性等。本文主要研究RDF图中异常数据的发现。随着RDF数据量的增加,数据质量成为这些RDF存储库可用性的一个重要问题。虽然关联规则已经被用来发现RDF图中的异常,但是现有的解决方案忽略了RDF图中连接结构的潜在语义。为了检测RDF图中潜在的依赖关系,首先,我们创新性地定义了一个基于图的条件函数依赖关系(GCFD),它可以统一地表示RDF数据的属性值和语义结构依赖关系。然后,我们提出了一个有效的框架和一些新的剪枝规则来发现大型RDF图中的GCFD。在几个真实的RDF库中进行的大量实验证实了我们的解决方案的优越性。

2、介绍

近年来,研究人员对数据质量问题给予了极大的关注,因为资源多样、自动转换工具差、错误的数据集成和本体的实际误用都会导致数据质量低下。据报道,美国企业花了数十亿美元来处理脏数据[5]。为了发现关系表中的异常数据,许多算法利用完整性约束来提高数据质量。最有代表性的是关系表中的函数依赖(FD)和条件函数依赖(CFD)。与关系数据不同,RDF采用“图”作为底层数据结构。虽然在建立RDF知识库方面已经做了大量的工作,如DBPeida,Yago 和Freebase,但是除了[13]之外,很少有文献研究RDF数据质量问题。但是,[13]没有考虑RDF图的图结构
在本文中,我们将传统的CFD(条件函数依赖)扩展到基于图的条件函数依赖(GCFD)(在第3节中正式定义),其被设计为以统一的方式检测属性值和RDF数据的语义结构的依赖规则。为了有效地发现GCFD规则,我们的方法如下:给定一个RDF图G,我们首先挖掘RDF图G中的频繁结构模式然后将每个频繁结构模式表示为一个表。显然,我们可以应用现有的算法在这些表中逐个找到CFD规则,但是,幼稚的解决方案由于大量的结构模式而效率低下。为了避免冗余计算,我们设计了几个剪枝规则。例如,如果一个结构模式P包含另一个模式P0,如果已经找到P0中的CFD,我们可以节省一些计算成本。更多细节见第5节。
综上所述,本文做出以下贡献:
1. 我们建议GCFD以统一的方式定义RDF数据的属性值和语义结构的相关性。
2. 我们提出了一个简单而有效的框架来发现RDF图中的GCFD。为了提高计算效率,我们设计了一些有效的剪枝策略来避免冗余计算
3. 我们在一些真实的RDF存储库中进行实验,以发现GCFDs,并使用它们来检测RDF图中的异常数据。

3、相关工作

函数依赖用于发现关系表中的数据依赖,这有助于检测数据冲突和提高数据质量。对它的研究已经进行了二十年,提出了许多方法,包括经典算法TANE ,FastFD。函数依赖有几个扩展:条件函数依赖(CFD),值聚集图函数依赖(VGFD) 。Fan等人提出了一种支持语义常量模式的函数依赖扩展,这对于清理关系数据是有用的。

尽管在建立大规模的RDF知识库方面做了大量的工作,但是除了[13]和[[1]之外,很少有文献研究函数依赖来发现RDF图中的异常数据。[13](扩展函数依赖检测rdf图中的异常数据)首次将RDF图视为一个图数据库,并提出了值聚类图函数依赖(VGFD)来发现异常数据。值聚类方法可以有效地解决多属性问题。然而,这种方法没有考虑语义约束。[1]提出了一种基于关联规则的方法来寻找RDF图中的依赖关系,但是,它也没有考虑RDF图的结构。

4、背景及问题定义

我们在这一部分正式定义了我们的问题,并回顾了一些将在本文中使用的符号。RDF图表示为G=<I , L , R , E>,其中 ,L ,R集合分别表示实例,字面量,关系标识符;而有向边集合E = ×R× (  L)。对于每一个关系r  R,我们表示他的相反关系为;而则是r对应的所有的集合;

图G上的路径c 表示为tuple<>,其中

(1) 

(2) ∀i,0 ≤ i < n, 

(3) 若i ≠ j,则。 也就是说路径的表示是: 起点-> 节点A -> 节点B -> 节点C -> 终点,其中箭头是单向边的意思

表示所有可能的路径。在传统的RDF数据的SPO(主谓宾)视图中,每个主语都有有限的谓词,所有谓语都围绕一个主语,形成一个“星形”模型。我们很容易注意到,这种“星形”模型描述主体的能力有限,缺乏邻近实体信息。因此,类似于[13],我们使用“复合属性”概念,并使用它来传达邻近信息

定义一: 图G的复合属性表示为,其中, 存在一个路径p=<>∈

给定一个复合属性,图G中所有支持的三元组都可以写成Inst(,G),并且Inst(,G)={}   这个Inst(r,G)表达的就是在G中存在一条路径从节点I_0到节点I_n,且这些路径是属于r^o的

表示G中从i通过路径r^o到达的节点i'。

如上图所示,三元组<Jonathan Demme,masterwork ,Philadelphia>,通过复合属性"masterwork o type" ,得到 <Jonathan Demme, masterwork o type, movie>,使实体信息表示的更加全面。

通过复合属性的定义,实体的描述可以在垂直方向上扩展。事实上,在“星形”模型中,实体的横向信息也有正式定义的必要。我们称之为“合取性质”。其定义详述如下。

定义二:图G的结合属性表示一个复合属性{}集合,表示为,其中,并且有

如上图所示,Jonathan Demme的结合属性"constellation + birthplace + occupation + masterwork "可表示为, 而其对应的是<Pisecs, New York, Philadelphia, film director>

考虑到在RDF数据集中具有多值属性是常见的:DBPedia中60%的属性是多值的。因此,我们将依赖关系重新定义如下:

定义三: 给定i,j,并且;i和j在性质上相等,如果表示为。此运算符扩展到合取属性,对于,意味着任意定义三表示的就是如果两个节点如果通过相同的边(也可能是复合属性)连接到相同的节点,那么Val(节点A,边x)≡Val(节点B,边x)

在定义3中,我们扩展了多值性质的传统等式关系。事实上,很难要求两个多值属性完全相等。如上图所示,Tom Hanks和Jonathan Demme可能除了“Philadelphia”还有别的互不相同的master work,所以定义3定义这两个实体在master work性质上相等表示为Val(Tom Hanks,master work)Val(Jonathan Demme,master work)。

以上定义是基于传统的逻辑变量,没有语义的条件限制[6]。基于这种考虑,我们定义了广义等式关系。在此之前,我们首先给出基本的陈述。是一个模式表,它包含了一些属性的赋值。x是一个属性,要么是一个dom(x)中的常量值,要么是一个用 _ 标记的可以是dom(x)中的任意值的未命名变量。

定义四:虑到常数值和符号“_ ”,我们定义一个运算符。给定i,j

当且仅当或者其中一个为_时,

当且仅当∀时,

基于以上这些形式定义,我们定义基于图的条件函数依赖(GCFD)如下:

定义五:(GCFD) 图条件函数依赖是表示为的元组,其中。对于模式表中的每个元组,给定i,j,当且仅当 时,

如下图所示,给出了GCFD(occupation→ masterwork ◦ type, film director | movie)的例子,其由图形结构表示,其中“a”和“b”是数据集中的实体。这个GCFD的意思是:如果“a”是一个film director,那么a的masterwork应该是一部movie。

GCFD的定义使我们能够更好地描述RDF图的依赖关系。同时,我们可以将GCFDs作为规则来检测违反规则的异常数据。在下一节中,我们将介绍挖掘GCFDs的框架。

5、解决方案

作为传统的依赖规则挖掘,我们假设只有频繁依赖关系是可信的。因此,给定一个RDF图G,我们首先发现满足指定频率阈值的频繁图结构。我们以表格的形式表示每个频繁的图形结构。然后,我们设计修剪策略来减少冗余计算。最后,我们将CFD发现方法应用于这些转换后的“表格”,以发现GCFDs。整个框架在算法1中描述。

事实上,该框架是根据跳数进行的逐级发现。第2行描述了检测n跳邻域图结构的过程。我们稍后会详细介绍。第8行使用修剪策略来减少冗余计算。第9行首先将图结构转换成表,然后通过使用在传统关系表中发现循环前缀的方法产生循环前缀。

在链接数据集中,实体通过关系连接。我们相信两个实体之间一定有某种联系,就像雨林中的蝴蝶效应一样。在这个场景中,一个主体就像一只“蝴蝶”,它的影响逐渐扩散到他周围的环境中。因此,为了更好地发现数据相关性,我们使用n跳邻域图模式来描述“蝴蝶”的周围环境。下面我们给出一个正式的定义。

定义六(多跳邻域图模式):给定RDF图G=<>并且合取属性集,任意, 从开始的N跳深度优先搜索构成的合取性质称为N跳邻域图模式,简称图模式,表示为P'其中P'

通过定义n跳邻域图模式,我们可以将算法1中第2行的任务转化为发现频繁图模式。我们可以把这项任务分成几个步骤。首先得到每个实体的相关n跳邻域图。其次,我们把每一个n-hop邻域图看作一个表,在这个表中,实体的每一个属性都被转化为表中的一列。第三,在把每个实体翻译成一个表之后,我们把每个表看作一个事务,把主体看作事务id,把属性看作项目。然后,我们可以挖掘这些事务的频繁模式,获得目标结构,并在此基础上寻找数据依赖关系。上述过程在算法2中描述。

举个栗子:下图展示了得到一跳图结构。JD和TH分别表示Jonathan Demme和Tom Hanks的实体。o、m、c、bp、bl是图1中相对属性的缩写。是相对属性值。第一步通过1跳DFS算法得到包含JD和TH实体所有信息的1跳表。步骤2从每个表中提取主题和所有谓词,形成一个事务表。步骤3通过使用FP-Growth算法获得频繁模式<o,m,c>,并获得目标结果图结构。

如开始所讨论的,在获得频繁图模式之后,所有匹配它的实体可以形成一个表。例如,在图3中,<o,m,c>是一个频繁图模式,然后我们从“JD”和“TH”中提取相对属性值,形成一个转换表。这样,我们就把我们的问题转换成了另一个问题:发现表中的依赖关系。对于这个问题,可以用CFD发现算法来解决。

[6]提出了三种发现表中CFDs的算法:CFDMiner、CTANE和FastCFD。CFDMiner的目标是不断发现CFD。而CTANE和FastCFD是为一般CFD而开发的。实际上,CFDMiner的性能总是优于其他两种算法。随着表的增大,CTANE的时间呈指数增长。但是FastCFD可以很好地扩展,而当arity大于17时,CTANE很难运行到完成。因此,考虑到我们工作中图形模式的规模可能相对较大,我们将选择CFDMiner和FastCFD算法来发现CFD。

总之,在这一部分,我们介绍了我们的解决方案的框架。对于任何频繁的图形模式,我们将利用计算流体动力学发现算法来检测相对转换表中的依赖关系。然而,与传统CFD问题不同的是,我们这里有多个表。我们的修剪策略就是基于这种差异。

6、修剪策略

6.1修剪规则

在我们以前的框架中,我们通过使用FP-Growth得到频繁图模式。这些图形模式可以有重复的属性。当我们使用CFDMiner或FastCFD来发现这些重复属性上的GCFDs时,可能会导致冗余计算。我们直观的剪枝思路就是基于这个考虑。

给定一个RDF图G,我们有图模式P和实体e,如果∀,实体e有这个复合属性。我们称实体e匹配模式P,表示为e ∝ P。数学图形模式P的所有实体构成一个表,我们称之为模式表,用T(P,G)表示。例如,图4显示了一个模式表。它基于图3中发现的频繁图模式。support(P,G)表示T(P,G)中的实体数。在我们介绍修剪策略之前,我们给出“向上模式表”的定义,如下所述。

定义七(向上模式表):给定一个RDF图G,图模式,其中,我们通过插入“null”作为空属性值来扩展以形式匹配的所有实体。我们将这些实体组织成一个表,表示为

我们在图5中展示了一个向上模式表的例子。它可以从T(,G)扩展以适应图形模式,或者从T(,G)扩展以适应图形模式。实体“Jonathan Demme”匹配,但不匹配。我们在中插入“null”作为“出生地”属性值。

给定一个RDF图G,频繁模式其中 ,我们有模式表T(,g)和T(,g)。为了发现T(,G)和T(,G)中的CFDs,我们需要分别运行CFDMiner两次。我们的策略旨在简化这一过程。

如图5所示,我们知道T(,G),T(,G)和U(,G)之间的关系。我们还找出了这三个表中自由项集合的关系。我们将自由项集合分别标记为。那么我们有,我们给出下面的证明。

定理1:给定RDF图G、图模式P和模式表T(P,G),从T(P,G)中发现的所有自由项集合都标记为。我们将记录添加到T(P,G)中,以创建新的表T'(P,G)。那么∀X∈,X仍然是T'(P,G)中的自由项集合。

命题1:给定RDF图G和频繁模式,其中,我们将从上层模式表U(,G)中发现的所有自由项集标记为。模式表T(,G)中的所有自由项集表示为。然后我们有

命题2:给定RDF图G和频繁模式,其中,从上部模式表U(,G)中发现的所有自由项集被表示为。从模式表T(,G)中发现的所有自由项集都表示为。然后我们有

如上所示,我们找出了两个图形模式之间的自由项集合关系。我们概括了下图所示的图形模式的大小。

定理2:给定RDF图G=<I,L,R,E>和图形模式,∀i,1 ≤ i ≤ n,我们将模式表T(,G)中的所有自由项集标记为,向上模式表U(,G)中的所有自由项集标记为,必须有(1 ≤ i ≤ n)。

根据定理2,我们可以简化CFDMiner[6],同时在多个表上运行它。例如,当在模式表T(,G)和T(,G) ()上运行CFDMiner时,我们不需要分别计算T(,G)和T(,G)上的自由项集。我们只需运行一次CFDMiner,就可以发现上模式表U(,G)上的自由项集。对于中的每个自由项集,我们检查它是否是T(,G)和T(,G)中的自由项集。这会节省很多时间。更具体地说,当存在三个或更多形式的子集关系时,可以节省更多的时间。在接下来的章节中,我们主要介绍发现图模式之间的子集链的方法。

6.2发现子集链

一般来说,给定图形模式,我们可以很容易地判断这两种模式之间是否存在包含关系。然而,当面对大量的模式时,检查包含关系和发现子集链并不是一件容易的事。我们将图模式集转换为有向图,然后使用贪婪算法来选择路径

首先,我们介绍了将图模式集P转换为有向图T的过程,P中的每个不同的图模式都被视为图中的一个节点。图T的节点数与P中的模式数相同。给定两个模式∈ P,如果,则在T中存在从节点到节点的有向边,其中分别表示图模式

如上所述,有向图T可以表示集合P的所有包含关系。因此,我们在集合P中发现子集链的问题被转化为在图T中检测路径的新问题。在讨论这个新问题之前,我们引入了一种编码技术来将图模式集转换为有向图。

对于集合P中的每个性质,我们设计了一个唯一的代码。对于每一个p ∈ P的图模式P,它的代码都是由P中的所有属性通过“或”运算组成的。例如,在图6(a)中,我们有五个属性:“occupation”、“masterwork”、“constellation”、“birthplace”和“bloodtype”。我们分别为它们设计独特的编码:“10000”、“01000”、“00100”、“00010”和“00001”。模式p1(“occupation”、“masterwork”)被编码为“11000”,这是“10000”和“01000”之间“或”运算的结果。

给定任意两个模式(),我们分别有它们的代码。我们知道,当且仅当 = 。当使用|来表示时,我们有当且仅当|= 。换句话说,如果我们用“异或”运算来表示结果,则(|) ∧ = 0。同样,当且仅当(|) ∧ = 0,我们有  = 。所以为了检查的关系,我们只需要确认(|) ∧ = 0还是(|) ∧ = 0。考虑到“或”和“异或”是基本操作和相对节省时间,这种编码技术将花费更少的时间来获得有向图。

如上所述,图模式的子集链是有向图中的一条路径。因此,我们的目标是选择图中的路径

首先,我们定义图T中的最大路径,如果有一条路径,并且不存在路径p'使得∈ p' (1 ≤ i ≤ k)且pp' 。那么我们称p为最大路径。对于图中的任意节点n,可能有许多包含节点n的最大路径,我们只能选择一条路径作为子集链。我们希望选择包含节点n的最长路径。因此,我们的目标是选择覆盖尽可能多节点的最大路径。

我们分两步选择最大路径。首先,在这个有向图T中有一个拓扑排序是很重要的。之后,我们给每个节点一个层次,这个层次代表最长最大路径中的顺序。其次,我们在这个分层的有向图中选择子集链。下面是详细描述。

许多应用都是基于拓扑排序的。在我们的工作中,我们使用它来标记节点的级别,以发现图中的最大路径。

在有向图上进行分级排序后,我们将重点放在路径的选择上。在分级图中,我们的贪婪策略主要考虑以下因素:

1 .当一个节点被多条路径覆盖时,优先选择较长的路径。

2 .当面对候选节点时,选择级别较高的节点。

3 .当候选节点具有相同的级别时,选择具有最小外倾角的节点。如果它们仍然有相同的外倾角,选择一个较小的内倾角。

4 .每个节点只能选择一次,每次选择后立即更新图形。

在算法3中,我们给出了上述考虑的正式描述。例如,在图6(b)中,我们选择“001”作为第一个节点,因为它具有最高级别。当考虑下一个节点时,“002”和“003”是两个候选节点,它们具有相同的出度。但是“003”有较小的索引。所以我们选择“003”作为下一个节点。基于同样的原则,我们选择“005”和“008”作为后续节点。这样,我们选择子集链(001,003,005,008)和(006,002)。

实验

在这一部分,我们评估了我们的方法在两个真实的大型图形数据集,包括数据库和中文链接数据集。我们简要介绍了这两个数据集:

DBPedia。DBPedia是一个大型的结构化数据协作知识库,从包括维基百科在内的许多来源获得。它有400万个实体和24.6亿个三倍。它包含529个类和927个属性。

Chinese Linked Data Set。该数据集是从中国百科全书中构建的,它集成了许多半结构化的数据资源,如百度百科2和豆瓣3。到目前为止,它有590万三倍,208处房产和67万个实体。

我们的算法是使用标准C++实现的,我们的实验是在一个具有2个至强2.0G内核和30G内存的工作站上进行的。我们用的关系数据库是MySQL 5.5.15.0。

首先,我们评估了我们的方法的性能,如图7所示。考虑到当邻居级别大于4时,只有很少的GCFDs存在,我们在实验中限制邻居级别不超过4。此外,我们对图形模式进行了抽样实验。我们随机选择了DBPedia中的400个频繁图模式和CLDS的200个频繁图模式。正如我们所看到的,修剪策略可以节省至少8%的时间。

图7显示,我们在百威英达发现了760个基因芯片,在CLDS发现了89个基因芯片。图9显示了GCFDs的例子。我们在图8中给出了一个从CLDS数据集发现的解释的例子。

这个GCFD描述了这样一个规则:在中国,如果一个实体的邮政编码是“410007”,那么这个实体的位置一定是在湖南长沙,它的相关方言应该是长沙话。这个规律很有道理,说明了一个普遍现象:无论在哪里,它的邮编在一定程度上决定了它的方言和所属省份。我们可以看到,这个GCFD反映了考虑属性值和RDF数据语义结构的数据依赖性,这是传统方法无法发现的。

在检测到GCFDs后,我们使用它们来发现相关数据集中的异常数据。给定GCFD规则,如果任意两个实体I和j满足Val(i,X)Val(j,X),但Val(i,Y)Val(j,Y)或Val(i,Y)或Val(j,Y)。我们认为实体 i 和 j 一定有异常数据。

下面的例子说明了这个过程。如图9所述,我们发现了图10所示的GCFD法则[ =occupation→masterwork◦ type (film director | movie)]。我们使用此规则来检查是否存在违反此规则的实体。结果,我们发现实体“Jonathan Demme”违反了这一规则。其RDF三元组描述如下。

<Jonathan Demme, occupation, film director>  <Jonathan Demme, masterwork, Philadelphia>  <Philadelphia, type, city>

正如我们所看到的,第一个三倍是规则的左部分的满意度,这表明Jonathan Demme的占领。然而,第三个三点表示Philadelphia是一个city,这违反了我们的GCFD规则。因此,该规则有利于检测异常三元组。此外,我们发现CLDS的这种错误是由数据链接引起的,因为CLDS是由多源数据构成的。《Philadelphia》是一部著名的movie,也代表了一个city,导致了上面提到的违规。

在DBPedia中,我们利用GCFD规则发现了2145个异常三元组。我们选择了100个样本,并确认其中85%是真正的错误。我们还在CLDS确认了60%的精确度。这种低精度是因为CLDS是一个由多种资源构成的中文数据集,中文中的相同含义可以有许多不同的表达方式。

在DBPedia中,我们利用GCFD规则发现了2145个异常三元组。我们选择了100个样本,并确认其中85%是真正的错误。我们还在CLDS确认了60%的精确度。这种低精度是因为CLDS是一个由多种资源构成的中文数据集,中文中的相同含义可以有许多不同的表达方式。

结论

本文旨在解决RDF图中异常数据的发现问题。与传统方法不同,我们提出了基于图的条件函数依赖的定义(GCFD),并设计了一个框架来有效地发现它们。受条件函数依赖的启发,我们将其扩展到图形数据。考虑到涉及多个表,我们设计了剪枝策略来减少冗余计算。最后,在两个数据集上的实验结果证明了算法的有效性,证实了工作的实用价值。

[论文阅读]《Using Conditional Functional Dependency to Discover Abnormal Data in RDF Graphs》阅读笔记相关推荐

  1. 【PaddlePaddle论文复现】LARGE SCALE GAN TRAINING FOR HIGH FIDELITY NATURAL IMAGE SYNTHESIS阅读心得

    [PaddlePaddle论文复现]LARGE SCALE GAN TRAINING FOR HIGH FIDELITY NATURAL IMAGE SYNTHESIS阅读心得 作者:Andrew B ...

  2. 【论文】Believe It or Not, We Know What You Are Looking at! 阅读笔记

    [论文]Believe It or Not, We Know What You Are Looking at! 阅读笔记 1.Gaze Following 2.总的网络图 3.Gaze directi ...

  3. CGAN论文解读:Conditional Generative Adversarial Nets

    论文链接:Conditional Generative Adversarial Nets 代码解读:Keras-CGAN_MNIST 代码解读 目录 一.前言 二.相关工作 三.网络结构 CGAN N ...

  4. 【论文阅读】Weakly Supervised Semantic Segmentation using Out-of-Distribution Data

    一篇弱监督分割领域的论文,发表在CVPR2022上: 论文标题: Weakly Supervised Semantic Segmentation using Out-of-Distribution D ...

  5. 【护眼阅读】PC端通过主流常用浏览器打开本地WEB页面阅读本地TXT小说

    自用-通过WEB页面阅读本地小说,生成章节导航,设置字色和背景色达到护眼目的,HTML+CSS+JS 章节导航 需求分析 HTML代码 CSS代码 JS代码 总结 章节导航 从分析需求入手,查找资料, ...

  6. 吴军,阅读与写作,01理解他人,什么是合格的阅读理解?

    课程的第一讲,我们先来聊聊阅读理解. 受过教育的人,都识字,但真不见得阅读理解能力过关.比如,根据我当学生.当助教.当老师和职业管理者的经验,在任何考试中,考不好的学生一半是题目没读懂. 为什么我会这 ...

  7. 安卓pdf阅读器_带笔的小尺寸BOOX Nova Pro电子书阅读器来了!

    近两年,给阅读器配备手写笔逐渐成为了电纸书行业的一种潮流.2月23日,文石隆重推出了一款全新的7.8寸电子书阅读器BOOX Nova Pro. 这款产品最特别的地方在于,它首次给7.8寸的小屏阅读器配 ...

  8. [置顶] 为什么要阅读源代码?如何有效的阅读源代码? 选一些比较优秀的开源产品作为源代码阅读对象?...

    盛大TeamHost上有个关于学习开源项目的wiki :http://www.teamhost.org/projects/learn-with-open-source/wiki/Wiki 一.为什么要 ...

  9. 为什么要阅读源代码?如何有效的阅读源代码? 选一些比较优秀的开源产品作为源代码阅读对象?

    一.为什么要阅读源代码? 很多作家成名之前都阅读过大量的优秀文学作品,经过长期的阅读和写作积累,慢慢的才有可能写出一些好的.甚至是优秀的文学作品. 而程序员与此类似,很多程序员也需要阅读大量的优秀程序 ...

最新文章

  1. C#开发ActiveX网页截图控件
  2. HTTP 与HTTPS的结构
  3. 是什么摧毁了程序员的工作效率
  4. 删除计算机文件的几种方法,电脑删除不了文件怎么办?教你几种好的处理方法,一学就会...
  5. SpringMVC自学日志05(结果跳转方式,数据处理 ,乱码问题)
  6. 米的换算单位和公式_小学三年级数学常用公式和单位换算,孩子复习宝典!
  7. python测量信号信噪比
  8. C#实现对文件目录的实时监控
  9. 一个防御SQL注入攻击需要注意的问题
  10. Android 开发性能优化
  11. Java面试 Java简历 Java简历模板
  12. 窥探PTAM之模板搜索
  13. HAL库STM32CuBe实现按键扫描芯片STM32F407
  14. 2.3 从外部置入图片 [Ps教程]
  15. 跟阿里巴巴学开会,我们拉着5位CEO聊如何“捅刀子”
  16. 创新理念 汉王手写式鼠标砚鼠新品使用体验
  17. opencv图像处理初步(一):灰度化和二值化
  18. 2020年百度之星·程序设计大赛 - 初赛一(前三题)
  19. java编程基础篇-- 编写一个程序,从键盘输入三个整数,求三个整数中的最小值。
  20. 30.华为WLAN产品特性介绍_射频管理

热门文章

  1. Linux:xinetd服务安装与配置(操作环境:Ubuntu 18.04)
  2. OSPF特殊区域(stub、stub no-summary、nssa)
  3. java中jsp内建对象有_JSP内置对象有哪些
  4. 马士兵mca课程java学习笔记
  5. PS长图快速切片_如何解决PS选择主体崩溃问题
  6. Tomcat系列:Tomcat版本与JDK版本对应关系
  7. 一文搞懂ROS2的spin_some, spin和ROS的spinOnce
  8. VBA 连接Oracle 数据库
  9. 先验概率与后验概率是什么
  10. Android .mk文件语法规范及使用模板