消息中间件

一、简介

消息中间件就是在消息的传输过程中保存消息的容器。消息中间件再将消息从它的源中继到它的目标时充当中间人的作用。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功的传递它为止,当然,消息队列保存消息也是有期限点的。

二、消息中间件特点

1、采用异步处理模式

消息发送者可以发送一个消息而无须等待响应。消息发送者将消息发送到一条虚拟的通道(主题或队列)上,消息接受者则订阅或是监听该通道。一条消息可能最终转发给一个或多个消息接受者,这些接受者都无须对消息发送者做出同步回应。整个过程是异步的。比如用户消息注册,注册完毕后过段时间发送邮件或者短息

2、应用程序和应用程序调用关系为松耦合关系

发送者和接受者不必了解对方、只需要确认消息

发送者和接受者不必同时在线

比如在线交易系统为了保证数据的最终一致,在支付系统处理完成后会把支付结果放到消息中间件里通过订单系统修改订单支付状态。两个系统通过 消息中间件解耦

三、消息传递服务模型:

四、消息中间件的传输模式

1、点对点模型

点对点模型用于消息生产者和消息消费者之间点到点的通信。消息生产者将消息发送到由某个名字标识的特定消费者。这个名字实际上对于消费服务中的一个队列(Queue),在消息传递给消费者之前它被存储在这个队列中。队列消息可以放在内存中也可以是持久的,以保证在消息服务出现故障时仍然能够传递消息。

传统的点对点消息中间件通常由消息队列服务、消息传递服务、消息队列和消息应用程序接口API组成,其典型的结构如下图所示。

特点:

a、每个消息只用一个消费者

b、发送者和接受者没有时间依赖

c、接受者确认消息接受和处理成功

2、发布-订阅模型(Pub/Sub)

发布者/订阅者模型支持向一个特定的消息主题生产消息。0或多个订阅者可能对接收来自特定消息主题的消息感兴趣。在这种模型下,发布者和订阅者彼此不知道对方。这种模式就好比是匿名公告板。这种模式被概况为:多个消费者可以获得消息,在发布者和订阅者之间存在时间依赖性。发布者需要建立一个订阅(subscription),以便能够消费者订阅。订阅者必须保持持续的活动状态及接收消息,除非订阅者建立了持久的订阅。在这种情况下,在订阅者未连接时发布的消息将在订阅者重新连接时重新发布。

 发布订阅模型特性

1)每个消息有多个订阅者
2)客户端只有订阅后才能接受到消息
如下图,当有消息更新后会同时更新订阅者,并且一个消息会有多个订阅者,如下图:

3)持久订阅和非持久订阅
如下图,如果此时持久订阅出现故障,在故障后重启则会重新发送一次消息,如果非持久订阅则不会,消息则错过,如下图:

消费者订阅后,中间件会投递给消费者,消费者确认后在返回给中间件,如下图:

发布者和订阅者是存在时间以来的,当接受者和发布者只有建立订阅关系才能收到消息。当订阅关系建立后,消息就不会丢失,不管订阅者是否都在线。
当订阅者接受了消息,必须一直在线,当只有一个订阅者时约等于点对点模式,如一个消息中间件分为多个块,如下图:

注意:
(1)发布者和订阅者有时间依赖
接受者和发布者只有建立订阅关系才能收到消息
(2)持久订阅
订阅关系建立后,消息就不会消失,不管订阅者是否都在线
(3)非持久订阅
订阅者为了接受消息,必须一直在线。
当只有一个订阅者时约等于点对点模式

五、消息中间件应用场景

1、用户注册异步处理

用户注册,成功会发生邮件或短信
当正常情况下回发生成功,如果在期间发生网络抖动或者服务意外停止,则可能需要消息超时机制,在或者重试机制,如下图:

以上模式一般是用户注册成功后,写入一条数据到mysql,在发送一条消息到MQ!

如果不用消息中间件(或者简单的做成异步发送),做成了用户提交了注册之后,成功后,就同步立即执行发送邮件和短信服务脚本(这样耗时间),这样用户体验不好时间慢!

术语: SOA

2、日志分析使用

把日志进行集中收集,用于计算PV、用户行为分析

术语:灰度发布,小流量

3、数据复制

(1)将数据从源头复制到多个目的地,一般是要求顺序或者保证因果序列

(2)用于跨机房数据传输、搜索、离线数据计算等。

术语:AOP

4、延迟消息发送和暂存

