- 博客(521)
- 资源 (13)
- 问答 (1)
- 收藏
- 关注
原创 云计算 Cloud Computing
举个例子,摆宴席,云计算可以让你不用自己支架子架锅,即云基础设施IaaS,而自己做饭的这套设施,只能你自己用,即私有云,而你做完了,这个锅别人也可以用,即公有云。首先考虑用物理服务器,如此,需要自己建机房、买服务器、开发系统、专人维护服务器。,这种模式提供可用的、便捷的、按需的网络访问,进入可配置的计算机资源共享池(资源包括网络、服务器、存储、应用软件、服务),这些资源能够被快速提供。入住以后,你想要再配置点娱乐设施、健身设施,此时,你也不用自己动手,SaaS就是这些设施都是现成的,可以直接租用(订阅)。
2024-09-30 00:49:30 1177
原创 【RocketMQ】一、RocketMQ架构与领域模型
消息生产者生产出消息,投递到对应的topic主题下的队列里面(一个topic下,有多个Message Queue),消费者组通过订阅主题,从RocketMQ 服务端中获取消息并消费。
2024-09-22 15:26:25 857
原创 【RabbitMQ】二、SpringAMQP
和前面两种模型不同,一个消息被一个消费者消费完就没了。发布订阅模式允许将同一消息发送给多个消费者。实现方式是加入了exchange(交换机),交换机起到把一个消息路由到多个队列的作用。消息被路由到哪些队列中,由exchange决定。Fanout:广播Direct:路由Topic:话题exchange负责消息路由,而不是存储,路由失败则消息丢失。
2024-09-18 21:02:24 917
原创 Java中调用第三方接口
考虑到远程调用可能失败,失败后重试三次,以上面的hutool为例来实现,其余的都一样,主要还是一个是否成功标记位 + 一个计数,successFlag不用voilate,并发安全也不用考虑,线程内部调用的,用到的数存栈里了都。上面的RestTemplate,在调三方接口时挺好用的,但微服务架构下,各个微服务之间调用时,url就不好写,由此,用Feign:一个声明式的http客户端。和getForEntity的区别是,getForObject只有一个响应的内容,响应码、响应头等没有。
2024-09-04 01:00:28 1184 1
原创 同步、异步、回调函数
测试效果的话,就new A(),然后调用其a方法就行,上面代码没有进行必要的日志打印和Thread.sleep模拟异步停顿,可能视觉效果不明显,但意思就是这个意思。此时,方法a调用methodB,没问题,但以后再有方法c调用methodB,但其回调逻辑变了,是call_back_2呢?也即,如果方法a需要在方法b执行完成后,再做一点其余操作,或者说需要对方法b的执行结果进行监听呢 ==> 回调函数。如此,传入对应的Callback接口的实现类,就能在B类中调用对应的回调逻辑,类B一般也就不用更改了。
2024-09-02 18:43:21 561
原创 JSON处理库 -- Fastjson
实现FastJson的SerializeFilter接口,进行高度的定制化自定义序列化。PropertyFilter用于序列化时过滤掉特定的属性@Override// 例如,排除所有值为 null 的属性= null;// 示例// 设置属性NameFilter用于序列化时修改字段的名称@Override// 例如,将字段名转为大写ValueFilter用于序列化时,修改字段的值@Override// 例如,将所有字符串值转为大写。
2024-09-01 22:16:33 1121
原创 Java分布式锁
一个微服务有多个实例,或者说多个pod,也就有多个JVM,此时,想保证不同实例里的线程同步执行,靠synchronized这种JVM级别的锁就不能实现了,而要通过分布式锁,一种独立于JVM之外的锁
2024-08-26 01:21:34 842
原创 go中的值传递和指针传递
比如向函数调用栈里的下一个方法传递对象A,二者的区别在于,指针传递,传的是对象A的内存地址,传的是一个小巧的地址。值传递,是复制对象A的数据传下去。之前有个说法:想在调用的函数内部改变对象A的值,就用指针传递,但这句话也不全对,因为用值传递,照样可以实现同样的效果。最后,如果传递的是一个很大的结构体,那用指针传递更优。),它们占用的内存大小固定且小,大小与指针大小相当。值传递,代表的意志是:函数收到的是一个副本数据,这两种实现方式,在此时,没有谁优谁劣。注意看二者的返回值,对于固定大小的类型(
2024-08-02 12:26:24 1022 1
原创 【Leetcode】二十二、两数之和、两数相加、合并有序链表、两两交换链表节点
说白了就是两个数的加法,不过这两个数,存在链表里,且是个位数在最左边,如[2,4,3]就是数字342,这样倒着存,相加的时候,直接按顺序遍历链表,即是先按个十百千万的顺序算。如上图,绿色方框为一次递归,蓝色方框是第二层递归,第二层递归,交换后,返回4,退到第一层递归,让head.next指向第二层递归的返回值,即1指向4,完成全部交换。不玩指针指向,链表转数组,i和i+1交换值,然后数组转回链表,就解决了,但没必要这样,练习下链表。比如1、2、3、4四个点,1、2一组,两两交换,3、4一组,两两交换,
2024-08-01 14:09:05 654
原创 git回退未commit、回退已commit、回退已push、合并某一次commit到另一个分支
在一个分支修改代码后,还没commit提交,不想要这些修改了,想回到刚开始的样子。在一个分支修改代码并commit到了本地仓库,但没push到远程仓库,想回到刚开始的样子。最近一次的push我不要了
2024-07-31 13:31:39 1102
原创 【Leetcode】二十、记忆化搜索:零钱兑换
动态规划,重在状态转移,那些不用的中间值,存不存在你。amount = 14的剩余金额中,剩余7时,最优解最小,为1,因此14最优解就是 1 + 1 = 2。然后将F(0)存在数组下标为0的地方,F(3)存数组下标为3的地方,计算一个值时,先在数组中找,找不到时再计算。可以发现,计算左侧一支的F(4)时,会得到F(3)的值,存下F(3)的值的话,执行到右侧一支计算F(3)时,直接取就行。因此,amount的最优解是2。也叫备忘录,即把已经计算过的结果存下来,下次再遇到,就直接取,不用重新计算。
2024-07-27 16:06:58 544
原创 【Leetcode】十九、贪心算法:玩筹码 + 跳跃游戏
第 i 个筹码在 position[i],position = [2,2,2,3,3],就是说,第一个筹码在2号位置,第二个筹码也在2号位置,第三个筹码也在2号位置。往下遍历,一旦出现最远可达到的位置reachRight > 终点下标,即终止循环,返回true,反之,遍历完也不满足 reachRight > 终点下标,则返回false。再看上面这个例子,连续取两个5分后,差1,但现在没有1分的面值。但其实,这样也有坑,比如上面这样,按照贪心,结果是10 + 2 + 2,但最优解是 7 + 7。
2024-07-27 15:05:05 577
原创 【Leetcode】十八、动态规划:不同路径 + 全1的最大正方形
因为只能向下、向右走,所以从起始点走到点(R,C),路径数等于,以起始点到点(R,C)为对角线的矩形里,到点(R,C)左侧点的路径数 + 到点(R,C)上边点的路径数。从起始状态(0,0),到终止状态(R,C),中间每个格子的值(到达它的路径数),都会算出来,这些中间结果,可存入一个数组,这题可用二维数组存。前面已经分析过了,这儿的方程式为:F(m,n)= F(m - 1,n)+ F(m,n - 1),初始状态为(1,1),终止状态为(m,n)只能向下、向右的走,从图中左上角走到右下角,有几条路径。
2024-07-23 21:19:16 1081 1
原创 【Leetcode】一、排序
插入排序,正如这个名字,就像打牌一样,整牌时,比如现在最大的放在左边,那抽到一张新牌后,从右往左看,一个个比较,然后把新进来的牌插入到合适的位置。到这儿,想到一点,算法,即解决问题的步骤,把生活中怎么解决同样问题的行为,翻译成代码,就是答案。此外,解一道题,应该先举一个简单具体的例子,分析清楚后,再逐步扩大数据量来分析。前面选择排序是,我找到最值后,手动给它放到数组首位。冒泡则是:第n个元素和第n+1个元素对比,交换,让大的那个放右边,接着n+1和n+2位置的元素对比,依旧大的放右边。
2024-07-19 20:25:18 550
原创 【Leetcode】十六、深度优先搜索 & 宽度优先搜索 :二叉树的层序遍历
从root开始,root入队,count = 1,出队,同时root的左、右节点入队,并维护count。从root开始,一条路往下走,和前面一层层的取不一样了,DFS解时,每层递归有个level,level = 0,即root节点所在的那层,放到结果集result的0号位置,往下9,放到result的1号元素里面。先逮着1开始走,1符号要求,放入结果集,接着往下走,[1,2],也符合要求,放入结果集,接着往下走,[1,2,3],也符合要求,放入结果集,再往下,就到底了。和上面分析的BFS遍历二叉树不一样,
2024-07-17 20:35:19 1091
原创 【LeetCode】十五、回溯法:括号生成 + 子集
如此,枚举所有可能性的过程中,如果出现左括号的数量 < 右括号的数量,则说明此路不通,终止递归,回溯到上一步重新选择。以上注意:遍历前面的结果集里的每个元素时,用一个copy对象,防止引用传递。以空集开始,遍历给定集合的每个元素,并把上面每一层的结果和当前元素相加。比如给定[1,2,3]就得到了第四层:[3] 、[1,3]、 [2,3] 、[1,2,3]。
2024-07-16 16:25:22 434
原创 【Leetcode】二十一、前缀树 + 词典中最长的单词
从优化后的代码可以看到,搜索和判断前缀的区别是,判断到输入字符的最后一个字母后,搜索要有isEnd标志为true,表示有这样的单词,以免出现,搜abc,但只有abcd时也返回true的情况。比如app单词,a字母找到了,且isEnd为true,往下ap,也找到了,且isEnd为true,如此app这个单词就是目前符合要求的。此外,正常来说,每个Trie节点的值val也要存一下,但对英文字母不用,因为其对应的SSCII码,可以当下标,下标转一下就是字母值。root节点,一般不存数据,其下有孩子节点。
2024-07-16 15:48:00 977
原创 【LeetCode】十七、并查集:岛屿数量
有个数组array,长度为10,若array[1] = 6,说明1号元素的上级是6号元素。两个集合合并,或者说两个门派合并,看似改动很大,其实只要让一个门派的教主给另一个门派的教主当上级即可。想实现这个效果,可以:查询到x元素的根节点(教主)后,直接将x元素的上级改成根节点。合并后,比如让第一个集合的教主做合并后新集合的教主:5号的上级不再是自己,变成了1。也就是说,第一次find元素x,是没有压缩路径的,第二次才是优化后的效果。对应的数组:数组索引代表元素,数组的值,代表这个位置的元素的上级。
2024-07-15 10:43:37 586
原创 系统数据加密传输的实现
针对以上要加密的数据,用户密码处理的流程图如下:修改注册后端接口,用户注册时,提交密码,前端用公钥对密码进行加密后,传到后端服务器。对邮箱名、手机号等信息,可非对称加密,也可使用AES对称加密,实现加密传输,加密落库则可有可无,如果选择了加密落库,可能会影响到之前的userList接口等等,总之明文、密文别转换叉了。修改后端登录接口,登录时,前端传来的密码,解密后传到SpringSecurity框架,如果账户是加密传输的,也需解密,因为框架里要loadUserByUsername,用户名得转换过来。
2024-07-10 20:26:04 1353
原创 【LeetCode】十四、分治法:多数元素 + 最大子序列和
这里用分治法解决一下:把一组数分成一个个不可再分的元素(分治法里所说的小问题),再分别求众数,往上开始一层回退递归,如果左边有一半以上的数是n,右边也有一半以上的数是n,那左右两边合并后,多数元素就也是n。其次,每次左右两边的众数如果相等,则这一个区间的众数就是该值,反之,左右两边的众数值不一样,那就要比较这两个众数在区间里出现的次数,来决定选谁,如果连出现的次数也一样,那就随机取一个。因此说:左右两边分别是有序的,那把它两合并成一个新的有序的结果是更容易的。组合小问题的解,就是最终的排序结果。
2024-07-04 17:53:44 670
原创 【LeetCode】十三、递归:斐波那契 + 反转链表
以hello为例,第一层递归,L = 0,R = 4,进入第二层递归,L = 1,R = 3,进入第三层递归,L= 2,R = 2,此时,触底,第三层递归函数执行return,结束,出栈。如上,第一层递归,L = 0,R = 4,但其传入下一层递归的L和R分别为1和3。这里以双指针的思想为基础,硬套一层递归来实现:还是L和r两个指针,递归终止的条件是 L >= r,递归的拆解则是每次L指针+1,r指针-1,递归要传递的参数不再是一个,而是L和 r 两个,上一层递归结束,回溯回来时,交换L和r位置的元素。
2024-07-03 20:55:22 1069
原创 【LeetCode】十二、滑动窗口:长度最小的子数组 + 定长子串的元音最大数目
依旧每次让i++前进一位,但结果不再重新累加,而是下一组的和 = 上一组的和 - 上一组的第一个元素 + 新框进来的元素。像窗口向前滑动,每次和上次相比,多了一个新元素,少了最开始的一个旧元素。,接着再继续去掉array的第一个元素,直到不满足 >=s的条件时,窗口向前滑动,直到出现第二个子数组array。定长,考虑滑动窗口,先计算第一个k长度的窗口的元音数量,然后一步一步滑动到末尾,期间取Math.max()这题两个关键点:一是要求子数组是连续的,二是子数组不是定长的,但也可以用滑动窗口。
2024-07-03 16:12:43 652
原创 【LeetCode】十一、二分查找法:寻找峰值 + 二维矩阵的搜索
第一个想法是:先普通的二分查找value,返回-1后,说明不存在,那就再遍历这个数组,用双指针,当p1的值 < value && p2的值 > value时,return p1 + 1,但这样应该是复杂了。,如果有等于target的,那返回其下标,如果不存在,那就要插入到第一个比target大的值的位置,第一个大的值的下标则往后移动一位。在有序的集合里找一个数字,可以二分查找。找一个数,有序的情况下,直接遍历找,时间复杂度为O(n),用二分法,一半一半的砍着找,则时间复杂度为O(log n),更优。
2024-07-02 20:58:24 692
原创 【LeetCode】十、双指针算法:环形链表检测 + 救生艇
最先想到的是,两层循环,遍历array,如外层 i = 1,内层循环 j = 4 5 7 9,外层 i = 4,内层循环 j = 1 5 7 9……其实本质是两个人的体重之和问题,和上面提到的对撞指针很像,不过一个是等号,一个是小于号,因此考虑先给所有人的体重从小到大排个序(因为排序是对撞指针移动的基础前提)此时可用快慢双指针,慢的一次走一步,s = s.next,快的一次走两步,f = f.next.next,二者同时从队首出发:。移动三次后,快慢指针相遇了,这说明是个环形,否则二者不会相遇。
2024-06-28 15:06:33 492
原创 【LeetCode】九、堆的使用:第K个最大元素 + 前K和高频单词
可用HashMap,统计完后,前k个、第K个,则可考虑最大堆。不过,题中要求次数相等时,按照字母排序,因此,要自定义比较器的实现:先比次数,次数相等再按字母排序。如果要用最小堆实现:应该将值最小的元素往堆顶放、同等次数的把字母靠后的往堆顶放。这题应该快排来解,这里用堆仅做练习。
2024-06-27 19:50:16 397
原创 【LeetCode】八、树、堆、图
如下,一个数组转为一个完全二叉树,其结果是唯一的(遍历数组,从上到下、从左到右的摆放),即0号元素当根节点,后面两个1、2号元素当根节点的左右子节点,3、4、5、6号元素分别当1、2号元素所在节点的左右子节点。如下:整个树看成三块,A、A的左子树、A的右子树,在两块子树里,继续按中序的左根右遍历,结果就是:D ⇒ B ⇒ E ⇒ A ⇒ F ⇒ C ⇒ G。同理,换完后,第二层不再满足最小堆,需要再交换,10 > 8 也有 10 > 7,选最小的7这个节点进行交换。堆化,即把一组无序的数加到堆里去。
2024-06-27 19:49:02 777
原创 【LeetCode】七、哈希集合Set相关:存在重复元素判断 + MyHashSet设计
思路:重复的判断,借助数据结构的set,数组的长度 > set集合的长度,即有重复。相比之前对这个题的解法,很明显的感觉到,用上数据结构,比无脑for循环要快很多。,删除一个10,就把下标索引为10的地方改为false,重复放进来同一个值,仍然为true,符合Set集合的不重复。主要作用:查看是否有重复元素(给一个数组,转为set,数组的长度 > set的长度,即有重复元素)实现自己的HashSet类,那也就要达到搜索、插入、删除的时间复杂度为O(1),
2024-06-27 19:48:06 332
原创 【LeetCode】六、哈希表相关:统计重复元素 + 找不同
又叫散列表,存键值对,将key用哈希函数转为数组下标索引当两个不同的key经过哈希函数得到相同的结果i,即哈希冲突了此时 i 位置就要存两个值,因此,链表出现,如下图中数组下标2的位置:时间复杂度:根据key找value,时间复杂度为O(1),但如果有哈希冲突,则时间复杂度为O(k),k为冲突位置链表元素的个数下面这种用数组表示哈希表的结构,是key为下标索引,value为数组元素的值。重点关注HashMap就行:单论这题要return的结果,其实不借助数据结构,直接for循环遍历,里面再嵌套遍历
2024-06-27 13:40:05 770
原创 【LeetCode】五、栈相关:有效的括号 + 下一个更大的元素
期间如果中途取到了更大的值,则存一下,以防有多个更大的值,下次出现更大的值,不论大小,直接覆盖,因为取的是下一个更大元素,不是下一个更大的元素里的最大的元素。每循环一次,处理num1的一个元素,num2的栈元素也会被弹出,等处理num1的下一个元素时,num2的栈就不完整了,因此,这里用一个tmp临时栈,记录num2栈被弹出的元素,后面再塞回num2栈,以便处理num1的下一个元素。有没有比该元素大的,如果采用栈,将num2入栈,遍历num1的每个元素n,每次弹出栈顶元素来比较,根据这个特点:比较的是。
2024-06-27 13:38:04 501
原创 【LeetCode】四、队列相关:最近的请求次数
比如下面,1ms、100ms的时候分别进来两个请求,此时返回2,3001的时候再进来一个请求,[3001-3000,3001]的请求数量为3,3002的时候再进来一个请求,[3002-3000,3002]区间,1ms的请求就不算了,返回3。思路:用一个队列,每进来一个请求(或者说每入队一个时间t),就对比最先入队的元素,判断其是否出t-3000和t闭区间,是则不再题目的统计范围,移除。很逆天的题目描述,就是不同时间会有请求发来,现在需要计算t-3000和t闭区间之内的请求次数。
2024-06-26 14:34:16 304
原创 【LeetCode】三、链表相关:移除与反转链表
此外,要求最后返回新的头节点,只靠一直往下移动的pre和head,遍历完后,无法获得头节点信息(单向链表),因此还要加一个虚拟节点dummy(位置在传入的head的前一个节点),dummy的next等于传入的头节点,dummy的val则随便给,反正用不到。满足则让当前节点head的前一个节点指向head.next,完成删除,但当前为单向链表,获取不到前一个节点,因此需要维护一个pre node的值,记录遍历到的当前节点的head的前一个节点,以便进行删除操作。
2024-06-26 14:34:00 695
原创 【LeetCode】二、数组相关:双指针算法 + 置换
当左指针L >= 右指针R时,说明已经全部遍历了一遍了,此时,看下,如果L所在的值为val,说明其前面全都是不等于val的值,比如L为4,说明当前位置下标为4,前面为0、1、2、3这四个元素,返回的数量就是4,也即L的值,反之,L所在的值不等于val,说明当前位置的值及其前面的值,都是不等于val的值,数量 = 索引 + 1,返回L + 1。一开始想的是:遍历找为0的元素,找到一个就将其后面的所有元素往前移动一位,然后将这个为0的元素自身扔在数组末尾。访问时,时间复杂度为O(1)
2024-06-25 19:58:39 1207
原创 【Java面试】二十三、项目相关
前面提到,在交易平台要做一些校验和消费记录落库的操作,这些是对接所有三方系统的公共步骤,而后面请求第三方系统接口肯定要做的鉴权认证以及转发或者调用,则属于各个三方系统的定制化行为。因为不同的第三方供应商系统有不同的认证方式,想实现打通,就要有不同的具体策略类(比如策略类A是通过appid完成认证,策略类B是通过密钥完成认证),因此考虑使用了策略模式。用户在浏览器发送请求数据到后台系统,期间数据在网络传输,如果这些数据是敏感数据,被恶意拦截时,就有安全问题,造成用户密码泄漏等等。
2024-06-25 11:12:34 636
原创 策略模式 + 抽象工厂实现多方式登录验证
每种登录就是实现登录这个目的的一种策略,因此先想到的应该是策略模式,所有具体策略类所需要实现的接口就是抽象策略类的login方法。其次,前端传不同的type,要调用不同的具体策略类对象,如此,再引入工厂模式。因为不同的第三方供应商系统有不同的认证方式,想实现打通,就要有不同的具体策略类(比如策略类A是通过appid完成认证,策略类B是通过密钥完成认证),因此考虑使用了策略模式。这样写,以后再增加新的登录方式,工厂类还得改,为了解耦,使用配置文件,不同的登录方式的type,对应一个登录方式的具体策略类。
2024-06-24 20:02:38 1548
原创 【Java面试】二十二、JVM篇(下):JVM参数调优与排查
再比如栈大小的设置,一般256KB,用于存放每个线程的栈帧,这个值太大,则从栈可用空间层面限制了最大线程数量,比如设置了512KB,在总内存不变的情况下,线程数量上限就减半。内存泄漏,即一些对象没有被回收,累积导致OOM,表现为运行一段时间后服务宕机,但生产环境不能等服务挂了再修,可选择监控+告警邮件,比如普罗米修斯,让内存占用到一定阈值后,触发告警,此时可选择VisualVM分析。通过查看堆信息的情况,可以大概定位内存溢出是哪行代码出了问题,找到对应的代码,通过阅读上下文的情况,进行修复即可。
2024-06-19 19:30:44 840
原创 【Java面试】二十一、JVM篇(中):垃圾回收相关
JVM处理class字节码文件成为二进制文件,类加载的作用则是将class字节码文件加载到JVM中。启动类加载器:加载JDK下的jre/lib下的类,这个加载器由C++实现扩展类加载器:加载JDK下的jre/lib/ext下的类,如果把开发者自己写的class放这个目录,也会被扩展类加载器加载应用类加载器:加载开发者自己写的class自定义类加载器:自己去继承ClassLoader,自己实现。
2024-06-19 16:38:02 914
原创 CentOS更新镜像源
Linux下安装很多指令或者工具时,发现yum执行超时或者返回没找到有效的package,此时需要更新yum源Yum(Yellowdog Updater Modified)是一种在 Linux 操作系统中用于软件包管理的工具Yum 源就是存储那些软件包及其相关信息的服务器或仓库Yum 源包含了各种软件包的元数据和二进制文件,这些软件包可以通过 yum 指令进行下载、安装、更新和卸载。
2024-06-18 21:27:20 575
原创 【Java面试】二十、JVM篇(上):JVM结构
根据JVM策略,新创建的对象在伊甸园区,伊甸园区满了以后,触发Young GC,GC后或者的对象,复制到幸存者区,后面每GC一次,活着的对象年龄加一(对象头里存着年龄),对象GC年龄到达阈值(如15)后,晋升到老年代。因为永久代/方法区或者说后来的元空间,存储的主要是一些类信息和常量,需求开发,加载的类越来越多,这个空间不可控,移除永久代,在本地内存放个元空间,可以防止OOM。栈,即每个线程运行时需要的内存空间,保存着该线程方法调用的基本数据,先进后出,其中,每一个调用的方法用一个叫栈帧的东西存。
2024-06-18 20:45:19 889
TA创建的收藏夹 TA关注的收藏夹
TA关注的人