简单易用的MongoDB

    从我第一次听到Nosql这个概念到如今已经走过4个年头了,但仍然没有具体的去做过相应的实践。最近获得一段学习休息时间,购买了Nosql技术实践一书,正在慢慢的学习。在主流观点中,Nosql大体分为4类,键值存储数据库,列存储数据库,文档型数据库,图形数据库。 今天主要快速的浏览了文档型数据库中目前市场占有率的最高的MongoDB数据库。记得初次见到和关注这个数据库还是我刚来上海的时候,公司将该数据库作 为新建的项目管理系统的后台数据库,当时还是很向往的,只是无缘参与那个项目,也就一直没有和该数据库打上交道。接下来简单的介绍下该数据库的基本原理和 相关应用,也算是巩固知识和加强记忆了。大体上快速学习分为两部分,第一部分为基础,第二部分为进阶。

 

  •  优势与不足

  首 先,MongoDB不需要表结构,它是模式自由的(schema-free),例如{"welcome", "Shanghai"}, {"name", "bibi"}可以放到同一个集合中。那么它是如何在存储数据的呢?MongoDB在保存数据时会使用Bson的形式,一种json的二进制化形式,并把 它与特定的Key进行关联。这样将非常便于程的扩展和维护,在需要增加新字段或者修改字段时只需要修改程序,而不需要修改数据库的架构,非常的方便。

  其 次,MongoDB原生的提供很强的伸缩性,对于web应用,当需要存储的数据不断增加时,我们将面对一个很大的问题,如何给数据存储模块扩容。在原有的 数据存储模块架构中,往往需要通过购买功能更强大的机器,给数据库服务器升级,但这存在的问题是成本很高,同时升级也受限于当时硬件技术水平的。于此同 时,由于实际web应用中,访问量并不是相似的,例如在各种活动期间,会出现各种特殊峰值,例如淘宝的11节的第1分钟的访问量都已达到千万级,而在平时 这个值相对小很多。所有这时增加服务器在忙时可能仍然达不到目的,而闲时又会造成大量的浪费,所以伸缩性成为上成为web架构中的最重要的技术指标之一, 这也是当前Nosql技术流行的主要原因。

  最后,MongoDB还提供丰富的功能,包括支持辅助索引,支持MapReduce和其他聚合工具,并提供了分布式环境下的高可用,比如自动的在集群中增加和配置节点。

  当 然,MongoDB也不是万能的,实际上也存在一些不足。例如,不支持join查询和事务处理,数据也不是实时写入到磁盘的,同时存储数据时需要预留很大的空间。在实际项目中,需要根据实际的需要进行选择,当前很多主流网站均使用Sql+NoSql的形式构建数据库存储模块。

  • 基本结构

  MongoDB中的文档document相当于Sql数据库中的一行记录;多个文档组成一个集合collection,相当于关系数据库的多个集合组合在一起,就是数据库database;一个数据库服务器可以有多个数据库实例。

  • 相关文档和程序

官方下载地址:https://www.mongodb.org/, 官方目前的版本是3.2,其实2.4以后版本都可以很.NET平台很好和整合,如果官网下载失败(常见),就直接网上搜索一个指定版本就好。

官方文档地址:https://docs.mongodb.org/getting-started/shell/

Mongod:数据库程序

Mongos:分片控制器

Mongo:Windows下客户端Client

Mongodump:数据库的dump工具,支持备份,快照等方式

Mongorestore:从一个dump文件恢复数据库

Mongoexport:导出单个数据集合到json、CSV等格式

Mongoimport:导出json、CSV等格式数据

Mongofiles:用于到GridFS中,设置和获取数据文件