(1)把消息中间件当成可靠的消息暂存地
(2)定时进行消息投递,比如模拟用户秒杀访问,进行系统性能压测

消费者消费完后不删除消息! 这种压测方式比较真实,比一般的并发压测软件更符合真实环境!

5、消息广播

(1)缓存数据同步更新
(2)往应用推送数据
例如更新本地缓存、变更商品价格

就像很多数据都是缓存在本地的应用中的如tomcat应用,如一个数据价格缓存,当有数据更新的时候,就需要及时(而不是通过租约到期去解决) 这个时候就需要中间件,不是一个一个去通知更新

六、消息中间件分类:

1、(push)推消息模型:

消息生产者将消息发送给消息传递服务,消息传递服务又将消息推送给消息消费者。 --场景:交易,注册

2、(pull)拉消息模型:

消费者请求消息服务接收消息,消息生产者从消息中间件拉该消息。  --场景:行为分析,PV计算

3、两种类型的区别

七、metaq消息中间件(pull)

 1、概述

metaq是一款完全的队列模型消息中间件,服务器使用java语言编写,可在多种软硬件平台上部署。客户端支持java/c++编程语言。单台服务器可支持1万以上各消息队列,通过扩容服务器,队列数几乎可任意横向扩展。每个队列都是持久化,长度无限(取决于磁盘空间大小),并且可从队列任意位置开始消费

官网:http://metaq.taobao.org

2、总体架构

3、metaq特点

1)生产者、服务器和消费者都可分布式

2)消息存储顺序读写

3)性能极高,吞吐量大

4)支持消息顺序

5)客户端pull,随机读,批量拉数据

6)数据迁移,扩容对用户透明

7)消费状态保存在客户端

 4、metaq重要术语

1)topic:消息的主题,可理解为队列名,由用户定义并在中间件配置,producer发送消息到某个topic下,consumer从某个topic下消费消息

2)offset:消息在中间件broker上的每个分区都组织成一个文件列表,consumer拉取数据需要知道数据在文件中的offset,是绝对偏移量,中间件会将offset转化为具体文件的相对偏移量

3)broker:metaq的服务端,在消息中间件中通常称为broker

4)partition:分区,同一个topic下有多个partition,例如meta-test这个topic可分10个partition,分别有两台broker提供,那可能每台broker提供5个partition,若broker id分别为0和1,所有分区为0-0、0-1、0-2、0-3、0-4、1-0、1-1、1-2、1-3、1-4

 5、metaq 主要配置

[zookeeper]
zk.zkEnable=true #是否注册到zk,默认为true
zk.zkConnect=localhost:2181 #zk的服务器列表
zk.zkSessionTimeoutMs=30000 #zk心跳超市,单位毫秒,默认30秒
zk.zkConnection TImeoutMs=30000 #zk链接超时时间,单位毫秒,默认30秒 [system]
brokerld=0 #服务器id,必须唯一,0-1024之间
serverprot=8123 #服务端口
hostName= #默认将取本机IP,如果多机网卡需要指明
dataLogPath= #日志存放路径,默认和datapath一样
datapath= #指定默认数据存储路径

daletepolicy=delete,168
#数据删除策略,默认超过7天则删除,这里是168是小时,10s表示秒,10m表示分钟,10h表示小时,默认为小时

deleteWhen=0 0 6,18 * * ?
#何时执行删除策略的cron表达式,默认是每天6:00和18:00执行

flushTxLogAtCommit=1
#事务日志的同步设置,0表示os决定,1表示每次commit都同步,2表示每隔1s同步一次;此参数严重影响性能,可根据需要的性能和可靠性权衡作出合理选择,建议设为2,有问题最多丢失1s内运行的事务,这个级别对大多数服务是可靠的;最安全的是设为1这将严重影响事务性能;而0的安全级别最低,在安全级别上1>=2>0,而在性能上0>=2>1

unflushthreshold=0
#每隔多少条消息做一次disk sync,强制将更改的数据刷入disk,默认0表示强制每次写入都sync,当为0时服务器会自动启用groupcommit技术, 将多个消息合并成一次sync来提升io性能, 经测试group commit情况下消息发送者的tps没有受到太大影响,但server负载会上升很多;若为1000表示在掉电时最多允许丢失1000条消息

unflushinterval=10000
#间隔多少ms做一次disk sync,默认10s,在掉电时最多丢失10s内发送过来的消息,不可设为0或<0

 6、metaq的集群实现:

