Joker With Time Passing!

Boy meets ambitions!


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

分布式系统学习---可扩展的Web体系结构和分布式系统

发表于 2020-08-13 21:42:30   |   更新于 2020-08-22 12:06:59 |
字数统计 11.8k 字 | 阅读时长 39 分钟

¶分布式系统学习(一) : 可扩展的Web体系结构和分布式系统

本文是学习用的自翻译版本,原文地址 : Scalable Web Architecture and Distribute Systems


¶开篇:

  • 出于系统学习了解分布式知识的想法,从耗子叔的极客时间专栏看到推荐的入门阅读文章,抱着一边学习一边翻译的的想法,开始尝试系统地了解分布式领域的技术知识。

¶译文:

  • 对于一些大型站点来说,开源软件已经成为基础设施模块一样的存在。而且随着这些站点规模的持续扩张,对应的最佳实践和设计原则也应运而生。这一章节力求涵盖大型站点设计的关键问题,以及用于实现站点架构设计的构建模块等。

¶1.1 WEB分布式系统设计原则

  • 构建和维持一个具备扩展性的系统/应用意味着什么?在底层的实现方式上仅仅是通过远程网络资源将用户关联起来–使得系统具备扩展性的是资源的分布或者说访问资源的方式,是分散在多台服务器上的。

  • 像生活中中的其他事情一样,在构建web服务之前先花时间仔细制定计划,有助于系统的长期稳定;理解大型站点设计背后的注意点和权衡取舍会在设计小型站点时产生更优的决策。以下是一些影响大型扩展性系统设计的关键原则:

    • 可用性: 对于大多数企业来说,自身站点的正常可用时间会直接影响到企业自身的声誉和业务,对于一些大型的在线电商而言,数分钟的站点不可用将会导致百万收入的流失,因此它们的系统设计的持续可用和弹性容错不仅仅是基本的业务需求,也是技术要求。高可用系统要求谨慎的地考虑系统关键组建的冗余性,部分故障的快速恢复,问题出现时的服务降级。

    • 性能: 对大多数站点来说性能越来越成为重要的考量标准。站点的响应速度会直接影响系统使用和用户体验,就像搜索引擎排名,性能直接关联到站点收入和用户留存。因此,构建系统如何优化以达到快速响应和低延迟是关键

    • 可靠性: 系统需要可靠是毋庸置疑的,请求指定数据的请求应该直接返回同样的数据,但是当数据更新之后,同样的数据请求应该返回更新后的数据。用户需要知道系统是否写入或存储了新的内容,这些内容可以持久化并在将来也可以被检索获取到。

    • 扩展性: 谈到任何大型分布式系统时,系统大小只是分布式系统扩展需要考虑的一个方面。就像需要对系统扩容以支持更大的负载,通常指的都是系统的伸缩性。系统的伸缩性可以映射为系统的许多指标:能支多少额外的业务,是否能便利地增加存储容量,能够处理多少笔正常交易等。

    • 可管理性: 设计易于操作的系统也是另一个需要考量的方面。系统的可管理性等同于操作的伸缩性:保养和更新。具备可管理特性的系统,意味着当问题出现时很容易诊断问题根源,易于对系统进行更新,且易操作。

    • 成本: 成本是一个比较重要的因素。很明显,包含了软件和硬件的成本,但也要考虑到部署和维护系统所需的部分。系统开发所需的大量开发者,系统运行所需的准备工作,甚至包括系统使用的培训过程等,这所有的一切都可以归纳到成本的范畴中来。

阅读全文 »

一次Spring Bean 对象debug过程

发表于 2020-07-15 20:35:58   |   更新于 2020-08-11 08:06:59 |
字数统计 5.1k 字 | 阅读时长 21 分钟

¶一次Spring Bean 对象debug过程


¶概述

  1. 用了Spring 这么久,除了觉得它对于web开发十分便利之外,并没有太多地了解它内部的一些实现过程。之前听人提起过,debug的方式可以带你一步一步跟着框架的执行思路了解它的内部机制,因此尝试了一下;( 懒得分开写,文字很多,嫌麻烦可以直接翻到最后的流程图 )

  2. 标准的SpringBoot项目,断点的代码比较简单:

  3. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    @Service
    public class UserService { //断点处

    @Autowired
    private UserMapper userMapper;

    public int addUser(User user){
    return userMapper.insert(user);
    }

    public User getUser(Integer userId){
    return userMapper.selectByPrimaryKey(userId);
    }

    public User getUserByName(String userName){
    return userMapper.getUserByName(userName);
    }
    }
  4. 断点打在第三行,类加载的时候

阅读全文 »

cpuMemory(1)

发表于 2020-06-29 22:45:12   |   更新于 2020-08-11 08:06:39 |
字数统计 3.3k 字 | 阅读时长 11 分钟

¶CpuMemory(1)


¶概述

  1. 为了了解更多内存和cpu相关的内容,阅读 What Every Programmer Should Know About Memory 文档,尽可能地理解

