总结:

  • Spring 中的 AOP,有接口默认就用 JDK 动态代理,没有接口就用 CGLIB 动态代理。

    但可以设置 @EnableAspectJAutoProxy(proxyTargetClass = true) 强制使用 CGLIB。

  • Spring Boot 中的 AOP,2.0 之前与 Spring 一样;2.0 之后默认使用 CGLIB 动态代理,如需使用 JDK 动态代理,需在 application.properties 中配置 spring.aop.proxy-target-class=false

有时会遇到这样的题目:设计一个公平的洗牌算法

与之类似的还有 随机打乱一个数组,其中用到的都是「随机算法」。

这类问题的核心在于“公平”、“随机”。

什么叫“公平”?

假设有一个长度为 $n$ 的数组(无重复元素),那么它的排列共有 $n!$ 种。

要做到公平,就要求等概率地返回这 $n!$ 种排列中地其中一种。

一种朴素的想法就是,生成所有 $n!$ 种排列,然后随机返回其中的一个。

毫无疑问这种算法是正确的,但是 $O(n!)$ 的时间复杂度是不可接受的,它是比指数爆炸 $2^n$ 还恐怖得多的存在。

换个角度思考,上面的要求等价于 每个元素等概率地出现在数组的每个位置

就有了大名鼎鼎的 Knuth 洗牌算法,其实只有两行:

1
2
3
for (int i = nums.length - 1; i >= 0; i--) {
swap(nums, i, random.nextInt(i + 1));
}

这两行代码就可以完成上述的目的。

错误描述

在 Spring Cloud 项目中通过 Open Feign 远程调用时出现如下错误:

1
2
feign.codec.EncodeException: No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
...

Spring Cloud 版本:Hoxton.SR9

Spring Cloud Alibaba 版本:2.2.2.RELEASE

Spring Boot 版本:2.3.7.RELEASE

错误原因

从报错信息中不难看出,错误原因是容器中缺少 HttpMessageConverters 这样一个 bean 对象。

GitHub 上 spring-cloud/spring-cloud-openfeign 与此相关的 issue:https://github.com/spring-cloud/spring-cloud-openfeign/issues/235。

在 spring-boot-autoconfigure 的较新版本中(具体哪个版本我也不知道),HttpMessageConverters 的自动配置条件更改了,可以参见 HttpMessageConvertersAutoConfiguration 类:

1
2
3
4
// 这里省去了其他无关注解
@ConditionalOnClass({HttpMessageConverter.class})
@Conditional({HttpMessageConvertersAutoConfiguration.NotReactiveWebApplicationCondition.class})
public class HttpMessageConvertersAutoConfiguration {}

因为现在的 Spring Cloud Gateway 是基于 WebFlux 的,是 Reactive Web。所以根据 @Conditional 的条件,HttpMessageConvertersAutoConfiguration 就不会生效,进而也不会进行自动配置,就导致容器中缺少 HttpMessageConverters 对象。

解决方案

这个问题解决方法也很简单,只需自己写一个配置类,向容器中注册一个 HttpMessageConverters 对象即可。方法可以从 HttpMessageConvertersAutoConfiguration 中复制。参考如下:

1
2
3
4
5
6
7
8
@Configuration
public class FeignConfig {
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
}
}

重启项目,问题解决。

错误描述及原因

项目启动时 RabbitMQ 报错了,控制台打印一大堆就不贴了,问题的源头是:

1
Failed to declare queue(s):[你的消息队列名]

也就是说声明队列失败了。

阅读全文 »

声明:本系列文稿整理自抖音 @吾纪录 发布的中国政法大学马克思主义学院郭继承教授的系列视频,对口头讲述内容进行了书面整理,并不是逐字对应,但保证没有篡改原意。仅供学习,如觉有不妥,请联系删除

国运线