所有的broker注册到zookeeper;

客户端连接zookeeper并返回可用的broker列表,选择一个broker发送消息

7、metaq主要命令

1、启动
#./metaServer.sh start &

2、停止
#./metaServer.sh stop

3、重启
#./metaServer.sh restart &

4、重新加载
#./metaServer.sh reload &

5、查看状态
#./metaServer.sh stats

8、安装zookeeper

1、安装Java运行环境(即安装JDK)
rpm -ivh jdk-7u40-linux-x64.rpm


2、配置zookeeper环境
mkdir -p /app/zk1 /app/zk2 /app/zk3
cp zookeeper-3.4.6.tar.gz /app/zk1
cd /app/zk1
tar xf zookeeper-3.4.6.tar.gz
mv zookeeper-3.4.6 zookeeper

3、配置zookeeper
cd zookeeper
mkdir dataDir dataLogDir (dataDir用于存放数据文件,dataLogDir用于存放日志文件)
echo 1 > dataDir/myid
mv conf/zoo_sample.cfg conf/zoo.cfg
vim conf/zoo.cfg
12 dataDir=/app/zk1/zookeeper/dataDir
13 dataLogDir=/app/zk1/zookeeper/dataLogDir
16 server.1=127.0.0.1:8880:7770
17 server.2=127.0.0.1:8881:7771
18 server.3=127.0.0.1:8882:7772
###############################
cd /app/zk1
cp -a zookeeper zk2
cp -a zookeeper zk3
echo 2 > /app/zk2/zookeeper/dataDir/myid
echo 3 > /app/zk3/zookeeper/dataDir/myid
vim /app/zk2/zookeeper/conf/zoo.cfg
12 dataDir=/app/zk2/zookeeper/dataDir
13 dataLogDir=/app/zk2/zookeeper/dataLogDir
15 clientPort=2182
vim /app/zk3/zookeeper/conf/zoo.cfg
12 dataDir=/app/zk3/zookeeper/dataDir
13 dataLogDir=/app/zk3/zookeeper/dataLogDir
15 clientPort=2183
##############################

3、启动zookeeper并验证
./app/zk1/zookeeper/bin/zkServer.sh start
./app/zk2/zookeeper/bin/zkServer.sh start
./app/zk3/zookeeper/bin/zkServer.sh start
验证
./app/zk1/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
./app/zk1/zookeeper/bin/zkCli.sh -server 127.0.0.1:2182
./app/zk1/zookeeper/bin/zkCli.sh -server 127.0.0.1:2183
进入ls 查看,quit退出

9、安装多实例 metaq

1、创建目录
mkdir -p /app/metaq1 /app/metaq2
tar xf metaq-server-1.4.6.2.tar.gz -C /app/metaq1
tar xf metaq-server-1.4.6.2.tar.gz -C /app/metaq1
#######################################

2、配置metaq1
cd /app/metaq1/taobao/metamorphosis-server-wrapper/
vim conf/server.ini #配置文件 [system]
brokerId=0
serverPort=8123
dashboardHttpPort=8120 [zookeeper]
zk.zkConnect=127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183 [topic=xl] #自定义的消息xl的队列
##################################

3、配置metaq2
cd /app/metaq2/taobao/metamorphosis-server-wrapper/
vim conf/server.ini #配置文件 [system]
brokerId=1
serverPort=8124
dashboardHttpPort=8121 [zookeeper]
zk.zkConnect=127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183 [topic=xl] #自定义的消息xl的队列 vim bin/metaServer.sh 启动脚本
PID_FILE="$PID_DIR/.run1.pid" 看环境,可以不做 vim bin/env.sh
export JMX_PORT=9124 默认是9123端口
#################################################

4、启动
./app/metaq1/taobao/metamorphosis-server-wrapper/bin/metaServer.sh start & #实例一
./app/metaq1/taobao/metamorphosis-server-wrapper/bin/metaServer.sh start & #实例二
###################################
5、查看状态
./app/zk1/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181 #登陆
ls /meta/brokers/ids #有两个broker就表面集群部署成功
get /meta/brokers/ids/1

 八、RabbitMQ

1、概述

RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统。他遵循Mozilla Public License开源协议

RabbitMQ是流行的开源消息队列系统,用erlang语言开发

RabbitMQ是AMQP(高级消息队列协议)的标准实现

官网:http://www.rabbitmq.com/