Mongostat:显示性能统计信息

  • 安装步骤(还可以参考博主懒惰的肥兔的博文http://www.cnblogs.com/lzrabbit/p/3682510.html,非常详细,点个赞)
  1. 首先在当前目录中,建立相关目录:Data保存数据文件,log保存日志信息,etc保存配置文件(mongodb.conf)。
  2. 在cmd中使用命令,命令如下所示:

创建服务:sc create mongodb binPath="d:\mongodb\bin\mongod.exe –service –config=d:\mongodb\etc\mongodb.conf"

快捷方式:mongod -f d:\mongodb\etc\mongodb.conf --install

开启服务:net start mongodb

关闭服务:net stop mongodb

删除服务:sc delete mongodb

配置文件内容如下:

dbpath=D:\mongodb\data #数据库路径 logpath=D:\mongodb\log\mongodb.log #日志输出文件路径 logappend=true #错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件 journal=true #启用日志文件,默认启用

quiet=true #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false

port=27017 #端口号 默认为27017

 

.NET 下Mongodb的客户端API可以nuget中很容易的找到,mongoDB .NET 2.0 Driver是使用率最高的,其支持.NET await的异步模型、动态类型dynamic、扩展方法形式的常见Linq查询(表达式树)、简化的日志管理和静态性能的记录,使用起来非常的便捷。

在该组件中,client默认就是连接池的方式,所以直接使用单例的client即可,在插入数据时使用BsonDocument,其和json的结构完全一样,此外在构建Client的连接字符时主要加上mongodb://的协议名就OK。该组件还支持类似automapper之间的功能,将数据库对象与业务对象的映射,包括自定义属性映射,缓存元数据等功能具备。

基础操作文档地址为:http://mongodb.github.io/mongo-csharp-driver/2.0/getting_started/quick_tour

AutoMap文档地址:http://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/mapping/

 

  • 性能优化

Mongodb和一般关系型数据库一样,也支持查看执行计划explain,来了解系统实际对索引的使用情况,并根据该情况优化索引,提升查询性能。在执行计划结果中,包含如下属性。

Cursor:返回游标类型(BasicCursor, BTreeCursor)

Nscanned:被扫描的文件数量

N:返回的文件数量

Millis:耗时(毫秒)

indexBound,表示索引的使用情况,

 

优化器Mongodb database profiler

和 关系型数据库类似,mongodb也提供慢查询(就是耗时较长的命令)日志的分析,Mysql有show Query Log与之对应。Profile有3个级别,分别是:0,不开启;1,记录慢命令(默认为>100ms);2,记录所有命令。可以通过以下命令获取 和设置profile级别和慢命令的执行时间阀值,db.getProfilingLevel(),db.setProfilingLevel(1, 100)。

MongoDb 的profile是记录在数据库的系统db中的,位置在system.profile,因此可以通过如下命令获取所有执行时间大于10ms的 profile记录,db.system.profile.find({millis:{$gt:5}})。结果字段中,ts表示命令的执行时 间,info为命令详细信息(类似SQL语句了),reslen表示返回结果集大小,nscanned表示查询扫描的记录数,nreturned表示实际 返回的结果集,millis为执行耗时。此外,profile还提供一个show profile命令用于获取最近5条执行记录。

当发现扫描的数据集数远大于返回的记录集数时,就需要考虑建立索引来加速查询了,接下来介绍几条常见的优化策略:

  1. 在查询条件和排序字段上建立索引
  2. 限定返回的结果集skip(),limit(),在这点上mongo真心很赞,因为在互联网场景下的查询都是数据库分页的
  3. 只 查询使用到字段,减少内存消耗,在find()中第一个参数为查询条件,第二参数为所选字段,与SQL中尽量不要使用select * 类似。例子为db.students.find({}, {name:1}).sort(age: -1).skip(2).limit(3)
  4. 采 用Capped Collection,类似固定大小的数组,效率高,使用方式为:db.createCollection("mycoll", {capped:true, size:100000})。需要注意的是该集合只支持insert和update操作,不支持一般的delete,只支持类似于SQL中 truncate的drop操作。其数据顺序以插入顺序为准,如果超过大小,则按照循环数组的形式覆盖最先的记录(FIFO)。
  5. 使用类似存储过程的Server Side Code Execution来减少网络传输开销
  6. 在mongodb query optimizer不能良好工作时(极少),可以通过hint强制索引,在SQLServer, Oracle中也有相似概念,就是不知道有木有包含索引
  7. 采用profiling

 

  • 性能监控

与性能监控相关的常见命令包括:

db.serverStatus(): 查看数据库实例的运行状态,信息包括:服务器版本、启动时间、globalLock中的当前请求(读/写)队列信息、activeClients当前的连 接信息、mem内存占用信息、indexCounters索引被访问命中的相关信息、服务器的数据量、添删改查等操作的信息

db.stats(): 查看当前数据库的状态,例如当前的test数据库中集合&对象的数量,数据的可用&当前大小,索引的数量和大小等

Tip:

在windows中有mongostat和mongotop工具用于查看统计信息,在Linux有mongosniff,mongostat等工具,此外还有cacti、Nagios、Zabbix等第三方监控工具。

 

  • Replica Sets复制集

MongoDB 支持在多个机器中通过异步复制达到故障转移和实现冗余,多机器中同一时刻只有一台用于写操作,其支持的高可用分为旧的Master-Slave主从复制方 式和Replica Sets复制集方式,推荐使用后者。可以通过rs.status()命令查看复制集状态,members节点描述复制集相关信息,还可以使用 rs.isMaster()查看相关信息。需要注意的是,在多服务器的集群中,通过一个keyFile来行进识别。

    Replica Sets时通过日志oplog来存储写操作的,oplogs.rs是一个固定长度的Capped Collection,存在于local数据库中。命令db.printReplicationInfo()可以查看oplog的元数据信 息,db.printSlaveReplicationInfo()可以查看slave的同步信息。此外,ReplicaSets的配置信息放在 system.replset中,可以很方便的看到主从的配置信息。

    实 现数据的读写分离非常简单,只需要在从库中设置db.getMongo().setSlaveOk()即可。ReplicaSets的故障转移是自动的, 比如我们kill primary的pid, 然后再次查看rs.status()可以看到主服务器的的转移。在windows中可以使用tasklist查看进程信息,tskill关闭指定pid的 进程,netstat –aon | findstr "27020"可以找到占用指定端口的pid。

    在 提供高可用方案的同时,它也提供负载均衡的解决方案,增减Replica Sets节点非常常见,可以通过rs.add("replset:27023")增加节点,节点增加后自动与主服务器同步数据,可以通过 rs.remove("replset:27024")减去该节点,感觉棒棒哒。

部署Replica Sets

  1. 在单机多实例的实验场景下,由于次要的仲裁服务器arbiter不支持使用localhost(会提示重复),因此在C:\Windows\System32\drivers\etc\hosts中添加一行:127.0.0.1 replset 
    
  2. 添加primary节点和两个Secondary节点(其中一个为仲裁节点),其实就是把之前的配置复制一遍,在各自的配置文件中加入replSet=rs1,并设置不同的port
    
  3. 分别启动三个节点mongo -f XXX
    
  4. 连接primary节点(--port 27020),并通过命令行配置,命令如下所示,当然也可以通过配置文件来设置:
    
设置配置:config_rs1 = {_id : "rs1",members : [ { _id:0, host:"replset:27020", priority:1 },{ _id:1, host:"replset:27021", priority:1 },{ _id:2, host:"replset:27022", priority:1, "arbiterOnly": true } ]} 启用配置:rs.initiate(config_rs1) 这儿需要注意,这个操作可能需要很长时间,请耐心等待

Tip:默认情况primary支持读写,而secondary不支持,可以通过rs.slaveOk()命令使得次要节点也能读写。

此外,大家也可以查看:http://www.cnblogs.com/jRoger/articles/4708490.html,博主的内容很详尽。

 

  • Sharding分片

这 是一种将海量数据水平扩展的数据库集群系统,数据分别存储在Sharding的各个节点上,这就是mongodb源生支持互联网场景的特征,这部分管理不 再是第三方的一个解决方案而是数据库自带的,因而更加便捷高效,这也是我们常说的分库分表。MongoDb的数据分块被称为chunk,每个chunk都 是collection中的一段连续的数据记录,通常大小为200MB,超出则生成新的数据块。

构建一个Sharding Cluster需要三种角色:

  1. Shard Server即存储实际数据的分片,每一个shard可以是一个mongod实例,也可以是replicaSet,推荐后者
  2. Config Server,为了将一个特定的Collection存储在多个Shade中,需要为该Collection指定一个shard key,例如{age:1},shard key决定该条记录所属的chunk。Config Servers就是用来存储所有Shard节点的配置信息、每个chunk的shard key范围、chunk在各shard的分布情况、该集群中所有DB和Collection的Sharding配置信息。
  3. Route Process是一个前端路由,客户端由此接入,然后询问Config Server需要到哪个Shard上查询或保存记录,在连接到相应的Shard进行操作。客户端只需要将原本发送给mongod的信息发送到 Routing Process,而不用关系操作记录存储在哪个Shard。也就是说这个步骤对用户透明,路由算法由系统提供,比如我们常见的一致性hash算法。

 

搭建步骤:(也可以参照博友苏若年的博文http://www.cnblogs.com/dennisit/archive/2013/02/18/2916159.html,非常详细)

  1. 首 先构建之前之前介绍过的三个角色,route process 1个(port, 27026),config Server 1个(port, 27027),Shard Server 2个(port, 27028, 27029),建立相关目录和设置相关配置文件。配置文件的差异有:Config配置文件:configsvr=true;Router配置文 件:configdb=localhost:27027(配置服务器地址), chunkSize =100(chunk块的大小),其他配置基本一致。
  2. 连 接到Router的admin数据库, mongo admin --port 27026, 然后运行命令添加两个shard节 点,db.runCommand({addshard:"localhost:27028"}),db.runCommand({addshard:"localhost:27029"}), 完成Sharding集群的配置。
  3. 选择指定数据库将其状态设置为可以分片db.runCommand({ enablesharding:"test" })
  4. 指定分片具体集合,db.runCommand({ shardcollection:"test.users", key:{ _id:1 }}),至此环境搭建完成。
  5. 可以在该表中插入100000条测试数据,然后通过db.users.stats()查询该数据集情形,在shards中可以看到具体各个片区的数据量。

 此外,该系统支持添加节点和删除节点,删除节点的命令为 db.runCommand({ "removeshard":"localhost:27030" ),printShardingStatus()查 看分片的生效情况,还可以通过db.runCommand({ isdbgrid:1 })命令查看当前实例是否在Sharding环境中。

 

  • Replica Sets与Sharding的结合

通 过ReplicaSet和Sharding结合,可以提供可扩展的高可用方案。当业务规模增大时,我们常见的扩展方式有两种,一种是垂直伸缩,一种是分片 (水平伸缩),前者通过增加服务器的CPU和内存来实现,成本很高,而后者将数据分布到不同的服务器,不同服务器上的数据分块共同组成一个逻辑数据库。

图 2 完整的mongodb高可用可扩展架构

Shards:存储数据,通过replica sets提供高可用和数据持久性。

Query Routers:当数据库服务器mongod很多时,推荐增加Router来分发大量的客户请求。Mongos是一个轻量级的进程不需要数据目录,

Config servers:存储集群元数据,包含集群数据集与各个片区的映射,在3.2版后支持将config-servers部署为replica set,避免单点故障,不再推荐原有的三镜像形式的配置服务器实例。

MongoDb 通过shard key对数据进行分区,系统默认使用range based partition或hash based partition。前者通过区间分布,因而相近数据分布较近,范围查询的效率更高,于此同时由于分布不均匀,当请求集中在其中一台服务器时,将出现过量 负载;后者通过hash函数分布,分布比较分散,负载均匀,但对于范围查找相对较慢。

系 统提供后台运行的splitting功能,当Shard不断增大超过阀值,系统将会把它分成等量的两部分。后台balancing进程管理chunk的迁 移,当负载均衡器发现某个shard中chunk过多时,会将部分chunk转移到chunk数最少的服务器,值得一提的是,只有在源shard的 chunk迁移到目的shard后,才会删除源上的chunk,因此在迁移过程中出现问题并不会导致数据丢失。

 

在Windows上详细构建步骤可参照博友左盐的博文http://www.cnblogs.com/spnt/archive/2012/07/26/2610070.html,以及博友Geek_Ma的博文http://www.cnblogs.com/geekma/archive/2013/05/16/3081532.html。

 

  • 基础查询

有 几点需要注意:不需要预先创建集合,在第一次插入数据时会自动创建;文档中可以存储任意类型数据,不需要类似alter table的语句来改变结构;每次插入时都有一个_id,类型为OBjectId,其实就是GUID了,便于分布式环境下的唯一标示,当然它也可以是 int或long等类型。

操作类别实例备注
插入j={name, "bibi"};t={x : 3};db.things.save(j); db.things.save(t);db.things.find();
  1. 不需要预先创建集合
  2. 文档中可以存储任何结构的数据
  3. 每次插入时默认添加一个_id字段
  4. 该操作等价于insert()操作
选择数据库Use test
  1. 默认使用test
修改Db.things.update({name,"mongo"}, {$set:{name:"mongo_new"}});  
删除Db.things.remove({name:"mongo_new"});  
普通查询var cursor = db.things.find();while(cursor.hasNext()) printjson(cursor.next());获得游标,遍历游标。注意在数据集合很大时可能会引起内存溢出
  Db.things.find().forEach(printjson)  
  Var arr = db.things.find().toArray();Arr[5];  
条件查询Db.things.find({x:4}, {j:true}).forEach(printjson);  
FindOnePrintjson(db.things.findOne({name:"mongo"}));  
limitDb.things.find().limit(3);  

   

  • 高级查询
操作符实例备注
条件操作符Db.collection.find({"field":{$gt:value}});Db.collection.find({"field":{$lt:value}});Db collection.find({"field":{$gte:value}});Db.collection.find({"field":{$lte:value}});Field>valueField<valueField>=valueField<=value
$allDb.users.find({age:{$all:[6, 8]}});必须满足[]内所有值
$existsDb.things.find({age:{$exists:true}});Db.things.find({age:{$exists:false}});查询存在age字段的记录查询不存在age字段的记录
Null值的处理Db.collection.find(age:null)}Db.collection.find(age:{$in:[null], $exists:true})}这儿要注意,在只用null作为判断条件是,还会把不存在age字段的记录找出来
$modDb.collection.find({age:{$mod:[10, 1]}})取模运算
$neDb.things.find({x:{$ne:3}});不等于
$inDb.users.find({age:{$in:[2,4,6]}});包含
$ninDb.users.find({age:{$nin:[1,3]}})不包含
$size{name:'bibi', age:26, luck_number:[3,7,9]},db.users.find({luck_number:{$size: 3}})数组元素个数
正则表达式匹配Db.users.find({name:{$not:/^B.*/}});查询不匹配name=B*带头的记录
Javascript查询和$where查询Db.collection.find({a:{$gt:3}});Db.collection.find($where:"this.a>3");Db.collection.find(this.a>3");f=function(){return this.a>3}db.collection.find(f);查询a大于3的数据
countDb.users.find().count();Db.user.find().skip(10).limit(5).count();Db.user.find().skip(10).limit(5).count(true);查询记录条数还是返回的所有记录数加true也能限制数量
SkipDb.users.find().skip(3).limit(5)相当于limit(3, 5)
sortDb.colletion.find().sort({age:1});Db.colletion.find().sort({age:-1});按升序进行排序按降序进行排序
游标For(var c = db.t3.find();c.hasNext();){Printjson(c.next());}Db.t3.find().forEach(function(u){printjson(u);});  

   

  • 统计Map/Reduce

Map/Reduce 这个概念已经存在了很多年,记得有个印度工程时通过做不同口味的番茄酱的理解风趣幽默的为妻子解释了这个概念,主体的意思就是分工然后汇总。在这里 Map/Reduce相当于MySQL中的"group by",使用过程需要实现Map函数和Reduce函数。

函数名实例备注
前提条件Db.students.insert({classid:1, age:14, name:'Tom'})Db.students.insert({classid:2, age:27, name:'Bibi'})插入班级1,2共8条记录.
Mapm=function(){emit(this.classid, 1)}Map函数必须调用emit(key, value)返回键值对,使用this访问当前待处理的Document.相当于SQL的分组操作,其中的this.classid分组属性,1是用于聚合的属性或值
Reducer=function(key, value){var x =0;values.forEach(function(v){x+=v});return x;}Reduce函数接受的参数类似Group效果,将Map返回的键值序列组合成{key, [value1, value2, value3..]}传递给reduce. 相当于SQL的聚合操作,这儿的x+=v实际就是SQL中的count(*)
ResultRes=db.runcommand({mapreduce:"students",map:m,reduce:r,out:"student_res"});相当于分组聚合操作的执行,并将结果集输出到指定的Collection获得结果:{"_id": 1, "value":3}
finalizeF=function(key, value){return {classid:key, count:value};} Res=db.runcommand({…(同上)finalize:f});利用finalize()我们可以对reduce()的结果做进一步的处理。结果变为如下形式:{"classid": 1, "count":3}。类似于SQL中的取别名格式化输出等操作。
optionsRes=db.runcommand({…(同上)Query:{age:{$lt:10}}});可选项,例如过滤操作,只取age<10的数据。相当于where操作,注意不是having。

   

  • 索引

MongoDB提供了多样性的索引支持,索引信息被保存在system.indexes中,且默认总是为_id创建的索引。

操作符实例备注
基础索引Db.t3.ensureIndex({age:1});Db.t3.getIndexes();按升序排序的索引。注意,1表示升序,-1表示降序查看有哪些索引,默认情况下,_id为创建表时自动创建的索引
  Db.t3.ensureIndex({age:1}, {background:true});当系统已有大量数据时,创建索引非常耗时,我们可以在后台执行
文档索引Db.factories.insert({name:"SORY", addr:{city:"Shanghai", state:"China"}});Db.factories.ensureIndex({addr:1});索引可以是任何类型的字段,甚至文档。注意索引建立的顺序,这点和关系型数据库一样,错误的select顺序可能造成不触发索引
组合索引Db.factories.ensureIndex({"addr.city":1, "addr.state":1});  
唯一索引Db.users.ensureIndex({firstname:1, lastname:1}, {unique:true});注意,如果建立索引所选字段的既有值有重复的,是无法建立唯一索引的。
强制使用索引Db.t5.find({age:{&lt: 30}}).hint(name:1, age:1).explain(); 通过执行计划查看,SQL Server中也有相似的概念,强制走索引
删除索引Db.t1.dropIndexesDb.t1.dropIndex({firstname:1})删除t3表的所有索引删除指定索引

 

Tip:

博文主要供个人基础学习使用,若有疏漏,忘见谅。文中部分图片来之于mongodb官网https://docs.mongodb.org/manual/。

参考资料:

  1. 皮雄军. NoSQL数据库技术实战[M]. 北京:清华大学出版社, 2015.

转载于:https://www.cnblogs.com/zhangyubao/p/7008802.html

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

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

相关文章

java断点续传插件_视频断点续传+java视频

之前仿造uploadify写了一个HTML5版的文件上传插件&#xff0c;没看过的朋友可以点此先看一下~得到了不少朋友的好评&#xff0c;我自己也用在了项目中&#xff0c;不论是用户头像上传&#xff0c;还是各种媒体文件的上传&#xff0c;以及各种个性的业务需求&#xff0c;都能得到…

tomcat中设置Java 客户端程序的http(https)访问代理

1、假定http/https代理服务器为 127.0.0.1 端口为8118 2、在tomcat/bin/catalina.sh脚本文件中设置JAVA_OPTS&#xff0c;如下图&#xff1a; 保存后重启tomcat就能生效。转载于:https://www.cnblogs.com/zhangmingcheng/p/11211776.html

MQTT服务器搭建--Mosquitto用户名密码配置

前言&#xff1a; 基于Mosquitto服务器已经搭建成功&#xff0c;大部分都是采用默认的是允许匿名用户登录模式&#xff0c;正式上线的系统需要进行用户认证。 1.用户参数说明 Mosquitto服务器的配置文件为/etc/mosquitto/mosquitto.conf&#xff0c;关于用户认证的方式和读取的…

压缩/批量压缩/合并js文件

写在前面 如果文件少的话&#xff0c;直接去网站转化一下就行。 http://tool.oschina.net/jscompress?type3 1.压缩单个js文件 cnpm install uglify-js -g 安装 1>压缩单个js文件打开cmd,目录引到当前文件夹&#xff0c;cduglifyjs inet.js -o inet-min.js 或者 uglifyjs i…

软件安装(JDK+MySQL+TOMCAT)

一&#xff0c;JDK安装 1&#xff0c;查看当前Linux系统是否已经安装了JDK 输入 rpm -qa | grep java 如果有&#xff1a; 卸载两个openJDK&#xff0c;输入rpm -e --nodeps 要卸载的软件 2&#xff0c;上传JDK到Linux 3&#xff0c;安装jdk运行需要的插件yum install gl…

TensorFlow 2.X中的动手NLP深度学习模型准备

简介&#xff1a;为什么我写这篇文章 (Intro: why I wrote this post) Many state-of-the-art results in NLP problems are achieved by using DL (deep learning), and probably you want to use deep learning style to solve NLP problems as well. While there are a lot …

静态代码块

静态代码块 静态代码块&#xff1a;定义在成员位置&#xff0c;使用static修饰的代码块{ }。位置&#xff1a;类中方法外。执行&#xff1a;随着类的加载而执行且执行一次&#xff0c;优先于main方法和构造方法的执行。格式&#xff1a;作用&#xff1a; 给类变量进行初始化赋值…

学java 的要点_零基础学Java,掌握Java的基础要点

对于程序员群体来说&#xff0c;了解一定的技巧会对学习专业技能更有帮助&#xff0c;也更有助于在自己的职业发展中处于有利地位&#xff0c;无限互联Java培训专家今天就为大家总结Java程序员入门时需要掌握的基础要点&#xff1a;掌握静态方法和属性静态方法和属性用于描述某…

实验人员考评指标_了解实验指标

实验人员考评指标In the first part of my series on experimental design Thinking About Experimental Design, we covered the foundations of an experiment: the goals, the conditions, and the metrics. In this post, we will move away from the initial experimental…

核心技术java基础_JAVA核心技术I---JAVA基础知识(集合set)

一&#xff1a;集合了解(一)确定性&#xff0c;互异性&#xff0c;无序性确定性&#xff1a;对任意对象都能判定其是否属于某一个集合互异性&#xff1a;集合内每个元素都是无差异的&#xff0c;注意是内容差异无序性&#xff1a;集合内的顺序无关(二)集合接口HashSet&#xff…

nba数据库统计_NBA板块的价值-从统计学上讲

nba数据库统计The idea is not to block every shot. The idea is to make your opponent believe that you might block every shot. — Bill Russel这个想法不是要阻止每一个镜头。 这个想法是让你的对手相信你可能会阻挡每一个投篮。 —比尔罗素 The block in basketball ha…

【炼数成金 NOSQL引航 三】 Redis使用场景与案例分析

验证redis的主从复制&#xff0c;将实验过程抓图 复制配置文件 更改slave的端口 和相关master配置 主从复制测试 研究在OAuth中的“一次数”nonce有什么用途&#xff1f;怎样使用&#xff1f;以此熟悉OAuth的全流程 nonce &#xff0c;一个随机的混淆字符串&#xff0c;仅仅被…

js建立excel表格_建立Excel足球联赛表格-传统vs动态数组方法

js建立excel表格介绍 (Introduction) I am going to show you the different ways you can build a football league table in Excel. Some of the methods are old school but others utilise Excel’s new capabilities.我将向您展示在Excel中建立足球联赛表格的不同方法。 其…

postman+newman生成html报告

作为测试菜鸟,在学习postmannewman的使用过程中真的是颇费周折......没办法技术太菜,只能多学习. postman的下载安装不多言说,下载地址:https://www.getpostman.com/downloads/ newman的安装过程: 1.首先需要安装node.js,可以去官网下载,地址:https://nodejs.org/en/#download …

java jdk1.9新特性_JDK1.9-新特性

1. Java平台级模块系统该特性使Java9最大的一个特性&#xff0c;Java提供该功能的主要的动机在于&#xff0c;减少内存的开销&#xff0c;JVM启动的时候&#xff0c;至少会有30~60MB的内存加载&#xff0c;主要原因是JVM需要加载rt.jar&#xff0c;不管其中的类是否被classload…

两个链接合并_如何找到两个链接列表的合并点

两个链接合并了解问题 (Understand the Problem) We are given two singly linked lists and we have to find the point at which they merge.我们给了两个单链表&#xff0c;我们必须找到它们合并的点。 [SLL 1] 1--->3--->5 \ …

安装veket到移动硬盘NTFS分区

如果你已经看过《手动安装veket到硬盘》和《简单的将veket安装到U盘的方法》两篇文章并且安装成功的话&#xff0c;说明不适用本文的安装环境&#xff0c;就不用往下看了。 《手动安装veket到硬盘》一文采用grub4dos来引导硬盘上的veket&#xff0c;主要是用来在本机已安装Wind…

简书使用小技巧

1、不同字体  在 设置->基础设置->富文本 模式下可以实现 2、添加图片&#xff0c;让文章更生动 3、添加代码框 &#xff01;注意&#xff1a;设置为Markdown模式后&#xff0c;只对新创建的文章起作用。转载于:https://www.cnblogs.com/HMJ-29/p/7049540.html

杭电2064

此题是一道简单的递归 此题是一道递归运算题&#xff0c;这题又是一道汉诺塔问题&#xff01;&#xff01;&#xff01;只要了解其规律&#xff0c;呵呵&#xff0c;你就可以很快AC了&#xff01;&#xff01; 这是一般的汉诺塔问题的解题方法照片&#xff01;&#xff01;&…

阻塞队列实现

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 阻塞队列 1. 什么是阻塞队列2. 标准库中的…