&emsp;&emsp;在人类三四千年的历史长河中,中国绝大多数的时间都在人类文明的第一梯队。大汉时期,那有拓疆万里的雄心;盛唐的时候,那有融汇天下为我所用的气派。同时代的欧洲,它的文明程度、社会治理,方方面面中国走在前面。这是事实,没有什么好抬杠的。盛唐女孩的衣服,胸下围一道绳子束着,下面敞开没有束缚。我吃多少,多么健硕,什么腰粗不粗,你管得着吗?“人面不知何处去,桃花依旧笑春风”。同时代的欧洲和中国比,在欧洲你笑春风一次?你的后果很严重。在欧洲所有的说法只要跟它的宗教不一致、跟教皇说的不一致,烤死,布鲁诺只是其中之一。还有的喝水把肚子喝得很大,然后用石头猛撞肚子。各种处罚人,称之为“黑暗的中世纪”。所以欧洲的文明程度没有中国高,中国历史两千多年没有出现神权压抑人权。中国历史上有王权对人性的压抑,但神权控制人,严格意义上没有出现。

大家读唐诗的时候,都是那个时代人的精神风貌。李白写诗:“君不见黄河之水天上来,奔流到海不复回”。离别的时候一般人都伤感,可是在大唐气象里面,离别的时候都可以拍手唱歌,“李白乘舟将欲行,忽闻岸上踏歌声,桃花潭水深千尺,不及汪伦送我情。”,“海内存知己,天涯若比邻”。王维的诗:“九天阊阖开宫殿,万国衣冠拜冕旒”,那是唐朝气象。

到了宋代的时候,中国整个气象的开阔仍然有。李清照的词你们都读过吧,那种心情的舒展。“常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。”少男少女在一起喝酒啊、划拳行令啊,兴尽晚回舟,乘舟的时候还要比看谁快,争渡争渡。那个时候也没有那么多约束,要男孩女孩授受不亲啦,乱了风俗?没有这种说法吧,而且很高兴还写诗。

可是朋友们,后来中国的生命力就开始萎缩。到了宋代以后,贞节牌坊开始出现了。这个贞节牌坊,我是这样看待的,比如有的女同志她的丈夫去世了,这个女同事觉得哎呀我也不想再嫁了,那么这种人有个贞节牌坊,我不想再嫁了,行不行?当然行了,人家的自由嘛。而有的女同志丈夫去世以后自己生活不方便,还想再嫁,可以不可以?当然可以了,这怎么了。可是那个时候就不行,沉重的枷锁就束缚了。衣服从盛唐时期那个状态往上收了,到了明朝的时候变成领子剩一点小口。到了清朝的时候,没了,什么都看不到。衣服表现了一个民族在走向封闭、走向僵化、走向保守。在明朝中后期以后,海禁;清朝以后,文字狱。

同时代的欧洲和中国比,比我们怎样呢?中国的国运,我们从南宋的节点就开始往下走了,思想被束缚了,活力被束缚了,就衰败了。但是人家欧洲,从十三世纪、十四世纪一步一步地在冲破两个枷锁,一个是神权一个是王权。有个人叫但丁,但丁写神曲的时候,你们有没有发现他在地狱里边给谁留了个位置?教皇。敢在地狱里给教皇留位置,掀开了向神权进行清算的西方文艺复兴的序幕。有一个画家叫达芬奇画了个谁?蒙娜丽莎。有人说蒙娜丽莎的微笑多么漂亮,我说你的审美很宽容。蒙娜丽莎的微笑不是它美,是它在思想史和哲学史上的地位。原来的画,只能画圣母、天使。而达芬奇把一个家庭妇女当做绘画的主题,说明西方的思想和画家的笔端开始从遥远的天国拉向了人间,这是它的意义。梵高的向日葵,挣扎、扭曲,向日葵为什么这样?向日葵什么样都不重要,这是梵高心中的向日葵。梵高这么画,说明人苏醒了。西方人开始挣破神权的束缚,开始把人的尊严和自由给呼喊出来。这就是文艺复兴。