在AMQP协议标准基础上完整的,可复用的企业消息系统,遵循Mozilla Public License开源协议,采用Erlang实现的工业级的消息队列MQ服务器
AMQP高级消息队列协议,是一个一步消息传递所使用的应用层协议规范,作为线路层协议,而不是API,例如JMS,AMQP客户端能够无视消息的来源任意发送和接受信息。AMQP的原始用途只是为金融界提供一个可以彼此协作的消息协议,而现在的目标则是为通用消息队列架构提供通用构建工具。因此,面向消息的中间件MOM系统,例如发布/订阅队列,没有作为基本元素实现,反而通过发送简化的AMQ实体,用户被赋予 了构建这些实体的能力,这些实体也是规范的一部分,形成了在线路层协议顶端的一个层级,AMQP模型,这个模型同意了消息模式,例如之前提到的发布订阅,队列,事务以及流数据,并且添加了额外的特性,例如更易于扩展,基于内容的路由

2、RabbitMQ整体架构,如下图:

3、运行原理图

 RabbitMQ核心组件分别是exchange和queue,如下图:

4、RabbitMQ术语

1)sever(broker):接受客户端连接,实现AMQP消息队列路由功能的进程

2)Virtual Host:其实是一个虚拟概念,类似于权限控制组,一个Virtual Host里面可以有若干个Exchange 和Quece,但是权限控制的最小粒度是Virtual Host

3)Exchang:接受生产者发送的消息,并根据Binding规则江消息路由给服务器中的队列,Exchange Type 决定了Exchange路由消息的行为,例如:在Rabbitmq中,

Exchange Type有direct ,fanout和topic三种,不用类型的exchange路由的行为是不一样的

4)Message Queue:消息队列,用于存储还未被消费者消费的消息

5)Message:由Header和Body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化,由那个Message Queue接受,优先级是多少等,而Body是真正需要传输的APP数据

6)Binding key:所谓绑定就是将一个特定的exchange 和一个特定的queue绑定起来,绑定关键字为bindinkey

5、Exchange分类

 直接式交换器类型

Direct Exchange 直接交互式处理路由键,需要将一个队列绑定到交换机上,需要该消息与一个特定的路由键完全匹配,这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键“dog",则只有被标记为“dog"的消息才被转发,不会转发dog.puppy,也不会转发dog.guard,只会转发dog,如下图:

广播式交换器类型

Fanout Exchange 广播式路由键,只需要简单的将队列绑定到交换机上,一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上,很像子网广播,每台子网内的主机都获得了一份复制的消息,fanout交换机转发消息是最快,如下图:

主题式交换器类型

Topic exchange,主题式交换器,通过消息的路由关键字和绑定关键字的模式匹配,将消息路由到被绑定的队列中,这种路由器类型可以被用来支持经典的发布,订阅消息传输模型,使用主题名字空间作为消息寻址模式,将消息传递给那些部分或者全部匹配主题模式的多个消费者,主题交换机类型的工资方式如下:绑定关键字用零个或多个标记构成,每一个标记之间用"."字符分隔,绑定关键字必须用这种形式明确说明,并支持通配符“”匹配一个词组,“#”零个或多个词组,因此绑定关键字“ *。stock.#" 匹配路由关键字”usd.stock“和”eur.stock.db",但是不匹配“stock.nasdaq”,如下图:

6、rabbitMQ常用配置介绍

一般情况下,rabbitMQ的默认配置就足够了,如果希望特殊配置的话,有2个途径

1)环境变量的配置文件rabbitmq-env.conf

2)配置信息的配置文件rabbitmq.config

注意,这2个文件默认是没有的,如果需要必须自己创建

1)rabbitmq-env.conf这个文件的位置是确定和不能改变的,位于:/etc/rabbitmq目录下,这个目录需要自己创建

rabbitmq_node_ip_address:      #指定ip地址
rabbitmq_node_port: #指定端口号,more5672
rabbitmq_config_file: #配置文件的路径,注意配置文件后缀必须是.config
rabbitmq_log_base: #日志文件路径

2)rabbitmq.config这是一个标准的erlang配置文件,它必须符合erlang配置文件的标准。erlangtuple,结构为{key,value},key为atm类型,value为一个term,其中关键参数为:

tcp_listerners                #设置rabbimq的监听端口,默认为5672
disk_free_limit #磁盘低水位线,若磁盘容量低于指定值则停止接收数据
vm_memory_high_watemark #设置内存低水位线,若低于该水位线,则开启流控机制,默认值是0.4,即内存总量的40%