¶Cpu Cache

  1. 早期的Cpu访问速度仅仅和内存总线一个级别,内存访问只比寄存器访问慢一点点。但是到了90年代,CPU技术有了突破性的进展( INTEL 1982年推出80286芯片 ),cpu的吞吐量大大提升,但是内存总线和RAM存储的速度并没有按比例提升,并不是因为快速的RAM存储无法制造,而是基于成本的原因( 例如结构复杂的SRAM,相对于DRAM,单位体积造价高而且容量小 ),无法采用。

  2. 如果在这样两种方案之间选择: 拥有一小块快速RAM存储的机器结构和拥有大量相对快速的RAM存储的机器结构,后者毫无疑问会胜利,既可以提供相当大的存储空间,而且也降低了访问第二存储介质(通常是硬盘)的成本。

  3. 限制在于第二存储介质的访问速度,也就是硬盘,用来存储RAM工作集换出的部分,访问硬盘上的存储数据甚至比访问DRAM的数据要慢上好几个数量级

  4. 不过,SRAM和DRAM是可以共存的,一台电脑在大量的DRAM存储之外,还可以拥有一小块快速的SRAM存储,可能的实现方案是在处理中划分出一块指定的地址空间容纳SRAM和DRAM,这样系统任务就会优化数据分配以更好的利用内存,基本上,SRAM是作为处理器的额外寄存器使用。

  5. 但是这种实现方案是不可行的。它要求每个处理器软件中管理自身区域的内存分配。但是每个处理器所拥有的这一块内存区域的大小是不同的,而程序的每一个部分都要求共享SRAM内存,由于这种同步的要求反而增加了开销。简单来说,增加SRAM快速存储带来的收益会完全被管理这些资源的开销给抵消掉。

阅读全文 »

LeetCode-4.Median of Two Sorted Arrays

发表于 2020-07-02 07:05:39   |   更新于 2020-07-15 22:39:50 |
字数统计 880 字 | 阅读时长 5 分钟

¶LeetCode - 4 : Median of Two Sorted Arrays

  • There are two sorted arrays nums1 and nums2 of size m and n respectively.Find the median of the two sorted arrays.

  • The overall run time complexity should be O(log (m+n)).

  • You may assume nums1 and nums2 cannot be both empty.

阅读全文 »

无锁队列

发表于 2020-06-22 21:29:12   |   更新于 2020-06-25 23:08:49 |
字数统计 3.6k 字 | 阅读时长 15 分钟

¶无锁队列


¶概念:

  1. 通常队列要实现安全的并发访问,需要对入队和出队方法加锁,例如在基于链表实现的队列中,入队和出队都涉及到头/尾节点指针的操作,不安全的并发控制很容易导致读取到错误数据甚至破坏链表结构

  2. 例如线程A插入数据x , 获取到当前的尾节点 tail ,此时线程 B插入数据y ,将尾节点更新为为值为y的节点 ,而后线程 A 又将旧的尾节点更新,这就导致丢失了线程B插入的节点 y

  3. 在多线程并发访问的情况下这是完全有可能发生的,解决这个问题可以直接在入队和出队方法加锁,例如使用synchronized 关键字控制对出入队方法的访问,这样可以实现并发控制,但是在软件工程里面,效率也是一个很重要的问题,锁的粒度越大,效率越低;反之亦然。

  4. 无锁队列并不是真正的没有锁,而是使用CAS模拟出了细粒度的锁,控制线程间的共享变量的访问 – 我们在实现并发控制的时候,是没有必要锁住整个对象的 – 这样线程之间就可以安全地通信

阅读全文 »

LeetCode-BinaryTreeLevelOrderTraversal

发表于 2020-06-23 20:47:47   |   更新于 2020-06-23 20:55:24 |
字数统计 272 字 | 阅读时长 1 分钟

¶LeetCode-二叉树的按层遍历


¶思路:

  1. 如何确定同一层的节点?可以从根节点开始用0标记层数,然后累加,相同的层数表示在同一节点
  2. 使用容器或数组保存每一层的节点

¶实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

public class BinaryTreeLevelOrderTraversal {

public static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}


//按层输出,需要确定层数
public static void getNodeLevel(TreeNode node,int level,List<List<Integer>> list){

if(null == node){
return;
}else{
if( level > list.size()-1){
list.add(level,new ArrayList<>());
}
list.get(level).add(node.val);
}
TreeNode left = node.left;
TreeNode right = node.right;
if(null != left || null != right){
level++;
}else{
return;
}
getNodeLevel(left,level,list);
getNodeLevel(right,level,list);
}

}
  1. 递归代码中永远都需要小心确定循环的退出条件,空节点直接退出递归
  2. 当存在非空的子节点,将level累加向下传递
  3. 虽然没有按照 LeetCode 的代码提示方法去做,不过还是测试通过了

知识反刍--数组

发表于 2020-06-17 21:25:52   |   更新于 2020-06-22 20:11:28 |
字数统计 1.8k 字 | 阅读时长 6 分钟

¶知识反刍–数组