文艺复兴、启蒙运动、宗教改革,三个合在一起,思想的缺口打开了;法国大革命、光荣革命、美国独立战争,政治制度打开了;工业革命,科技的创造打开了;亚当·斯密的《国富论》,市场经济打开了。

哎呀同学们,两三千年不如我们的欧美,野蛮增长。为什么说野蛮增长呢?马克思对它的评价就是:资产阶级来到世间的一百年创造的财富,比以往历史所有总和都多。西方资本主义社会来到人间,创造那么多财富,可是它带给我们人类太多的血腥,中国就是受害者。帝国主义对我们民族的灾难和罪恶,罄竹难书。

中华民族到了十七世纪,其实也开始突破了。黄宗羲有没有反思两三千年中国存在的专制制度?顾炎武反思了没有?王夫之反思了没有?方以智都在反思。历史都在这个突破口。只可惜十七世纪发生一件什么事?清军入关。李自成被灭了以后,1644 年顺治皇帝在北京称帝。哎呀同学们,这一次中国的历史在即将突破的时候,一个比中原地区的文明和治理程度远远落后的游牧部落占领中国了。这就是历史,没法改。那么清朝它占领中国以后,它没有接着明朝、接着黄宗羲王夫之往前走,没有对以前两千多年制度进行清算、创造一个新的文明体系。没有,反而回去了,更加比旧制度还要封闭。这一下不要紧,中西方的差距一下子拉开了。我们踽踽独行,被时代远远抛开了。当然了,瘦死的骆驼比马大,毕竟两三千年的沉淀。太阳将要落山的时候,也有一抹彩霞,映得满天通红。那一抹彩霞真的很艳丽啊,康乾盛世。可是朋友们,晚霞消失以后,是我们这个民族无尽的黑暗,同胞的挣扎和血泪。

那么这个时候,一旦跟西方交手,真的是溃不成军。为什么?

声明:本文是新华社记者张扬 @小羊在鲜花舍 在五四青年节之际发布的一条视频 【年轻时写日记要藏好,不然就被出版了】 的文字版。我觉得写得很好,既可以平常当作小文章读读,也可以在写作时参考借鉴。仅供学习使用,如觉有不妥,可联系删除

一日晴…… 晚子英来,招之至广和居饮。

二十六日…… 归途过临记洋行买饼饵少许。

三日…… 过稻香村买饼干一元。

——《鲁迅日记》

  如果你可以穿越百年,和那时的青年对话,你会聊些什么呢?是聊诗词歌赋,还是谈谈人生哲学?其实,和他们的共同语言,比想象中要多得多。

阅读全文 »

报错信息

今天启动项目打开 Swagger 文档的时候,突然报了这么个错误:

1
2
3
i.s.m.p.AbstractSerializableParameter : Illegal DefaultValue null for parameter type number
java.lang.NumberFormatException: empty String
......

或者像这样:

1
2
3
i.s.m.p.AbstractSerializableParameter : Illegal DefaultValue null for parameter type integer
java.lang.NumberFormatException: For input string: ""
...

然而程序运行一切正常,检查代码也没发现什么错误,最后锁定到了 Swagger 身上。

阅读全文 »

位运算这种东西,代码一般比较简单,但比较难想到。属于是见过就会,没见过就不会那种。而且比较难记住,很容易记错记混。

位运算模拟加法

设两个数字的二进制形式为 $a$、$b$,其和 $s=a+b$,$a(i)$ 表示 $a$ 的二进制第 $i$ 位。

$a(i)$ $b(i)$ 无进位和 $n(i)$ 进位 $c(i+1)$
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

规律就是:对单个数位而言,异或结果就是无进位和,与运算结果就是进位(因为是进位,还需左移一位)。

位运算模拟加法的公式就是:(a^b) ^ ((a&b)<<1),循环这个过程,直到进位为 0。

例题:剑指 Offer 65. 不用加减乘除做加法

排序算法

虽然实践中排序通常都会直接调用库方法,但是一些排序算法的思想还是要学习的,设计得很巧妙。

重点学习:快速排序、归并排序、堆排序。

阅读全文 »