7、RabbitMQ命令介绍

1、/etc/init.d/rabbitmq-server start | restart | stop | reload     #服务启动、停止
2、rabbitmqctl add_vhost vhostname #创建虚拟主机
3、rabbitmqctl delete_vhost vhostname #删除虚拟主机
4、rabbitmqctl list_vhosts #遍历所有虚拟主机信息
5、rabbitmqctl add_user username password #添加用户
6、rabbitmqctl change_password username password #修改用户密码
7、rabbitmqctl set_user_tags username administrator #设置username的角色(administrator)
8、rabbitmqctl set_permissions -p vhost user ".*" ".*" ".*" #绑定权限,并且具备读写的权限
9、rabbitmqctl list_queues #显示所有队列

8、RabbitMQ安装

1、yum安装
yum install -y rabbitmq-server

2、安装插件
/usr/lib/rabbitmq/bin/rabbitmq-plugins list #列出所有的插件
/usr/lib/rabbitmq/bin/rabbitmq-plugins enable rabbitmq_management #启用web监控插件

3、启动
/etc/init.d/rabbitmq-server restart

4、验证
netstat -lnt |grep 15672
ps -ef |grep rabbit

5、配置
默认不需要配置,如果有需要/etc/rabbitmq/ 下可以创建

6、实例
rabbitmqctl add_vhost test #新添加vhost;/为默认就有t
rabbitmqctl list_vhosts #查看所有虚拟主机信息
rabbutmqctl list_users #查看用户列表
rabbitmqctl add_user admin admin #添加用户及密码
rabbitmqctl set_permissions -p test admin ".*" ".*" ".*" #绑定权限,并且具备读写的权限
rabbitmqctl list_queues #显示队列
rabbitmqctl list_user_permissions admin #查看用户权限
/etc/init.d/rabbitmq-server restart #一定要restart

 9、web管理连接

http://127.0.0.1:15672/
用户和密码:guest/guest

10、python程序模拟生产者

参考官网:http://www.rabbitmq.com/tutorials/tutorial-one-python.html

来自最简单的模型P-mq--C

cat send.py

#!/usr/bin/env python
#encoding==utf-8
#http://cuidehua.blog.51cto.com
#from http://www.rabbitmq.com/tutorials/tutorial-one-python.html
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()

模拟发送100条消息到queue=hello的这个列队中

for i in {1..100};do python send.py ;done

命令查看队列:(不指定vhost 列队在默认的vhost "/"中)

rabbitmqctl  list_queues  -p   "/"

web端查看

11、python程序模拟消费者进行消费

cat receive.py

#!/usr/bin/env python
#encoding=utf-8
#http://cuidehua.blog.51cto.com
#from http://www.rabbitmq.com/tutorials/tutorial-one-python.html import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.queue_declare(queue='hello') #定义回调函数
def callback(ch, method, properties, body):
print(" [x] Received %r" % body) channel.basic_consume(callback,
queue='hello',
no_ack=True) print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

执行消费,并等待messages! 直到ctrl+c 终止

python receive.py

再次查看队列

rabbitmqctl list_queues -p "/"

12、常见问题:

服务起不来? 报错:Error: unable to connect to node  rabbit@stu:  nodedown

原因是不能解析 本主机,原因是 默认作为解析的节点和 本机的hostname -s 结果一致

只要把hostname -s的结果, 加入到/etc/hosts中即可