学而不思则惘


¶起因:

  1. 学习这种事最怕一知半解而不自知,验证自己是否一知半解甚至错误理解的方式,就是看能否通过简单易懂的方式将概念表达出来;如果在尝试阐述的过程中遇到了停顿和迷茫,那说明需要回到知识源头重新学习
  2. 也是为了检验自己是否真的学进去了,而不是用战术上的勤奋掩盖战略上的懒惰

¶数组:

  1. 什么是数组?:

    1. 一种线性的数据结构,线性指的是其中数据的存储方式是像一条线一样连接在一起的
    2. 它使用的是一块连续的内存空间,这里的连续是指物理上的连续,也就是一整块的内存空间
    3. 存储着相同类型的数据
    4. 数组就像是一排规格一致的储物柜,柜子按照编号排列,每个柜子的大小都是相同的;想从哪个柜子里存取东西的时候,根据柜子的编号用钥匙去打开就行
阅读全文 »

知识反刍--链表

发表于 2020-06-18 07:37:55   |   更新于 2020-06-22 20:11:00 |
字数统计 1.7k 字 | 阅读时长 5 分钟

¶知识反刍–链表

学而不思则惘


¶尝试概念阐述:

  1. 链表也是一种线性结构,我们把链表的每个位置称作节点,每个节点存储的是本身的数据信息和指向前后节点的指针,最后一个节点指向NULL

  2. 和数组不一样,链表并不需要物理位置上连续的内存空间,因为每个节点通过指针联系在一起,好处就是链表的插入删除操作不需要做数据整体的移动,只需要改变该位置的指针信息;

  3. 坏处是,过长的链表很容易造成内存碎片,可能会导致内存利用率降低,而且对CPU缓存机制也不友好

阅读全文 »

Carol Dweck: A Summary of Growth and Fixed Mindsets

发表于 2020-06-16 23:00:01   |   更新于 2020-06-17 21:20:55 |
字数统计 2.1k 字 | 阅读时长 7 分钟

¶Carol Dweck: A Summary of Growth and Fixed Mindsets


  1. 从 费曼学习法 的末尾链接跳转到了这篇文章上,讲述的是 Carol Dweck的研究:关于智力是固定的还是可成长的观念的总结

有两种心态可以用来给我们的人生指引方向:成长和固定。拥有成长心态是成功必不可少的条件,在这个文章中,我们将会探索如何发展正确的心态来提高你的智力


  1. Carol Dweck 主要的研究方向是人类动机,她花费了很多时间研究为什么有的人可以获得成功以及有成功的哪些因素是我们可控的。她的关于两种心态(固定和成长)导致的结果差异令人惊讶。

  2. 像她自己表述的那样:“我的工作参杂了发展心理学,社会心理学,人格心理学以及验证人们用来直到自身行为的心态。我的研究是探索这些心态的来源,他们在行为动机和自我调节中扮演的角色以及它们对人们成就和人际交往的影响”。

  3. Carol Dweck的研究展示了我们所持有的基本信条的强大影响力。它们有意识或者潜意识地影响着" 我们追求的东西是什么以及我们能否成功得到它 "这种处于心态对自身的思考。这既在某方面推动了我们,也会在某些方面阻碍我们发挥自己的潜能

阅读全文 »

The Feynman Technique: The Best Way to Learn Anything(费曼学习法)

发表于 2020-06-16 22:02:34   |   更新于 2020-06-16 23:03:55 |
字数统计 1.4k 字 | 阅读时长 4 分钟

¶The Feyman Technique :The Best Way To Learn Anything


  1. 在 Google ‘the best way of learning knowledge’ 的时候看到了这篇文章,介绍了费曼学习方法,还用上了学习任意事物的最佳方法这样的形容词,就点开仔细看一下,确实是很科学的,质朴的学习方法,不过相比现在的快节社会而言,可能大部分人都做不到 (我也是 )

  2. 费曼学习法的四个步骤是:

    1. 确定你要学习/了解的知识点/概念
    2. 假设你将要把这个概念讲述给一个12,3岁刚好具备认知能力的学生听
    3. 鉴别你的理解断层,回到知识源,重新去理解
    4. 回顾并简化这个概念
  3. 停止学习你就会停滞不前,但是我们如何从学习中获得反馈?以及如何学习一个新的主题并且鉴别出自身已有知识的断层所在?

  4. 知识和认知:费曼明白了知道一件事物的名字和了解一件事物的区别,也是他取得成功的重要因素之一。我们多数人都关注了错误的认知方式,就是仅仅是知道一个事物,不会再有多的了解,并且认为这就是全部,学习的过程也就停止在这里;而正确的的认知方式是对一个事物有清晰明白的认识和了解–更加内在的精髓,这才是真正的对事物的认知

阅读全文 »
12…4
Joker Zou

Joker Zou

Follow your heart

39 日志
4 分类
45 标签
© 2020 Joker Zou
由 Hexo 强力驱动
主题 - NexT.Gemini
访客数 只 总访问量 回