final代码实践package com.thinkingjava.chapter8; class People{ private Double a; People(Double a){ this.a = a; } public Double getA() { return a; } } public class Theeg1 { private final Double j = 0.000; private final People p; public Theeg1(Double x){ // j = x; p = new People(x); System.out.println(p.getA()); System.out.println("this is " + x + " million US dollars for the car"); } public static void main(String[] args) { Theeg1 d = new Theeg1(23.00); System.out.println(d.toString()); } @Override public String toString() { Theeg1 f = new Theeg1(24.00); return null; } } 结果:23.0 this is 23.0 million US dollars for the car 24.0 this is 24.0 million US dollars for the car null Java写程序提高代码质量教程写程序提高代码质量1、提高运行效率这是最重要的目的利用if else减少要进行对同一张多表做相同工作的事如一个插入功能不要写成先插入后查询,能一步解决一步OK另一方面运行效率也体现在sql方面,往往优化sql语句可以很大程度提高运行效率 @Override public Boolean updateBrandHotConfig(AdminJoinBrandHotConfigUpdateReq updateReq) { String brandCode = updateReq.getBrandCode(); //检查brandCode在join_brand_hot_config中是否存在 JoinBrandHotConfigResp byBrandCode = joinBrandHotConfigMapper.getByBrandCode(brandCode); //如果不存在,则插入 if (null == byBrandCode) { JoinBrandHotConfig hotConfig = getJoinBrandHotConfig(updateReq); hotConfig.setType(BrandHotConstant.BRAND_HOT_CONFIG_TYPE_REMEN); hotConfig.setGmtCreate(DateUtils.getNow()); hotConfig.setStatus(BrandHotConstant.JOIN_BRAND_HOT_CONFIG_STATUS_DEF); hotConfig.setSort(BrandHotConstant.JOIN_BRAND_HOT_CONFIG_SORT_DEF); hotConfig.setIndex(BrandHotConstant.JOIN_BRAND_HOT_CONFIG_INDEX_DEF); joinBrandHotConfigMapper.addBrandHotConfig(hotConfig); } else { //如果存在,则更新 JoinBrandHotConfig hotConfig = getJoinBrandHotConfig(updateReq); joinBrandHotConfigMapper.updateBrandHotConfig(hotConfig); } return true; } private JoinBrandHotConfig getJoinBrandHotConfig(AdminJoinBrandHotConfigUpdateReq updateReq) { JoinBrandHotConfig hotConfig = new JoinBrandHotConfig(); hotConfig.setBrandCode(updateReq.getBrandCode()); hotConfig.setShowStartTime(updateReq.getShowStartTime()); hotConfig.setShowEndTime(updateReq.getShowEndTime()); hotConfig.setBrandLogo(updateReq.getBrandLogo()); hotConfig.setGmtModified(DateUtils.getNow()); return hotConfig; } 2、提高代码可读性前提是公共接口不要影响代码运行那么可以抽出相同的方法进行封装,一般这样的方法只维护相同属性,而不会去做很大变化。命名规范。整洁性,不要把两件事的步骤重合在一起,东一下,西一下最后,向规范致敬,学习规范,如果没有合适的规范代码,可以参考阿里巴巴规范代码,这样可以提高代码可读性,不关是要别人看得懂你的代码,一段时间后,你要迅速看懂你以前写的代码常量好用BrandHotConstant.JOIN_BRAND_HOT_CONFIG_SORT_DEF public interface BrandHotConstant { int JOIN_BRAND_HOT_CONFIG_SORT_DEF = 0; } 传多个参数的时候,可以用对象进行封装 JoinBrandHotConfig hotConfig = getJoinBrandHotConfig(updateReq); hotConfig.setType(BrandHotConstant.BRAND_HOT_CONFIG_TYPE_REMEN); hotConfig.setGmtCreate(DateUtils.getNow()); hotConfig.setStatus(BrandHotConstant.JOIN_BRAND_HOT_CONFIG_STATUS_DEF); hotConfig.setSort(BrandHotConstant.JOIN_BRAND_HOT_CONFIG_SORT_DEF); hotConfig.setIndex(BrandHotConstant.JOIN_BRAND_HOT_CONFIG_INDEX_DEF); joinBrandHotConfigMapper.addBrandHotConfig(hotConfig); 代码规范 @Override public Boolean setSort(String brandCode, Integer sort) { Date gmtModified = DateUtils.getNow(); log.info("修改排序 brandCode:{}, sort:{}, gmtModified:{}", brandCode, sort, gmtModified); JoinBrandHotConfigResp byBrandCode = joinBrandHotConfigMapper.getByBrandCode(brandCode); //如果不存在,则插入 if (null == byBrandCode) { JoinBrandHotConfig hotConfig = getJoinBrandHotConfig(brandCode); hotConfig.setIndex(BrandHotConstant.JOIN_BRAND_HOT_CONFIG_INDEX_DEF); hotConfig.setStatus(BrandHotConstant.JOIN_BRAND_HOT_CONFIG_STATUS_DEF); hotConfig.setSort(sort); joinBrandHotConfigMapper.addBrandHotConfig(hotConfig); } else { //如果存在,则更新 //排序 joinBrandHotConfigMapper.setSort(brandCode, sort, gmtModified); } return true; } 3、代码严谨,思路逻辑有序并且清晰需要进行各种空判断,考虑多种情况if 。。。。else考虑可能发生的错误少写全局变量,不能简单为了方便使用全局变量,多个方法调用,可能导致影响值结果的后果请求参数和实体类分开来写,看似啰嗦,实则严谨,可维护性高 private JoinBrandHotConfig getJoinBrandHotConfig(AdminJoinBrandHotConfigUpdateReq updateReq) {} 4、坚持,你一定可以提高代码质量每天进步IO流IO流1、File能对文件和目录进行增删改查,但不能访问文件内容本身所以要用到输入/输出流的这个概念。、File部分常用的方法public String getAbsolutePath() 获取绝对路径public String getParent () 获取上层文件目录路径public boolean renameTo(File dest) 把文件重命名给指定的路径public boolean isDirectory() 判断是否为文件目录public boolean isFile() 判断是否是文件public boolean exists() 判断是否存在public boolean createNewFile 创建文件public boolean mkdirs() 创建文件目录public boolean delete() 删除文件或者文件夹/2、2、java IO原理I/O-----》Input/Output—》处理设备之间的数据传输输入Input 读取外部数据(磁盘等)到内存中输出Output 将程序(内存)数据输出到磁盘等存储设备3、流的分类数据单位=========字节流,字符流流向=============输入流,输出流角色========节点流,处理流节点流:之间从数据源或者目的地读写数据处理流:不直接连接到输急眼或者目的地,而是“连接”在已存 在的流(节点流或处理流)之上,通过对数据的处理为程序提 供更为强大的读写功能。4、抽象基类 节点流(文件流) 缓冲流字节流InputStream FileInputStream BufferedInputStreamOutputStream FileOutputStream BufferedOutputStream字符流Reader FileReader BufferedReaderWriter FileWriter BuffereWriter5、对象的序列化允许吧内存的Java对象转换成平台无关的二进制,从而允许把这种二进制保存在磁盘上。堆、栈、方法区(3.0)0、上面比较形象可以看出堆、栈、方法区之间的区别,栈存的是局部变量、堆一般是对象等等,而方法区存在的事一些信息加载出来等等,他们互相分工。1、String a=new String(“fdsdfs”);堆 存放的是new出来的对象 jvm中只有一个堆区 被所有的线程共享栈 是变量a 每个栈中的数据私有的 其他栈不能访问。栈中分配的是基本类型和自定义对象的引用。方法区 是“fdsdfs”;被所有的线程共享,方法区包含所有的class static变量。方法区存放的是类信息和static变量。2、也可以这么理解:堆是用来存放对象的,栈是用来运行程序的。堆:java的垃圾回收器会自动的回收这些不用的数据。缺点是由于要动态的分配内存,存储效率会比较的慢。栈:栈的优势是存取效率比较快,仅次于寄存器,栈数据可以共享。但缺点是栈中的数据大小和生存期的固定的,缺乏灵活性。3、堆和栈的区别可以用如下的比喻来看出:(来自csdn/weixin_41254254)使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。final代码实践2package com.thinkingjava.chapter8; class Post{ public final void writecode(){ System.out.println("I am writing code"); } } final class FinalClass{ int c1 = 1; void f3(){ System.out.println("hi,this if FinalClass-f3 " + c1); } } public class Finalall { void IParameter(final Post a){ // a = new Post(); a.writecode(); } public static void main(String[] args) { Post b = new Post(); b.writecode(); FinalClass b2 = new FinalClass(); b2.f3(); b2.c1 = 10; b2.f3(); } } 结果I am writing code hi,this if FinalClass-f3 1 hi,this if FinalClass-f3 10 throw和throws的区别class Student{ private int id; public void dognji(int id) throws java.lang.Exception{ if(id > 0){ this.id = id; }else{ throw new java.lang.Exception("你的输入非法"); } } } throws与throw都是异常处理这块内容的,再来回顾一下异常处理的好处,异常处理是对可能发生的异常进行预测处理,以防止程序因为异常的原因无法进行下面的功能或者说卡在异常处理这块try…catch是捕捉异常,而throws与throw是抛出异常,throw是语句抛出一个异常。throws是方法可能抛出异常的声明。JavaScript中对象的方法被访问 <body> <p id="demo"></p> <p id="demo2"></p> <script> var username = { id : 1, name : "xiaoming", age : 18, mymethod : function(){ return this.id + " " + this.name + " " + this.age; }, zhognhua : function () { return this.id; } }; document.getElementById("demo").innerHTML = username.mymethod(); document.getElementById("demo2").innerHTML = username.zhognhua(); </script> </body> 结果 1 xiaoming 18 1 结果 1 xiaoming 18 1
同步调用优点:时效性强,打电话、直播,很快可以得到结果同步调用的问题:耦合度高性能和吞吐能力差有额外的资源消耗有级联失败的问题异步:对高并发有要求的功能使用异步优点:耦合度低性能和吞吐能力高流量削峰(对秒杀来说很重要)故障隔离缺点:异步时效性没有同步好依赖于Broker可靠性、安全性等要求高·1—————》Broker—>mq消息队列架构明显变复杂了场景:双11是购物狂节,用户下单后,订单系统需要通知库存系统,传统的做法就是订单系统调用库存系统的接口订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下但成功。库存系统:订阅订单的消息,获取下单信息,进行库操作。就算库存系统出现故障,消息列队也能保证消息的可靠投递,不会导致消息丢失流量削峰 场景:秒杀活动,一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列作用:1,可以控制活动人数,超过此阈值的订单直接丢弃2,可以缓解短时间的高流量压垮应用(应用程序安自己的最大处理能力获取订单)消息队列mq消息-----》以队列的形式存储先进先出异步解耦场景:注册邮件和短信通知在秒杀团队—》高并发 流量削峰总的来说,不管是rocketmq还是rabbitmq,他们应用的场景是1、流量削峰2、日志处理3、应用解耦4、异步处理RocketMQ发送消息和消费消息测试类====================二期实现导入依赖 <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.8.0</version> </dependency> 测试代码package com.example.springbootproject; import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; import org.apache.rocketmq.client.exception.MQClientException; import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.client.producer.SendCallback; import org.apache.rocketmq.client.producer.SendResult; import org.apache.rocketmq.common.message.Message; import org.apache.rocketmq.common.message.MessageExt; import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; import org.apache.rocketmq.remoting.common.RemotingHelper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.List; @SpringBootTest @RunWith(SpringRunner.class) @Slf4j public class mqtest { /** * 生产者 * @throws Exception */ @Test public void test() throws Exception { DefaultMQProducer producer = new DefaultMQProducer("GROUP_DEMO"); producer.setNamesrvAddr("127.0.0.1:9876"); producer.setSendLatencyFaultEnable(true); producer.start(); for (int i = 0; i < 10; i++) { Message msg = new Message("TOPIC_TEST", "TAGE_TEST", ("ROCKETMQ000" + i).getBytes(RemotingHelper.DEFAULT_CHARSET)); //发送核心方法 //同步 SendResult send = producer.send(msg); //异步 producer.send(msg, new SendCallback() { @Override public void onSuccess(SendResult sendResult) { System.out.println("===" + sendResult); } @Override public void onException(Throwable throwable) { System.out.println("e:" + throwable); } }); //单向 producer.sendOneway(msg); System.out.println("send:%s%n" + send); } //producer.shutdown(); } /** * 消费者 * @throws Exception */ @Test public void consume() throws Exception { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group_consumer"); consumer.setNamesrvAddr("127.0.0.1:9876"); //订阅Topic,去消费生产者产生的消息。 consumer.subscribe("TOPIC_TEST", "*");//tag tagA|tagB|tagC consumer.setMessageModel(MessageModel.CLUSTERING); consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext context) { try { for (MessageExt item : list) { String topic = item.getTopic(); String tags = item.getTags(); String msgBody = new String(item.getBody(), "utf-8"); System.out.println("收到消息:topic:" + topic + ",tags:" + tags + ",msg:" + msgBody); } } catch (Exception e) { log.error("e:", e); return ConsumeConcurrentlyStatus.RECONSUME_LATER; } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); //启动消费者 consumer.start(); System.out.println("consumer start"); } } ====================一期实现public class RockMQSendMessageTest { //发送消息 public static void main(String[] args) throws Exception { //1创建消息生产者,并且设置生成组名 DefaultMQProducer producer = new DefaultMQProducer("myproducer-group"); //2为生产者设置NameServer的地址 mq ip:port port可以在本地跑起来mq producer.setNamesrvAddr("......."); //3 启动生产者 producer.start(); //4 构建消息对象,主要设置消息的主题 标签 内容 topic tags 内容 Message message = new Message("myTopic", "myTag", ("Test jfdlfd").getBytes()); //5发送消息 SendResult result = producer.send(message, 1000); System.out.println(result); //6 关闭生产者 producer.shutdown(); } } public class RocketMQReceviceMessageTest { //接收消息 public static void main(String[] args) throws Exception { //1创建消费者,并且为其制定消费者组名 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("myconsumer-group"); //2为消费者设置NameServer的地址ip:port可以在本地跑起来mq consumer.setNamesrvAddr("......."); //3制定消费者订阅的主题和标签 consumer.subscribe("myTopic", "*"); //4设置一个回调函数,并在函数编写接收到消息之后的处理方法 consumer.registerMessageListener(new MessageListenerConcurrently() { //j处理获取到的消息 @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { //消费逻辑 System.out.println("Message====>" + list); //消息成功 return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); //5启动消费者 consumer.start(); System.out.println("启动消费成功"); } }
mybatis 字段与数据库关键字冲突了怎么办如update join_brand_hot setindex = #{top}where id = #{id}这样明显会因为index与索引关键词导致的冲突解决方法一update join_brand_hot set `index` = #{top} where id = #{id} 解决方法二update join_brand_hot h seth.index = #{top}where id = #{id}mybatis传入的参数不能直接干涉到MySQLmybatis传入的参数不能直接干涉到MySQL传入的参数做的if判定只能影响#{}这个传入的值不是对MySQL数据库进行选择所以应该这样写<if test="today != null" > and (show_end_time is null or show_end_time &gt;= #{today}) </if> mybatis for 循环查询输出 select * form user where name in <foreach collection="searchNameForList" item="item" index="index" open="(" separator="," close=")"> #{item} </foreach> 批量更新mybatis plus//条件 UpdateWrapper<MchDataAuthConfigRule> updateWrapper = new UpdateWrapper<>(); updateWrapper.in("id", idList); //更新 MchDataAuthConfigRule rule = new MchDataAuthConfigRule(); rule.setStatus(100); int update = mchDataAuthConfigRuleMapper.update(rule, updateWrapper); log.info("update:{}", update); mybatis常用标签1.if 标签 if标签通常用于WHERE语句、UPDATE语句、INSERT语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值。 2.foreach 标签 foreach标签主要用于构建in条件,可在sql中对集合进行迭代。也常用到批量删除、添加等操作中。 3 choose标签 有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。 MyBatis提供了choose 元素,按顺序判断when中的条件出否成立, 如果有一个成立,则choose结束。当choose中所有when的条件都不满则时, 则执行 otherwise中的sql。类似于Java 的switch 语句,choose为switch, when为case,otherwise则为default。 if是与(and)的关系,而choose是或(or)的关系。 4. where标签 这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。 此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。 5. set 标签 当在update语句中使用if标签时,使用set标签可以将动态的配置set关键字,和剔除追 加到条件末尾的任何不相关的逗号。 6.include标签 sql标签中id属性对应include标签中的refid属性。通过include标签将sql片段 和原sql片段进行拼接成一个完整的sql语句进行执行。 例如: 7.多表联查中: JavaType和ofType都是用来指定对象类型的,但是JavaType是用来指定pojo中属性的类型,而ofType指定的是映射到list集合属性中pojo的类型。 collection、association标签是用于体现关联的。 如一个实体与另一个实体之间是一对多的关系, 那么在一的一方使用 collection 标签,对应多的一方的一个集合, 在多的一方使用association标签对应一的一方的一个实体
git gitee github等系列提交备注规范,提交规范(实用)<新功能|bug修复|文档改动|格式化|重构|测试代码>: (影响范围) <主题> # 解释为什么要做这些改动?issue #?一、type 类型type 包含以下几种:【统一全部变成小写】增加了这些feat、feature : 新增 feature 新功能fix: 修复 bugdocs: 仅仅修改了文档,比如 README, CHANGELOG, CONTRIBUTE等等style: 仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑refactor: 代码重构,没有加新功能或者修复 bugperf: 优化相关,比如提升性能、体验test: 测试用例,包括单元测试、集成测试等chore: 改变构建流程、或者增加依赖库、工具等revert: 回滚到上一个版本 撤销上一次的commitadd:新功能update:更新del:移除文件build:构建工具或构建过程的变动,如:webpack升级、gulp替换为webpack等二、description 描述影响范围(可选)用于说明此次提交影响到的范围,如数据层、控制层、视图层等。主题用于本次提交的主题简短说明,可含主要模块的相关说明。issue(可选)所关联的issue。另一版本的git提交规范首先,规范没有好坏,只有适不适合,这是种习惯,为了可读性、方便查询代码提交记录commit message格式<type>(<scope>): <subject>type(必须)用于说明git commit的类别,只允许使用下面的标识。feat:新功能(feature)。fix/to:修复bug,可以是QA发现的BUG,也可以是研发自己发现的BUG。fix:产生diff并自动修复此问题。适合于一次提交直接修复问题to:只产生diff不自动修复此问题。适合于多次提交。最终修复问题提交时使用fixdocs:文档(documentation)。style:格式(不影响代码运行的变动)。refactor:重构(即不是新增功能,也不是修改bug的代码变动)。perf:优化相关,比如提升性能、体验。test:增加测试。chore:构建过程或辅助工具的变动。revert:回滚到上一个版本。merge:代码合并。sync:同步主线或分支的Bug。scope(可选)scope用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。例如在Angular,可以是location,browser,compile,compile,rootScope, ngHref,ngClick,ngView等。如果你的修改影响了不止一个scope,你可以使用*代替。subject(必须)subject是commit目的的简短描述,不超过50个字符。
实战:如何防止mq消费方消息重复消费如果因为网络延迟等原因,mq无法及时接收到消费方的应答,导致mq重试。(计算机网络)。在重试过程中造成重复消费的问题解决思路:1)如果消费方是做数据库操作,那么可以把消息的id,在重试的情况下,会触发主键冲突,从而避免数据出现脏数据。(也可以先用消息id或其他唯一标识去查找表是否存在数据,存在,不插入;不存在,插入)2)如果消费方不是做数据库操作,可以借助第三方应用,如redis,来记录消费记录。每次消息被消费完成的时候,把当前消息的id作为key存入redis,每次消费前,先去redis查询有没有该消费记录理论概述rocketmq是消息中间件,是一种队列,先进先出。主要实现异步功能生产者使用封装rocketmq的sendMsg发送消息到消息中间件完成了发送消息的过程。消费者从mq中获取消息,进行消费。生产者和消费者之间是低耦合的,独立的完成自己的任务。完成了异步和解耦。WHY?解决了什么问题之前如果一个订单服务分别调用支付服务、物流服务、库存服务等等里面的方法,如果说其中一个服务挂了,那么整个业务就无法执行的--------一般非核心业务。那么mq实现解耦功能,让核心业务和非核心业务解耦,让各个服务解耦。这样即使一些比如物流服务挂了,支付业务还是能正常执行,后面对物流服务做一个补偿机制。流量削峰,rockmq天生为高并发的秒杀服务的。没有使用mq的普通情况,多少请求就会到A系统,如果秒杀每秒5000次请求过去了,这个时候mysql说我最大只能每秒200请求,多了我受不了,系统接口直接查询慢或者卡住了直到超时。那么所有人都卡在这里,无法选出前200秒秒杀成功的用户。并且太多的请求堆积在A系统,最终可能导致A系统的崩溃。而mq来了,你生产者可以生产出每秒5000次,5000次消息到mq了,mq本身是高并发请求接受率比较高的系统,可以解决高峰问题,生产者任务完成了,你没有事了。而我消费者一个服务一秒只能最大消费200请求,拉取消息200,先来的先消费,我这一秒只消费200,其他的消息你再等一等,我现在没空。知道所有消息消费完毕。秒杀请求可以请求过来,但是要先到的200个我让你这一秒秒杀成功,后来的库存还有就可以消费,库存没有就秒杀结束。保证了A系统的稳定性,“用时间换空间”。维护性良好生产者业务改动的较少,一般改不同消费者去消费消息。很方便做到一些消息业务删除,增加,修改。没有使用mq的以前模式,那么改动可能消费者服务改一下,生产者服务改一下,严格意义没有所谓的生产者、消费者一说。补充:集群:多个服务器服务一个任务微服务:一个服务对应一个任务,是分布式的一种方式。rocketmq组成rocketmq: accessKey: LTAI4FzV************ secretKey: UzhGN************************* nameSrvAddr: localhost:8100;localhost:8100 consumerGroups: - groupId: GID-******** consumers: - topic: TOPIC-***** tag: DING-**** beanName: one**************Listener - groupId: GID-*********** consumers: - topic: TOPIC-***** tag: AD-******* beanName: user*********Listener Group:分组,对消费者用处较大,比如分为物流组、库存组,每个消费者消费自己所在的组,互不干扰,相对独立进行。Topic:主题,一类消息的主题或分类,电商可能衣服是个主题、鞋子是主题;也有根据业务服务来定义的,比如报告服务一类主题、采集服务一类主题、品牌服务一类主题。消费队列:topic可以生成一条消息队列,也可以多条消息队列。一个queue被一个consumer消费,并且messageQueue1---->consumer1,messageQueue2---->consumer2提高了消费并发度。tag:topic基础在还可以在分类,比如topic是手机,tag可以进一步细分苹果手机。可以让指定消费者只消费苹果手机。普通消息的发送同步发送确保发送成功,一些重要的消息,短信通知,应用消息通知,发送消息后,需要同步响应后再次发送消息。异步发送发送数据量大,对响应速度敏感的场景。发送消息后不用等响应,接着可以发送消息。不会阻塞发送消息线程单向发送速度快,对可靠性要求不高由于在 oneway 方式发送消息时没有请求应答处理,一旦出现消息发送失败,则会因为没有重试而导致数据丢失。若数据不可丢,建议选用同步或异步发送方式。普通消息有集群消费和广播消费两种集群消费用的多些,保证数据完整性。全局消息一个生产者-----》一个消费者先进先出部分顺序消息一个生产者----->多个消费者每个消费者对应消费不同的QueueX所以称局部按照先进先出的原则来的。延时消息18个等级message.setDelayTimeLevel(3);定时应用在付款关闭倒计时等还有批量消息、过滤消息等操作。来一个消费一个普通消息属性关系Offset:偏移量
标题最新最佳最重要的计算机相关网站推荐1、Github代码托管(https://github.com/)专为开发人员而设。作为开源代码库以及版本控制系统,GitHub是一个受您工作方式启发的开发平台。从开源到业务,您可以与3100万开发人员一起托管和审查代码,管理项目以及构建软件。随着越来越多的应用程序转移到了云上,Github已经成为了管理软件开发以及发现已有代码的首选方法。代码托管必备。总之,找开源项目,写blog。2、Dribbble设计达人(英文翻译有点麻烦)(https://dribbble.com/)Dribbble是一个面向创作家、艺术工作者、设计师等创意类作品的人群,提供作品在线服务,供网友在线查看已经完成的作品或者正在创作的作品的交流网站。对于前端设计来说真是再好不过的一个网站了。3、StackOverFlow技术问(http://stackoverflow.com/)碰到问题百度不到怎么办?Stack Overflow是一个与程序相关的IT技术问答网站。用户可以在网站免费提交问题,浏览问题,索引相关内容,在创建主页的时候使用简单的HTML。在问题页面,我们不会弹出任何广告,销售信息,Java 窗口等。4、全球最大中文IT社区(CSDN)(http://www.csdn.net/)中国最大的IT社区和服务平台,为中国的软件开发者和IT从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。就是你看的这个网站。5、博客园(http://www.cnblogs.com/)这样一个不起眼的地方,却吸引了很多IT技术精英,把这里当作自己的网上家园,每天在这里分享着精彩的原创内容,也许他们看重的不是华丽的外表、诱人的虚名,而是纯净、专注、对技术人员的理解。6、V2EX(http://www.v2ex.com/)相当于百度贴吧,发文的,但里面有许多的计算机专业人才在那里,回答有技术含量。7、程序员客栈(http://www.proginn.com)我们都知道,未来是互联网科技从业者的,更确切的说是属于程序员、设计师、产品经理的…因此,我们需要一个地方让这些人立体展现自我成就,建立影响力,输出价值,拓展机遇。同时我们帮助企业团队找到行业里最优秀的人才,解决难题。企业提供需求,程序员在云端工作。8、码农网(http://www.codeceo.com/)程序员编程资料和编程经验分享平台码农网是一个专注程序员编程资料、编程经验、职场面试分享的博客平台,帮助程序员在编程开发中获取第一手的实用资料。9、虎嗅(http://www.huxiu.com/)10、菜鸟教程https://www.runoob.com/11、学习视频用b站https://www.bilibili.com/独立科技博客,有些观点还不错51CTO博客51CTO博客是一个面向程序员、运维/网络工程师、以及即将成为程序员的大学生、程序开发爱好者的技术博客平台。里面可以付费买课、也可以看看博客。其它: codeproject.com 需要设计某个复杂的gui,又不想自己写怎么办? http://www.google.com/ncr 效率高 http://www.oschina.net 一些技术的八卦可以看看。 http://www.zhihu.com 知乎,很有名,了解更大的世界。 http://www.zaobao.com/ 新加坡联合早报(中文网),新闻比较中立。 https://blog.csdn.net/weixin_43206161 thinkphp5:http://www.dba.cn/book/thinkphp5/
2022年12月