学习RabbitMQ(一)的更多相关文章

  1. 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

    在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...

  2. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

  3. 【Todo】MQ学习-RabbitMQ, ActiveMQ, Kafka等

    之前学习过RabbitMQ,并且还安装过.安装记录的文章如下: Erlang:http://www.cnblogs.com/charlesblc/p/5512380.html RabbitMQ:htt ...

  4. 跟着小菜学习RabbitMQ启动和基础(系列一)

    前言 今天开始我们正式进入RabbitMQ系列学习,在这系列博客中也会发表.NET Core和EF Core文章,网上关于RabbitMQ例子比比皆是,我将综合网上所提供的信息并加上我个人的理解来详细 ...

  5. AMQP学习 & RabbitMQ 与 ActiveMQ、ZeroMQ以及Kafka的比较

    之前写了一篇文章关于Active以及消息队列推拉模式的文章,可以参考:link 关于 Active 与 RabbitMQ以及其他的比较,有如下记录: 这篇文章 link 提到: 基本介绍RabbitM ...

  6. MQ学习-RabbitMQ, ActiveMQ, Kafka等

    之前学习过RabbitMQ,并且还安装过.安装记录的文章如下: Erlang:http://www.cnblogs.com/charlesblc/p/5512380.html RabbitMQ:htt ...

  7. 官网英文版学习——RabbitMQ学习笔记(八)Remote procedure call (RPC)

    在第四篇学习笔记中,我们学习了如何使用工作队列在多个工作者之间分配耗时的任务.   但是,如果我们需要在远程计算机上运行一个函数并等待结果呢?这是另一回事.这种模式通常称为远程过程调用或RPC.   ...

  8. 官网英文版学习——RabbitMQ学习笔记(七)Topic

    在上一篇中使用直接交换器改进了我们的系统,使得它能够有选择的进行接收消息,但它仍然有局限性——它不能基于多个条件进行路由.本节我们就进行能够基于多个条件进行路由的topics exchange学习. ...

  9. 官网英文版学习——RabbitMQ学习笔记(五)Publish/Subscribe

    发布/订阅模式:把一个消息发送给多个消费者. 前几篇文章的思想是,我们好像看到了生产者将消息直接发送给queue,然后消费者也从queue中进行消费.其实并非如此,RabbitMQ中的消息传递模型的核 ...

  10. 官网英文版学习——RabbitMQ学习笔记(四)Work queues

    工作队列:把每个任务只发送给一个工作者. 上一篇我们是从一个指定的队列发送接收消息,在本文中,我们将创建一个工作队列,用于在多个工作者之间分配耗时的任务. 工作队列(即任务队列)背后的主要思想是避免立 ...

随机推荐

  1. 每日一算法之two sum

    题目如下:首先准备一个数组,[1,2,8,4,9]  然后输入一个6,找出数组两项之和为6的两个下标. 啥也不想,马上上代码,这个太简单了, static int[] twoSum(int[] num ...

  2. Weblogic 升级更新补丁操作步骤

    转至:https://blog.csdn.net/allway2/article/details/91424413 Weblogic 升级更新补丁操作步骤: 1.上传补丁包2.kill weblogi ...

  3. Qt:QSqlDatabase

    0.说明 QSqlDatabase类处理与数据库连接相关的操作.一个QSqlDatabase实例就代表了一个连接,连接时要提供访问数据库的driver,driver继承自QSqlDriver. 通过静 ...

  4. Java:代码改进技巧

    1.类名首字母大写:方法名首字母小写:常量名全大写: 2.当控制语句只有一句时,可以省略大括号{}:但是,建议任何时候都保留大括号,因为这是Java语句块的标志 3.用某个接口承接实现类时(多态),之 ...

  5. Vue中组件的递归

    先来说下需求,就是一个表单,会有树形结构一样,会有子表单,表单显示什么内容是后台通过接口数据来确定的:这个时候就和树形结构一样,肯定会有子组件的递归:这次是自己第一次写递归,遇到了三个问题记录下: 1 ...

  6. 矩池云上如何修改cudnn版本

    修改与之前修改nvcc.cuda这些的原理是一样的. 国内镜像 https://mirrors.cloud.tencent.com/nvidia-machine-learning/ 检查系统版本 so ...

  7. go RWMutex 的实现

    Overview go 里面的 rwlock 是 write preferred 的,可以避免写锁饥饿. 读锁和写锁按照先来后到的规则持有锁,一旦有协程持有了写锁,后面的协程只能在写锁被释放后才能得到 ...

  8. Redis环境搭建-Linux单机

    一.准备Linux 可以买云服务器,也可以用虚拟机,我用的是虚拟机Oracle VM VirtualBox 二.编译环境 1.检查linux下是否安装环境 yum list installed | g ...

  9. 【一】TSP、VRP、VRP模型介绍

    一. TSP问题数学模型 编辑 TSP,即Traveling Salesman Problem,也就是旅行商问题,又译为旅行推销员问题.货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求 ...

  10. 面试官:Java中对象都存放在堆中吗?你知道逃逸分析?

    面试官:Java虚拟机的内存分为哪几个区域? 我(微笑着):程序计数器.虚拟机栈.本地方法栈.堆.方法区 面试官:对象一般存放在哪个区域? 我:堆. 面试官:对象都存放在堆中吗? 我:是的. 面试官: ...