bt365体育投注.主頁欢迎您!!

    <acronym id="zvmrr"></acronym>
    <td id="zvmrr"></td>
  • <tr id="zvmrr"><label id="zvmrr"></label></tr>
  • <acronym id="zvmrr"></acronym>
  • Mr.Z

    Mr.Z 查看完整档案

    填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
    编辑
    _ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

    个人动态

    Mr.Z 发布了文章 · 11月26日

    Mybatis日志功能是如何设计的?

    引言

    我们在使用mybatis时,如果出现sql问题,一般会把mybatis配置文件中的logging.level参数改成debug,这样就能在日志中看到某个mapper最终执行sql、入参和影响数据行数。我们拿到sql和入参,手动拼接成完整的sql,然后将该sql在数据库中执行一下,就基本能定位到问题原因。mybatis的日志功能使用起来还是非常方便的,大家有没有想过它是如何设计的呢?

    从logging目录开始

    我们先看一下mybatislogging目录,该目录的功能决定了mybatis使用什么日志工具打印日志。

    logging目录结构如下:

    ?

    它里面除了jdbc目录,还包含了7个子目录,每一个子目录代表一种日志打印工具,目前支持6种日志打印工具和1种非日志打印工具。我们用一张图来总结一下

    ?

    除了上面的8种日志工具之外,它还抽象出一个Log接口,所有的日志打印工具必须实现该接口,后面可以面向接口编程。定义了LogException异常,该异常是日志功能的专属异常,如果你有看过mybatis其他源码的话,不难发现,其他功能也定义专属异常,比如:DataSourceException等,这是mybatis的惯用手法,主要是为了将异常细粒度的划分,以便更快定位问题。此外,它还定义了LogFactory日志工厂,以便于屏蔽日志工具实例的创建细节,让用户使用起来更简单。

    如果是你该如何设计这个功能?

    我们按照上面目录结构的介绍其实已经有一些思路:

    1. 定义一个Log接口,以便于统一抽象日志功能,这8种日志功能都实现Log接口,并且重写日志打印方法。
    2. 定义一个LogFactory日志工厂,它会根据我们项目中引入的某个日志打印工具jar包,创建一个具体的日志打印工具实例。

    看起来,不错。但是,再仔细想想,LogFactory中如何判断项目中引入了某个日志打印工具jar包才创建相应的实例呢?我们第一个想到的可能是用if...else判断不就行了,再想想感觉用if...else不好,7种条件判断太多了,并非优雅的编程。这时候,你会想一些避免太长if...else判断的方法,但是mybatis却用了一个新的办法。

    mybatis是如何设计这个功能的?

    1. Log接口开始

    ?

    它里面抽象了日志打印的5种方法和2种判断方法。

    1. 再分析LogFactory的代码

    ?

    它里面定义了一个静态的构造器logConstructor,没有用if...else判断,在static代码块中调用了6个tryImplementation方法,该方法会启动一个执行任务去调用了useXXXLogging方法,创建日志打印工具实例。

    ?

    当然tryImplementation方法在执行前会判断构造器logConstructor为空才允许执行任务中的run方法。下一步看看useXXXLogging方法:?

    看到这里,聪明的你可能会有这样的疑问,从上图可以看出mybatis定义了8种useXXXLogging方法,但是在前面的static静态代码块中却只调用了6种,这是为什么?

    对比后发现:useCustomLogging?和?useStdOutLogging?前面是没调用的。useStdOutLogging它里面使用了StdOutImpl

    ?

    该类其实就是通过JDK自带的System类的方法打印日志的,无需引入额外的jar包,所以不参与static代码块中的判断。

    useCustomLogging方法需要传入一个实现了Log接口的类,如果mybatis默认提供的6种日志打印工具不满足要求,以便于用户自己扩展。

    而这个方法是在Configuration类中调用的,如果用户有自定义logImpl参数的话。

    ?

    ?

    具体是在XMLConfigBuilder类的settingsElement方法中调用?

    再回到前面LogFactorysetImplementation方法

    ?

    它会先找到实现了Log接口的类的构造器,返回将该构造器赋值给全局的logConstructor

    这样一来,就可以通过getLog方法获取到Log实例。

    ?

    然后在业务代码中通过下面这种方式获取Log对象,调用它的方法打印日志了。

    ?

    梳理一下LogFactory的流程:

    • 在static代码块中根据逐个引入日志打印工具jar包中的日志类,先判断如果全局变量logConstructor为空,则加载并获取相应的构造器,如果可以获取到则赋值给全局变量logConstructor。
    • 如果全局变量logConstructor不为空,则不继续获取构造器。
    • 根据getLog方法获取Log实例
    • 通过Log实例的具体日志方法打印日志

    在这里还分享一个知识点,如果某个工具类里面都是静态方法,那么要把该工具类的构造方法定义成private的,防止被疑问调用,LogFactory就是这么做的。

    ?

    1. 适配器模式

    日志模块除了使用工厂模式之外,还是有了适配器模式

    适配器模式会将所需要适配的类转换成调用者能够使用的目标接口

    涉及以下几个角色:

    • 目标接口( Target )
    • 需要适配的类( Adaptee )
    • 适配器( Adapter)

    ?

    mybatis是怎么用适配器模式的?

    ?

    上图中标红的类对应的是Adapter角色,LogTarget角色。

    ?

    LogFactory就是Adaptee,它里面的getLog方法里面包含是需要适配的对象。

    sql执行日志打印原理

    从上面已经能够确定使用哪种日志打印工具,但在sql执行的过程中是如何打印日志的呢?这就需要进一步分析logging目录下的jdbc目录了。

    ?

    看看这几个类的关系图:

    ?

    ConnectionLoggerPreparedStatementLoggerResultSetLoggerStatementLogger都继承了BaseJdbcLogger类,并且实现了InvocationHandler接口。从类名非常直观的看出,这4种类对应的数据库jdbc功能。

    类名

    对应功能

    ConnectionLogger

    Connection

    PreparedStatementLogger

    PreparedStatement

    ResultSetLogger

    ResultSet

    StatementLogger

    Statement

    它们实现了InvocationHandler接口意味着它用到了动态代理,真正起作用的是invoke方法,我们以ConnectionLogger为例:

    ?

    如果调用了prepareStatement方法,则会打印debug日志。

    ?

    上图中传入的original参数里面包含了nt等分隔符,需要将分隔符替换成空格,拼接成一行sql

    最终会在日志中打印sql、入参和影响行数:

    ?

    上图中的sql语句是在ConnectionLogger类中打印的

    那么入参和影响行数呢?

    入参在PreparedStatementLogger类中打印的

    ?

    影响行数在ResultSetLogger类中打印的

    ?

    大家需要注意的一个地方是:sql、入参和影响行数只打印了debug级别的日志,其他级别并没打印。所以需要在mybatis配置文件中的logging.level参数配置成debug,才能打印日志。

    彩蛋

    不知道大家有没有发现这样一个问题:

    LogFactory的代码中定义了很多匿名的任务执行器

    ?

    但是在实际调用时,却没有在线程中执行,而是直接调用的,这是为什么?

    ?

    答案是为了保证顺序执行,如果所有的日志工具jar包都有,加载优先级是:slf4j?》commonsLog?》log4j2?》log4j?》jdkLog?》NoLog

    还有个问题,顺序执行就可以了,为什么要把匿名内部类定义成Runnable的呢?

    这里非常有迷惑性,因为它没创建Thread类,并不会多线程执行。我个人认为,这里是mybatis的开发者的一种偷懒,不然需要定义一个新类代替这种执行任务的含义,还不如就用已有的。
    原文:https://mp.weixin.qq.com/s/HV...

    推荐阅读

    全网找不出第二份能把Mybatis讲解这么详细且图文并茂的PDF,开放分享

    50W年薪程序员需要的技术栈分析

    关于【暴力递归算法】你所不知道的思路

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月26日

    距离 2020 年结束不到2个月,字节跳动员工却在闲鱼卖内推名额登上热搜!

    距离 2020 年结束不到2个月,字节跳动决定再举大力“招兵买马”,甚至员工在闲鱼卖内推名额登上热搜!

    脉脉研究院今年发布的《互联网人才流动报告2020》显示,字节跳动是互联网公司中对人才需求量最大的公司之一,显著超过阿里和腾讯。

    其中,字节跳动是技术岗位招聘量最大的企业,而Java资深工程师的平均薪资高达¥26.9K/月。

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    在Java程序界流行着一种默认的说法叫“黄金5年”,意思是:一个Java程序员从入职的时候算起,前5年你的选择直接影响着整个职业生涯的发展方向和薪资走向。

    • 1-2年:需深入了解Java底层和Java类库
    • 3-4年:提升代码能力难,需深入钻研某一项技术
    • 4-5年遇到“技术瓶颈期”,需提高就业背景

    而这5年,也决定了你能否成为职业大牛。那么,在这“黄金5年”里,Java程序员如何做才能实现自我突破呢?

    想要“事半功倍”突破瓶颈,你需要一位非常有经验的前辈指导方向,否则就是盲人摸象事倍功半。

    经过一朋友的透露,阿里巴巴团队首发了一份限量的“Java升级笔记”,里面记载的知识点非常齐全,看完之后才知道,差距真的不止一点点!

    Java升级笔记主要是将Java程序员按照年限来进行分层,清晰的标注着Java程序员应该按照怎样的路线来提升自己,需要去学习哪些技术点。

    由于细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!需要完整版的朋友可以点赞此文后在公众号【Java斗帝】回复666 免费获取;

    Java升级笔记大致内容如下:

    入门(0-2年):

    • 面试指南(简历应该如何写+如何准备面试+我的学习方法)
    • 扎实的Java基础?(面向对象+Java的超类+Java的反射机制+异常处理+集合+泛型+基础IO操作+多线程+JDK新特性)
    • 网络知识(计算机网络技术+HTTPS中的TLS)
    • 数据结构与算法
    • 必会工具(Git+Docker)

    初学(2-4年):

    • 并发编程(并发工具类实战+CAS+显示锁解析+线程池内部机制+性能优化)
    • JVM深度剖析(理解运行时数据区+堆外内存解读+JDK+内存泄漏问题排查+Arthas+GC算法和垃圾回收器+类加载机制等)
    • 数据库(MySQL+Redis)
    • 中间件&分布式(dubbo+MQ/kafka、ElasticSearch、SpringCloud等组件)
    • 深入Tomcat底层
    • 接触互联网项目实战(RestFul API+常用框架+认证授权+分布式+大型网站架构+微服务)

    进阶(4-7年):

    • 开源框架(Spring5源码+SpringMVC源码+Mybatis源码)
    • 分布式架构(Zk实战+RabbitMQ+RocketMQ+Kafka)
    • 高效存储(Redis+mongoDB+MySQL高可用+Mycat+Sharing-Sphere)
    • 微服务架构(RPC+SpringBoot+SpringCloud Netflix+SpringCloud Alibaba+docker+k8s)

    10年以上送外卖:开个小玩笑

    入门(0-2年):

    1、面试指南

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    2、扎实的Java基础

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    3、网络知识

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    4、数据结构与算法

    这是有本专门学习算法的笔记:刷Github时发现了一本阿里大神的算法笔记!标星70.5K

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    6、必会工具

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    初学(2-4年):

    1、并发编程

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    2、JVM深度剖析

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    3、数据库

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    4、中间件&分布式

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    5、深入Tomcat底层

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    6、接触互联网项目实战

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    进阶(4-7年)架构:

    1、开源框架

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    2、分布式架构

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    3、高效存储

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    4、微服务架构

    身为程序员,该如何搭上字节跳动这辆“印钞机”列车??

    如果想要入职字节必不可少的当然是算法了,推荐阅读:

    刷Github时发现了一本阿里大神的算法笔记!标星70.5K

    程序员50W年薪需要掌握的技术有哪些?

    写在最后

    如果你想利用好这“黄金5年”,或者是不想在中年时焦虑的话,那么这份“Java升级笔记”可能需要你用心参考一下;(需要完整版的朋友可以点赞此文后在公众号【Java斗帝】回复666 免费获取;)

    有人能在35+的“高龄”活出自我,找到崭新的平台,得到更好的岗位,登上人生的新高度。有人却只能默默挣扎在35岁的魔咒里无法自拔,觉得天下之大竟没有自己的容身之所。

    这一切的区别还是在个人的能力和履历,如果能力优秀,履历漂亮,相信没有哪家公司能拒绝。在还能努力的时候,拼命为自己的履历而奋斗吧!

    预祝各位可以早日实现自己的大厂梦,实现自己的人生价值;

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    ?

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月25日

    Alibaba官方发文:阿里技术人的成长路径与方法论

    简介:???有一句诗词说:宠辱不惊,看庭前花开花落;去留无意,望天上云卷云舒。其实就是讲内心修炼到了一种心境平和,淡泊自然的境界。

    为什么要成长

    成长是为了在职场升值,提升职场竞争力!

    **衡量标准:你成长的速度要匹配甚至超越业务发展的速度。
    **
    当你成长速度超越业务发展速度的时候,组织才会把更重要的职责交给你,如果你成长的速度跟不上业务发展的速度,可能会面临被调整。

    成长的维度

    image.png?
    阿里的技术人绝大部分是做业务技术的,即业务和技术要同时发展,纯技术发展路线是指中间件、数据库、操作系统、硬件之类的实打实的技术。阿里对业务技术人的要求,既要有技术的深度,又要有业务的高度,此外还需要你有领导力、影响力等软技能,当然心态也是不容忽视的。

    我的代表作是 MOZI ,2018 年年初开始做 MOZI ,我选择做 MOZI 的原因是我就要开始站在业务线或者公司层面去思考,MOZI 做了会给业务带来什么改变。
    image.png?
    做 MOZI 的时候是站在经济体的的角度在思考问题,另外那个时候经济体的云化产品化才刚刚开始,做出 MOZI 提供一套统一解决方案正逢其时。

    技术的深度

    image.png?
    我们是做业务技术的,业务技术如何做得更加“技术”,这里我学习了很多大牛的文章,尤其是张建飞大师对我启发非常大。这里我总结下两点:

    1 . 业务复杂度:“基于复杂业务场景的抽象能力”是一种能体现你技术深度的能力,业务的本质是模型,如果我们能基于复杂业务场景抽象出领域模型或者基于复杂业务场景做流程编排,做好分层,不仅反映你对业务认知的深度,也反映了你的技术深度。

    2 . 技术复杂度:“针对大用户量或者大数据量的可用性建设”这个是能很好的反映你的技术深度,但是我们在做这一块的时候要有一些创新性的思考,可用性年年做,但是基于新的业务场景会有什么不一样?比如 MOZI 提供了一个多租户&多账号的能力,那么我们做限流的时候是不是可以按租户限流,做缓存逐出的时候可以按租户来进行逐出,一种特别的租户我们可以区分对待。这些都是我们要去思考的问题,不能总是吃老本。

    另外我们其实都是属于“应用架构”领域的,张建飞大师总结的应用架构的道是:“核心业务逻辑和技术细节分离”,我觉得非常有道理,我们应该应用分治的思想,把业务和技术做分离,从而降低系统的复杂度。

    业务的高度

    image.png?
    马云曾说,我们既要能活在当下,又要有远大的理想,活在当下是一种务实,让客户先赢。远大的理想是我们长期发展的路线,也非常重要,背后体现你的一种“务虚”的能力。

    为什么优秀的业务开发人员一定要有“想法”?如果没有想法,基本上就是产品经理安排什么,然后就做什么,不会考虑未来的发展,也不能很好的培养你的业务敏锐度,更加不会有前瞻性。什么是前瞻性,就是你思考的东西和业务真正发展的路径其实是一致的,那么就是有很好前瞻性。如果你思考的东西和业务发展背道而驰,那其实不叫前瞻性。

    另外我们在做业务的时候,业务沉淀是非常重要的。阿里有句土话说,“规模可复制的结果才是好的结果”,你做的东西能不能影响更多的人,就看你的业务沉淀如何,如果你做的东西一年后经过几次改版都消失不见了,那其实没有什么沉淀。

    那么我们应该如何去做业务规划?注意这里的业务规划不是产品经理的规划,也不是你老板的规划,是你自己的规划。分享两点:

    一、要结合你当前的业务,不能脱离现状谈规划;

    二、要去参考你的行业标杆,我们可以借鉴别人的成功理念,然后融入到我们的业务场景里面。

    首先结合 MOZI 的两块业务,一块是经济体客户,一块是政务客户,另外我参考了 MOZI 的行业龙头来做的规划:

    软技能

    我们的软技能大体分为两部分:一种是影响他人的能力,主要是领导力&影响力;

    另外一种是强化自己的能力,比如结构化思维,抽象能力和构建认知坐标,最终你会具备一眼看穿本质的能力。
    image.png?

    领导力

    领导力是一种人人应该具备的能力,但是与你有没有领导力有很大的关系。那么到底什么是领导力,我觉得领导力就是“一种说服并且引领他人达成目标的能力”。
    image.png?
    领导力的提升核心就是上面这张图,这个图其实叫做乔哈里视窗,也叫沟通视窗,本质是一种关于沟通的技巧和理论,领导力的核心其实是沟通,通过沟通建立信任,从而来引领别人一起去达成目标。乔哈里将人际沟通信息划分为四个区,分别是公开象限,隐私象限,盲点象限和潜能象限。我们应该不断的从别的象限拿出一点东西然后放到公开象限里面去,让公开象限放大,这样你的领导力就提升了,比如国家领导人和明星,他们的公开象限就非常大。

    隐私象限:

    隐私象限就是自己知道但是他人不知道,把隐私象限往公开象限里面挪动最重要的方式就是自我揭示。比如你写个人成长经历,或者和同事聊聊你的过去,就是一种很好的自我揭示的方式,让别人更了解你是一个什么样的人,从而建立信任。

    盲点象限:

    盲点象限就是自己不知道但是他人知道,把盲点象限往公开象限里面挪动最重要的方式是恳请反馈。

    比如两夫妻吵架,妻子说你这人的嘴特损,就喜欢说人缺点。丈夫说“有吗,我从来没觉得”。后面丈夫去找朋友确认:“我妻子说我嘴特损,专门喜欢说人缺点,有这回事吗?”,朋友说“别把嫂子的话放在心上,大家都已经习惯了~~~”。哈哈,这里其实就是在吵架这种场景下发现了一个人的盲点象限。比如在分享的时候,我们要让听分享的人给你反馈,这个时候就能很好的发现分享人的盲点象限,从而提升你自己。

    潜能象限:

    大家都说人的潜能是无限的,我们应该去挖掘他。你们知道巴菲特最佩服的人是谁吗?他最佩服的是弗吉尼亚的一个老太太,这个老太太在88的时候开始创业,没看错就是88岁,她创建了弗吉尼亚毛毯厂,带人开始织毛毯,他从88岁一直干到104岁去世,公司做到了几百人的规模,获得和很大的成功,去世的时候她依然是CEO。这个故事其实就很好的说明,人的潜能是无限的,这个老太太88岁还在不断的学习和实践。那么怎么去从自己的潜能象限里面挪动一部分到公开象限呢,最重要的就是不断学习和实践,让你终身成长。

    阿里其实也有一套领导力的方法论:
    心力:其实是让大家对这件事情内心一致认同;

    脑力:是对事情的深度思考;
    体力:是引领大家把事情做好,拿到结果。

    用阿里土话就是“一群有情有义的人一起做一件有价值的事情”。这个事情有没有价值,你要去说服别人,说服完后要引领大家做出来。这个和前面的领导力“一种说服并且引领他人达成目标的能力”,其实是差不多的。

    影响力:

    影响力包含两个维度:一个是你做的产品影响力;另外是你的个人影响力。

    image.png?
    产品影响力:某大佬曾说,你做的东西影响范围如果只能影响 1 米和你能影响 100 米,甚至你做的东西能影响 1 公里,意义完全不同。所以你做出来了东西,要想办法去找资源横向放大你的价值,这个非常重要,比如你可以去写文章,去做分享,去找运营帮你写稿子。我在做 MOZI的 时候,我组织了 4 次视频分享,组织大家写了几十篇文章,然后还特意找了 ATA 的运营去帮忙推广 MOZI ,不然 MOZI 可能还是会名不见经传。

    个人影响力:影响力其实就是一种影响他人的能力,这里一个很重要的就是表达,把你的内心的东西通过一定的途径表达出来,表达最核心的东西其实就是“能说”加上“会写”。

    能说:你去现场演讲,你去做做直播,都是锻炼你的“能说”。

    会写:你去写文章或者写书都是锻炼你的“会写”。

    我们应该通过这两种途径不断的去提高你的个人影响力。

    结构化思维

    image.png?

    表达要有逻辑

    表达我们要条理清晰,你在晋升的时候要能把你自己领域的东西让别的领域的评委也能听得懂,这个就需要不断的强化你的表达能力,这里罗列了四种常见的思想组织逻辑。因果顺序,时间顺序,空间顺序和程度顺序。

    我给别人传达的一种思想是按照时间+空间的顺序:

    时间:从3年前到现在

    空间:我从服务阿里集团,到服务阿里经济体,再到服务中国政府
    事情:我全部是围绕着账号&权限这块来展开,塑造一个领域专精的形象

    这么一讲,思路就非常清晰,后面的PPT也都按照这个来展开。

    做事要有方法论

    不同领域都有前辈高人总结的方法论,我们应该学习他,会让我们做事做的更好。比如我们分析问题常见的“5W2H”模型,还有我们定KPI的时候的SMART模型,就应该经常要使用它。

    比如我在讲我的PPT的时候,也是应用了“ 5W2H 的模型”,我做了 BUC ,那么我怎么去讲 BUC 呢。这里不能一上来就讲我在 BUC 里面做了什么,而要先讲 WHY ,讲清楚了 WHY ,后面讲成果的时候就水到渠成。好的 PPT 其实是每一页都要讲 WHY 。“ BUC 的业务特点”这部分其实就是 WHY ,然后在“我应该做什么”这部分是 WHAT ,最后我获得了一些奖项是 HOW。

    抽象能力

    image.png?
    万物皆抽象,抽象能力让你可以化繁为简,从而抓住事物的本质,也能体现一个人的格局,所以我们要特别注重这种能力的训练。

    柏拉图的学生问柏拉图,什么是人?柏拉图想了一会儿说:“人是可以直立行走的两腿无毛动物”。第二天,他的学生带过来一只拔了毛的公鸡,这个也符合柏拉图对人的定义。直立其实是抽象程度还不够,没有抓住本质。

    如何进行抽象?这里其实就三招:

    1、通过对比寻找共性,把共性提炼出来
    2、如果没有共性了,那么就提升抽象的层次,往上提升,比如植物和动物再往上提升就是生物。
    3、最终构建出一个金字塔
    大家可以学习《金字塔原理》这本书,基本就这个套路。

    那么如何如何提升抽象的能力呢?

    1、多学习

    据说巴菲特一天会花超过5个小时进行学习。“樊登读书会”希望带领国人每年读50本书。文字的东西最具有想象力,在阅读的过程中多思考,抽象能力就慢慢提升了

    2、多总结并写作

    总结是一种提炼,一种归纳。总结后并且写出来无形中会让你抽象能力提升更快。所以我们要多写文章。

    3、领域建模训练

    对于我们技术同学来说,领域建模其实就是一种抽象的过程,把核心业务逻辑抽象出来并沉淀到领域层,这样可以极好的帮助我们去提升抽象的能力。

    人的大脑其实有超过 1000 亿个神经元,神经元和神经元其实是有连接的。学习和总结的过程会让你的神经元和神经元之间建立更多的连接,从而产生群智效应。

    构建认知坐标

    image.png?
    构建认知坐标是一种比深度思考更加重要的思维方式。我们看待一个事物,要看过去,看现在,看本质和看未来。

    看过去

    这个事情在过去是不是就已经存在,丘吉尔说:“看得到过去有多远,就能看得到未来有多远”,很多大牛其实都在不断的研究史书,借鉴过去的成功经验来探索未来。所以我们研究竞品的时候也一定要去研究竞品的历史,他的存在和成功肯定是有历史的原因的,不能一上来就去研究他一堆功能,功能只是一个表象。

    看现在

    王兴说:“每个行业在不同时代都值得重新做一遍”。这句话很有道理,比如“新闻”这个领域,没有互联网前是用报纸来传递,后面出现了“四大门户”,现在的“今日头条”,不同的时代会出现不同的产品形态。我们做产品要抓住时代的节点和规律,顺势而为。

    看本质

    任何事物都有表象和本质之分,我们要剥开层层迷雾,抓住他的本质,这样才能以不变应万变。比如MOZI里面有个认证,认证的本质其实是证明你是你。至于在不同的时代肯定有不同的证明方式,比如传统的账密,现在的扫脸,还是其他的一些生物识别等方式,都是证明你是你的一种形式而已。

    看未来

    历史的车轮滚滚滚向前,新时代一定会出现一些新的事物,然后让你的产品会有新的形态,所以我们要有一定的预见性,去大胆假设,小心求证,从而抓住未来的发展机会。

    一眼看穿本质的能力

    image.png?
    这种能力其实非常难得。

    《教父》里面一句话影响了很多人:“花半秒钟就能看透事物本质的人,和花一辈子都看不清事物本质的人,注定是截然不同的命运”

    训练这种能力有3个步骤:

    1 . 善于找到某一个领域的节律(节点和规律)

    如果你找准了色彩的节律,你会成为画家或者厉害的设计师;

    如果你找准了文字的节律,你会成为作家或者小说家;
    如果你找准了生命的节律,你会成为很养生家或者厉害的医生;
    如果你找准了商业的节律,你会成为投资人或者企业家;
    如果你找准了社会的节律,你会成为政治家;
    如果你找准了软件的节律,也许你也会成为XX之父。

    梵高和毕加索都是才华横溢的画家,但是梵高一生贫困潦倒,一生只卖出一幅画,死后才出名。毕加索辉煌一生,死后还留下几十亿美元的遗产。同样的才华但是有截然不同的命运,梵高没有抓住时代的节律,而毕加索抓住了,他创造了属于这个时代的作品。

    新能源汽车其实在 100 多年前就已经出现了,但是被燃油机的汽车打败了,那个时候发现了大量的油田,汽油极其的便宜,大家也不重视环保,所以新能源汽车昙花一现。现在由于能源的枯竭和污染的严重性,新能源汽车开始重新走向辉煌。所以 100 多年前新能源汽车没有抓住时代的节律,但是现在终于抓住了。

    那么如何去训练这种能力呢?方法是找到这个领域最经典的100个案例,反复的探索和钻研,不断总结其中的共性和特性,就能悟出其中的节律。记住一定要找最经典了,最经典是经过时间考验的,越经典越接近事物的本质。

    你要做广告,就研究最经典的 100 句广告词,仔细探索和对比,找到共性部分。
    你要做音乐,就去研究 100 首最经典的歌曲,去找到他的音律的共性部分。
    如果你要去创业,就去研究 100 个最经典的创业案例,仔细探索和对比。

    1. 找到不同领域的之间的共同规律

    当你精通某一个领域后,你研究别的领域发现也相对容易,因为很多东西其实是相通的,比如达芬奇就在绘画,植物、光学等很多领域都取得了辉煌的成就。

    1. 你要从万变中找到不变

    人们常说“万变不离其宗”就是这个道理,当你到了这个层次,别人看到的是变化,你看到的是不变。

    举个例子:商业模式千变万化,但是人性是不变的,所以很多的商业模式几乎都是围绕着不变的人性来展开的。

    在出行领域,最有名的是滴滴出行,现在又出现T3,花小猪这些平台。那么他们是怎么围绕着不变的人性展开的呢?

    T3 和滴滴出现的差异是,T3 的司机是一种上班的模式,司机上班 8 个小时,公司提供五险一金,有底薪,这种人追求的是一种安稳和保障。滴滴出行的司机是自由的,他们不喜欢被约束,但是没有保障。花小猪其实也是滴滴旗下的,他的特点是一口价,起点和终点确定后,不管你有多少红绿灯,是否堵车都不影响价格,那么坐花小猪的人其实是追求一种确定性,他们往往不太喜欢不太确定的东西。所以这里的人性有追求自由的的司机,追求有保障的司机,和追求确定性的乘客。

    心态

    image.png?
    我们在日常工作中很多人其实忽略了心态的历练。一个人能走得有多远,能力是一方面,其实心态更加的重要。

    我们都看过《西游记》,孙悟空神通广大,一个筋斗十万八千里,还会72变,唐僧从大唐去西天取经其实也是十万八千里,那么为什么孙悟空不背起唐僧一个筋斗就翻到西天呢?还要经历九九八十一难干嘛呢?

    其实真正看懂《西游记》的人都知道,孙悟空压根不存在,《西游记》其实是唐僧一个人修佛的过程。有个成语叫做“心猿意马”,孙悟空就是唐僧的“心猿”,白龙马就是唐僧的“意马”。孙悟空的 72 变,其实就是心的 72 中变化。心的力量很强大,比如我们想一下“纽约”,心就飞到“纽约”了,想一下“莫斯科”,心就飞到“莫斯科”了。心很难管控,孙悟空动不动就要脱离队伍,要回花果山,所以为了管控,观音给孙悟空带上了“紧箍咒”。

    猪八戒其实是唐僧的“欲望”,他贪财好色。沙和尚其实是唐僧的“逻辑和理性”,所以沙和尚很没意思,但是每句话都是对的,比如,“大师兄,师傅被妖怪抓走了”,“大师兄,二师兄被妖怪抓走了”,“大师兄,师傅和二师兄都被妖怪抓走了”。

    最终孙悟空修成了斗战胜佛,是讲唐僧修佛有成,战胜了自己的内心,孙悟空对观音说,能不能把我的紧箍咒取掉,观音微微一笑,你看你头上还有紧箍咒吗?孙悟空一摸,果然没有了,所以修心有成后,心灵的枷锁自然就去掉了。

    阿里对心态的要求是乐观、皮实和自省。

    乐观:万事万物有高潮就有低谷,我们要乐观的看待,没有什么事情是一帆风顺的,人生不如意十之八九。

    皮实:遭遇人生的挫折的时候还能及时调整就是皮实,比如被人批评了,被人挑战了,被DISS了,晋升失败了,被打3.25了,都是挫折,这个时候要能及时调整心态。我们要在工作和生活中把遇到的每一个人,每件事都当作是一次人生的修炼。

    自省:就是一种复盘,及时的总结和思考过去的得与失。这里最忌讳两种,一个是从不自省,觉得自己是最厉害的。

    一种是自省过头了,感觉自己这也不行,那也不行,对自己一味的否定。所以我们要喜欢自己,欣赏自己。

    有一句诗词说:宠辱不惊,看庭前花开花落;去留无意,望天上云卷云舒。其实就是讲内心修炼到了一种心境平和,淡泊自然的境界。

    成长方法论

    image.png?

    成长方法论遵循721原则。

    70%做中学

    不穷曾说:做得多会有更深的体会,思考得多会有更多的沉淀。说的非常有道理。

    所以我们首先一定要做,不能光说不练,有的时候思路没有很顺畅的时候,可以先尝试去做一点东西,做着做着就有思路了。另外在做的时候要思考,思考主要有两个维度:

    第一,下次如何把这个工作做得更好,这次这个工作做完了,代码已经写完了,但可不可以让它更漂亮,效果更好,这是一方面。第二个问题,能不能让这份工作更高效,把这份代码写完之后上去时,想下次能不能以更短的时间完成。只要问自己这两个问题,会发现有很多答案,这个答案再带入到下一个字,行。也就是在你工作过程中,下一个轮回时再去做时,同时观察自己,再提自己问题。有了这个循环之后,你会发现自己的工作越做越好。

    20%向他人学习

    听听牛人的分享,看他们的文章,多和不同的人进行交流,然后总结沉淀下来。

    10%自学

    自己参加培训和看书,然后写作和分享,分享会让你把学习到的东西真正的变成自己的东西。

    没有海量的输入,怎么会有高质量的输出,所以你不读书是写不出什么好文章的。

    阿里成长方法论

    image.png?
    阿里价值观的底层思想其实是借鉴了 释(佛)、儒、道三种思想:
    释(佛家):处理好人与心的关系,我们要战胜自己;
    儒(儒家):处理好人与人的关系,我们要团结好他人;
    道(道家):处理好人与自然的关系,我们应该顺势而为。

    价值观分为3层:最底下一层解决人与心的关系,让每个人成为更好的自己;

    第二层解决人与人的关系,让每个人可以更好的和他人合作;

    最上层其实是基于下面两层的,只有每个人搞定了自己也搞定了合作伙伴,那么服务起客户来肯定会如鱼得水。价值观20条,如果我们都按照上面去做,肯定会让你在职场变得不一样。

    原文:https://my.oschina.net/yunqi/blog/4727650

    推荐阅读

    为什么阿里巴巴的程序员成长速度这么快,看完他们的内部资料我懂了

    程序员达到50W年薪所需要具备的知识体系。

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月25日

    为什么说应用架构需要分类思维?

    简介:如何定义架构?应用架构的要素有哪些?什么是应用架构中的分类思维?开源应用架构COLA的作者张建飞介绍他在COLA架构设计中的一些思想经验,分享他的应用架构之道。

    模块(Module)、组件(Component)、包(Package),这些概念对于我们技术同学并不陌生,但并不是所有人都能理解其要义。

    深入理解之后,我才发现,其背后的深意是分类思维。而这种分类也是应用架构的核心所在,通过不同粒度、不同层次的分类,把复杂的软件系统实现控制在可以被理解、被维护的程度。否则,对于动则上100万行代码的软件,人类根本没有办法理解和维护。

    试想一个极端情况,假如没有这些概念协助我们分类,我们把所有业务逻辑都写在一个类里面,会是什么样的结果呢?我们很多的“非人类”系统,正是因为没有进行合理的分类造成的。

    早期,我不喜欢JavaScript的一个重要原因,正是因为其缺少像Java中package和jar的概念,导致代码的组织形式比较松散、随意。这个问题直到ES6、React才得到比较好的解决,在此之前,前端工程师不得不依靠seaJS,requireJS这些框架来做模块化、组件化的事情。

    至此,你可能有疑问,分类有什么魔力?怎么就成了应用架构的核心了呢?客官别着急,由我细细道来。

    分类的重要性

    所谓分类,就是依据一定的标准对给定的事物进行组别的划分。我们人类天生就有分类的本能,例如,当我们观察下面这张图的时候。

    image.png?

    无论是谁,乍一看到上面的六个黑点,都会认为共有两组墨点,每组三个。造成这种印象的原因主要是,人类大脑会自动将发现的所有事物以某种持续组织起来。基本上,大脑会认为同时发生的任何事物之间都存在某种关联,并且会将这些事物按某种逻辑模式组织起来。

    之所以我们大脑有这样的本能,是因为人一次能够理解的思想或概念的数量是有限的。正如乔治米勒在他的论文《奇妙的数字7》中提出的。人类大脑的短期记忆无法一次容纳7个以上的记忆项目。所以,当信息量过大时,唯有归类分组才能帮助我们去理解和处理问题。

    其实,自古及今,人类一直在做着归类/分类,早在春秋时期,《战国策》中就提出过“物以类聚,人以群分”的概念。

    在互联网行业,我们会对客户进行分类,然后针对不同的客户进行分层运营,也是这个道理。

    平常我们所说的分析和综合的背后,其实就是分类能力。分析是在一个类里面找差异性,综合是在不同事物中找联系、找共同性,而这个共同性相当于分类的维度。

    分类思维的能力,直接体现的就是看透事物本质的能力。

    应用架构中的分类思维

    概念定义

    在讨论架构之前,我们先来明确一下Module、Component和Package这几个概念。

    因为这些概念一直以来存在不小的歧义。通过Stack Overflow上几十篇询问这些概念差异的提问,以及五花八门的回答就能可见一斑。

    在一篇Stack Overflow的帖子[1]中,我们看到这样的回答:

    The terms are similar. I generally think of a "module" as being larger than a "component". A component is a single part, usually relatively small in scope, possibly general-purpose.

    然而,另一篇Stack Overflow的帖子[2],却有着不同的答案:

    There is no criteria to measure which one is greater than the other. One component can contain list of modules, and one module also can contain many components.

    在《实现领域驱动设计》一书中,作者有这样的描述:

    If you are using Java or C#, you are already familiar with Modules, though you know them by another name. Java calls them packages. C# calls them namespaces.

    然而,在AngularJS的设计文档[3]中,它对Module和Component是这样定义的:

    The module can be considered as a collection of components, Each component can use other components. One of many modules combines up to make an Application.

    image.png?

    通过比较,结合我自己的认知,我更赞同AngularJS里面的定义,即Module是比Component更大的概念。比如在Maven中,Module是组成Application的第一级层次,而Component的粒度一般比Module要小,多个Component会组成一个Module。

    因此,在进一步探讨之前,我特意对这些概念做如下定义:

    • 应用(Application):应用系统,有多个Module组成,用方框表示。
    • 模块(Module):一个Module是有一组Component构成,用正方体表示。
    • 组件(Component):表示一个可以独立提供某方面功能的物件,用UML的组件图表示。
    • 包(Package):Package相对比较tricky,它是一种组织形式,和粒度不是一个维度的,也就是说,一个Component可以包含多个Package,一个Package也可以包含多个Component。

    基于上面的定义,他们的表示法(Notation)是这样的:

    image.png?

    应用架构的要素

    关于架构的定义有很多,我最喜欢,也是最简洁的定义是:

    image.png?

    即架构是一种结构,是由物件(Components)+ 物件之间的关系 + 指导原则组成的。

    应用架构也是如此,从大的层面来说,企业级应用都逃不过如下图所示的三层结构,即前端、后端和数据库。

    image.png?

    对于后端开发来说,应用层是我们的主战场,也是整个系统最复杂的部分(当然,前端也不简单),所有的业务逻辑都汇聚在此。所以,对于应用层,我们需要进行进一步拆分,而不仅仅是在这里写业务逻辑就完事了。

    对应用层的进一步分层,就形成了COLA所提倡的四层结构,对应到Maven中,就是有4个Module,编译打包之后会有4个Jar。一个典型的应用,其Module呈现出如下的结构:

    <modules>
            <module>cloudstore-adapter</module> <!--Adapter 层--> 
            <module>cloudstore-app</module>  <!--App 层--> 
            <module>cloudstore-domain</module>  <!--Domain 层--> 
            <module>cloudstore-infrastructure</module>  <!--Infra 层--> 
            <module>cloudstore-client</module>  <!--RPC SDK--> 
            <module>start</module>  <!--SpringBoot启动--> 
    </modules>

    当业务变得复杂时,这种分层结构自然比没有分层要好。这也是COLA一直致力要去解决的问题——控制复杂度。

    从COLA 1.0的事无巨细,到COLA 3.0的化繁为简。我渐渐明白,COLA作为应用架构,其核心不是去提供功能,而是提供基模(Archetype)。

    在1.0的时候,COLA提供了Interceptor能力,提供了Event Bus能力,提供了扩展点能力。一个是我认为大家“需要”这些,另一个是感觉NB的框架就应该面面俱到,没有几个高级功能都不好意思开源。事实证明,我犯了一个惯性错误——过度设计。Interceptor完全可以用AOP替代,内部事件和扩展点很少被用到。所以在COLA 3.0的时候,果断的去掉了这些“鸡肋”,只保留了扩展点功能。

    回归到架构的本质,COLA的核心应该是规定应用的结构和规范,即应用架构基模(Archetype)。而不是去纠结那些锦上添花的功能。

    升级到COLA 3.1

    实际上,这样的回归工作,COLA 3.0已经做的差不多了。在这次3.1的升级中,除了进一步去除了Event Bus的功能之外,最重要的就是重新规范了分包策略,和扩充了原来控制层(Controller)的职责。

    分包策略调整

    分层是一种在功能维度上的横向切分,即每一层都有自己的职责。

    • Adapter层:路由用户request + 适配response。
    • App层:接收请求,联合domain层一起做业务处理。
    • Domain层:领域模型 + 领域能力。
    • Infrastructure层:技术细节(DB,Search,RPC..) + 防腐(Anti-corruption)。

    分层处理没有问题,只是这种功能划分,会带来一个问题,即领域维度的内聚性会收到影响。当一个application只负责一个领域的时候没有问题。然而,当一个application包含多个业务领域的时候,这种内聚性缺失的弊端就比较明显了。

    更好的分包策略是按领域划分,而不是按功能。因为,领域更内聚,功能是为领域服务的,应该归属于领域。

    然而,不巧的是,在COLA应用架构里面,我们要综合横向功能维度的划分,和纵向领域维度的划分,两个都很好,两个都想要。怎么办?我们可以采用物理划分和逻辑划分相结合的办法。

    横向上,我们用Module做有层次划分,属于物理划分。纵向上,通过Package来进行逻辑划分。最后,形成一个如下的结构:

    image.png?

    按照这个思想去分包,在工程中,Module下的顶层package不再是功能,而是领域:

    image.png?

    按照领域的分包策略至少会带来两个好处:

    • 系统的可理解性和可维护性更好,用白话说,就是找东西更好找了。
    • 方便以后的拆分,比如下单域(Order)变得越来越复杂,需要拆出去,我们只需要把Order下面的东西迁移到一个新应用就好了。

    用Adatper代替Controller

    Controller这个名字主要是来自于MVC,因为是MVC,所以自带了Web应用的烙印。然而,随着mobile的兴起,现在很少有应用仅仅只支持Web端,通常的标配是Web,Mobile,WAP三端都要支持。

    在这样的背景下,狭义的控制层已经不能满足需求了,因为在这一层,不仅仅要做路由转发,还要做多端适配,类似于六边形架构中的Driving Adapter的角色。鉴于此,我们使用适配层(Adapter)替换掉了Controller,一方面,是为了呼应六边形架构;另一方面,的确也是需要做多端适配。

    基于这样的变化,我重构了COLA Archetype,把Adapter作为一个层次凸显出来。实际上,Infrastructure也是适配器,是对技术实现的适配(或者叫解耦),比如,我需要数据来帮助构造Domain Entity,但是我不care这个数据是来自于DB、RPC还是Search,或者说,我可以在这些技术实现中进行自由切换,而不影响我Domain层和App层的稳定性。

    改造后的COLA在架构风格,模块、组件以及分包策略上都会有所调整,具体变化请参考下面两张图。

    COLA架构图:

    image.png?

    COLA3.1

    COLA组件关系图:

    image.png?

    组织架构中的分类思维

    这么重要的思维能力,其应用肯定不仅仅局限于架构设计的范畴。开篇已经说过了,分类是我们人类的本能,是分析和综合问题的重要手段。

    生产关系决定生产力,好的组织结构会助力业务发展,反之,则会拖业务的后退。因此,大公司的CEO每年都会花很多时间在组织设计上,这也是为什么,在大厂,每年我们都会看到不小的组织调整。

    看到一篇文章《苹果公司的组织架构是怎样的》[4],里面介绍了苹果成功和其优秀的组织架构有关系。如下图所示,传统企业偏向于业务型组织,而高科技企业偏向于职能型组织。

    image.png?

    有没有感觉苹果的组织架构,和我们的COLA思想是一样的:),物理上,按照职能划分;逻辑上,按照业务和产品划分。

    苹果这样的组织设计,是因为它是技术和创新驱动的公司,协作成本不是最大的问题,缺少专业性(技术不行),缺少创新才是攸关生死的大问题。所以他宁肯牺牲协同效率,也要确保专业性,也就是说,做摄像头的只做摄像头,做iOS的只做iOS,技术leader直接向CEO汇报,可以决定产品的发展方向。因为他们在这个领域更专业。

    很早以前,史蒂夫·乔布斯就有这样的观点:苹果公司的经理们应该是他们管理领域的专家。在 1984 年的一次采访中,他说:

    我们在苹果经历了那个阶段,当时我们出去想,哦,我们要成为一家大公司,让我们雇佣专业的管理人员。我们出去雇了一群专业的管理人员。一点也不管用……他们知道如何管理,但他们在专业方面什么都不知道。如果你是一个伟大的人,为什么你想为一个你什么都学不到的人工作?你知道什么是有趣的吗?你知道谁是最好的经理吗?他们是伟大的个人贡献者,他们从来都不想成为一名管理者,但却决定自己必须成为,因为没有其他人能够出色地完成工作。

    说实话,看完这篇文章,我很感慨,一方面是佩服乔布斯的洞见能力,另一方面也为我们这个行业感到唏嘘,业务技术也是技术啊,却没有一个像样的培育发展技术的环境和土壤。

    如今,业务技术Leader还有多少是专注在技术上呢,俨然都变成了业务Leader。如果技术Leader都变成了纯管理者,那么谁去关心技术,谁去关心代码,谁去关心工程师的成长呢?

    分类学是科学也是艺术

    最后,我还是要中庸一下,分类很重要,但同时也很难,带有一定的主观性。就像比尔.布莱森在《万物简史》里说的:

    分类学有时候被描述成一门科学,有时候被描述成一种艺术,但实际上那是一个战场。即使到了今天,那个体系比许多人认为的还要混乱。以描述生物基本结构的门的划分为例。许多生物学家坚持认为总数30个门,但有的认为20来个门,而爱德华在《生命的多样性》一书里提出的数字高达令人吃惊的89门。

    我们观察事物的视角不同,对问题的认知程度不同,得出来的分类也会不同。就拿COLA来说,直到现在的3.1版本,我个人认为其分层和分包的方式才相对比较合理。然而,很有可能在后期的迭代中,分类方式又会改变。

    组织架构的分类方式也是一样,按照业务和职能划分,都可以。关键看其分类是否匹配你组织的特性,没有最好的分类,只有最合适的。

    除了本文分享的分类思维,更多的思维能力还可以参看作者的新书:《代码精进之路:从码农到工匠》。这是一本为专业程序员而写的书,主要分为技艺、思想和实践三个部分,详细介绍了编程技巧和方法论、抽象能力、分治思想、常见的应用架构模式,以及COLA架构的设计原理。希望能够帮助广大程序员培养良好的编程习惯和思维。

    推荐阅读

    为什么阿里巴巴的程序员成长速度这么快?

    霸榜GitHub的Offer来了原理篇+框架篇,开放分享;

    50W年薪程序员需要的技术栈分析

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月25日

    三分钟带你搞懂分布式链路追踪系统原理

    分布式系统为什么需要链路追踪?

    随着互联网业务快速扩展,软件架构也日益变得复杂,为了适应海量用户高并发请求,系统中越来越多的组件开始走向分布式化,如单体架构拆分为微服务、服务内缓存变为分布式缓存、服务组件通信变为分布式消息,这些组件共同构成了繁杂的分布式网络。

    假如现在有一个系统部署了成千上万个服务,用户通过浏览器在主界面上下单一箱茅台酒,结果系统给用户提示:系统内部错误,相信用户是很崩溃的。

    运营人员将问题抛给开发人员定位,开发人员只知道有异常,但是这个异常具体是由哪个微服务引起的就需要逐个服务排查了。

    开发人员借助日志逐个排查的效率是非常低的,那有没有更好的解决方案了?

    答案是引入链路追踪系统。

    什么是链路追踪?

    分布式链路追踪就是将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。

    链路跟踪主要功能:

    • 故障快速定位:可以通过调用链结合业务日志快速定位错误信息。
    • 链路性能可视化:各个阶段链路耗时、服务依赖关系可以通过可视化界面展现出来。
    • 链路分析:通过分析链路耗时、服务依赖关系可以得到用户的行为路径,汇总分析应用在很多业务场景。

    链路追踪基本原理

    链路追踪系统(可能)最早是由Goggle公开发布的一篇论文

    《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》

    被大家广泛熟悉,所以各位技术大牛们如果有黑武器不要藏起来赶紧去发表论文吧。

    在这篇著名的论文中主要讲述了Dapper链路追踪系统的基本原理和关键技术点。接下来挑几个重点的技术点详细给大家介绍一下。

    Trace

    Trace的含义比较直观,就是链路,指一个请求经过所有服务的路径,可以用下面树状的图形表示。

    图中一条完整的链路是:chrome -> 服务A -> 服务B -> 服务C -> 服务D -> 服务E -> 服务C -> 服务A -> chrome。服务间经过的局部链路构成了一条完整的链路,其中每一条局部链路都用一个全局唯一的traceid来标识。

    Span

    在上图中可以看出来请求经过了服务A,同时服务A又调用了服务B和服务C,但是先调的服务B还是服务C呢?从图中很难看出来,只有通过查看源码才知道顺序。

    为了表达这种父子关系引入了Span的概念。

    同一层级parent id相同,span id不同,span id从小到大表示请求的顺序,从下图中可以很明显看出服务A是先调了服务B然后再调用了C。

    上下层级代表调用关系,如下图服务C的span id为2,服务D的parent id为2,这就表示服务C和服务D形成了父子关系,很明显是服务C调用了服务D。

    总结:通过事先在日志中埋点,找出相同traceId的日志,再加上parent id和span id就可以将一条完整的请求调用链串联起来。

    Annotations

    Dapper中还定义了annotation的概念,用于用户自定义事件,用来辅助定位问题。

    包含四个注解信息:

    cs:Client Start,表示客户端发起请求;

    sr:ServerReceived,表示服务端收到请求;

    ss:Server Send,表示服务端完成处理,并将结果发送给客户端;

    cr:ClientReceived,表示客户端获取到服务端返回信息;

    上图中描述了一次请求和响应的过程,四个点也就是对应四个Annotation事件。

    如下面的图表示从客户端调用服务端的一次完整过程。如果要计算一次调用的耗时,只需要将客户端接收的时间点减去客户端开始的时间点,也就是图中时间线上的T4 - T1。如果要计算客户端发送网络耗时,也就是图中时间线上的T2 - T1,其他类似可计算。

    带内数据与带外数据

    链路信息的还原依赖于带内和带外两种数据。

    带外数据是各个节点产生的事件,如cs,ss,这些数据可以由节点独立生成,并且需要集中上报到存储端。通过带外数据,可以在存储端分析更多链路的细节。

    带内数据如traceid,spanid,parentid,用来标识trace,span,以及span在一个trace中的位置,这些数据需要从链路的起点一直传递到终点。通过带内数据的传递,可以将一个链路的所有过程串起来。

    采样

    由于每一个请求都会生成一个链路,为了减少性能消耗,避免存储资源的浪费,dapper并不会上报所有的span数据,而是使用采样的方式。举个例子,每秒有1000个请求访问系统,如果设置采样率为1/1000,那么只会上报一个请求到存储端。

    通过采集端自适应地调整采样率,控制span上报的数量,可以在发现性能瓶颈的同时,有效减少性能损耗。

    存储

    链路中的span数据经过收集和上报后会集中存储在一个地方,Dapper使用了BigTable数据仓库,常用的存储还有ElasticSearch, HBase, In-memory DB等。

    业界常用链路追踪系统

    Google Dapper论文发出来之后,很多公司基于链路追踪的基本原理给出了各自的解决方案,如Twitter的Zipkin,Uber的Jaeger,pinpoint,Apache开源的skywalking,还有国产如阿里的鹰眼,美团的Mtrace,滴滴Trace,新浪的Watchman,京东的Hydra,不过国内的这些基本都没有开源。

    为了便于各系统间能彼此兼容互通,OpenTracing组织制定了一系列标准,旨在让各系统提供统一的接口。

    下面对比一下几个开源组件,方便日后大家做技术选型。

    附各大开源组件的地址:

    接下来介绍一下Zipkin基本实现。

    分布式链路追踪系统Zipkin实现

    Zipkin 是 Twitter 的一个开源项目,它基于 Google Dapper 实现,它致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展现。

    Zipkin基本架构

    在服务运行的过程中会产生很多链路信息,产生数据的地方可以称之为Reporter。将链路信息通过多种传输方式如HTTP,RPC,kafka消息队列等发送到Zipkin的采集器,Zipkin处理后最终将链路信息保存到存储器中。运维人员通过UI界面调用接口即可查询调用链信息。

    Zipkin核心组件

    Zipkin有四大核心组件

    (1)Collector

    一旦Collector采集线程获取到链路追踪数据,Zipkin就会对其进行验证、存储和索引,并调用存储接口保存数据,以便进行查找。

    (2)Storage

    Zipkin Storage最初是为了在Cassandra上存储数据而构建的,因为Cassandra是可伸缩的,具有灵活的模式,并且在Twitter中大量使用。除了Cassandra,还支持支持ElasticSearch和MySQL存储,后续可能会提供第三方扩展。

    (3)Query Service

    链路追踪数据被存储和索引之后,webui 可以调用query service查询任意数据帮助运维人员快速定位线上问题。query service提供了简单的json api来查找和检索数据。

    (4)Web UI

    Zipkin 提供了基本查询、搜索的web界面,运维人员可以根据具体的调用链信息快速识别线上问题。

    总结

    1. 分布式链路追踪就是将每一次分布式请求还原成调用链路。
    2. 链路追踪的核心概念:Trace、Span、Annotation、带内和带外数据、采样、存储。
    3. 业界常用的开源组件都是基于谷歌Dapper论文演变而来;
    4. Zipkin核心组件有:Collector、Storage、Query Service、Web UI。
      • *

    为什么阿里巴巴的程序员成长速度这么快?

    霸榜GitHub的Offer来了原理篇+框架篇,开放分享;

    50W年薪程序员需要的技术栈分析

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月25日

    为什么程序员不做外包

    不是悲观,而是外包行业水太深。本人有四年互联网二线大厂的从业经历,四年前不喜欢一直在一线城市呆着,回到三线城市。这几年一直在尝试接外包做副业。不得不说,外包的水很深,不接不知道,一接很绝望。现在基本已经放弃接外包赚钱的想法。

    1、没有稳定的客户

    很难有稳定的客户,基本上想找人开发程序的人,都是想省钱的人,各种PUA,嘴上说的好听,谈到价钱的时候,基本都是打马虎眼,很少有爽快的,几百块钱要做淘宝的人很多。开始做后,很多都是拼命催,自己的产品需求却说不清楚,还要隔三差五加功能。

    2、尾款难结

    尾款特别难结,对方有各种各样的借口来拖着你。每天你像个农民工一样去讨薪,被各种推脱,几次下来你的心会特别累,有时候会觉得自己特别傻。不去讨债的话,你就基本帮人白干。总之尾款问题对于开发者来说,特别被动,即便签合同也没办法解决这样的问题。

    3、技术要求高

    想稳定的接到外包,基本上前端、后端、运维、测试这些工作你都要一个人能搞定。不然找人的话,找到靠谱的、便宜、信得过的人特别难。一个人要活成一个技术团队,蛮辛苦的。

    35岁的程序员,不要有接外包赚钱的想法,实在不值当。


    为什么阿里巴巴的程序员成长速度这么快?

    霸榜GitHub的Offer来了原理篇+框架篇,开放分享;

    50W年薪程序员需要的技术栈分析

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月25日

    大厂都是怎么用Java8代替SimpleDateFormat?

    1 SimpleDateFormat 之坑

    1.1 格式化

    1.1.1 案例

    • 初始化一个Calendar,设置日期2020年12月29日
      ?
    • 日志
      ?

    这是由于混淆SimpleDateFormat的各种格式化模式:

    • 小写y是年
    • 大写Y是week year,即所在的周属于哪一年

    一年第一周的判断方式

    getFirstDayOfWeek()开始,完整的7天,并且包含那一年至少getMinimalDaysInFirstWeek()天。
    该计算方式和区域相关,对zh_CN区域,2020年第一周条件:从周日开始的完整7天,2020年包含1天即 可。显然,2019年12月27日周日到2020年1月2日周六是2020年第一周,得出的week year就是2021年。

    若把区域改为法国

    Locale.setDefault(Locale.FRANCE); 

    则week yeay就还是2020年,因为一周的第一天从周一开始算,2020年的第一周是2019年12月28日周一开始,27日还是属于去年:
    ?

    小结

    无特殊需求,针对年份的日期格式化,应该一律使用 “y” 而非 “Y”。

    线程安全问题

    使用一个100线程的线程池,循环20次把时间格式化任务提交到线程池处理,每个任务中又循环10次解析2020-01-01 11:12:13这样一个时间表示:

    • 运行程序后大量报错,即使没有报错的输出结果也不正常,比如2020年解析成57728年
      ?

    SimpleDateFormat?用于定义解析和格式化日期时间的模式。看起来是一次性工作,应该复用,但它的解析和格式化操作都非线程安全。

    分析源码

    ?

    SimpleDateFormat继承自DateFormat,DateFormat有字段Calendar;

    • SimpleDateFormat#parse调用CalendarBuilder#establish构建Calendar
      ?

    establish方法内部先清空Calendar再构建Calendar,整个操作没有加锁。
    ?

    显然,若使用线程池调用parse,即多线程并发操作一个Calendar,就可能会产生一个线程还没来得及处理Calendar就被另一个线程清空。format方法同理,不再赘述。因此只能在同一个线程复用SimpleDateFormat,

    解决方案

    通过ThreadLocal来存放SimpleDateFormat:

    • 日志输出全部正确?

    1.2 当需要解析的字符串和格式不匹配,SimpleDateFormat还是能得到结果

    案例

    使用yyyyMM解析20160901字符串:

    ?

    • 居然输出2112年,这是因为把 1111当成月份?

    对于SimpleDateFormat的这些坑,使用Java 8中的DateTimeFormatter即可避免。

    2 Java 8中的DateTimeFormatter

    2.1 格式化字符串

    首先,使用DateTimeFormatterBuilder定义格式化字符串,无需死记大写Y还是小写y,大写M还是小写m:
    ?

    2.2 线程安全

    可定义为static使用

    2.3 待解析字符串和格式不匹配时就报错

    ?

    • 日志
    2020/11/11 11:11:11.789
    Exception in thread "main" java.time.format.DateTimeParseException: Text '20201111' could not be parsed at index 0
        at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
        at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1777)
        at org.javaedge.time.commonmistakes.datetime.dateformat.CommonMistakesApplication.better(CommonMistakesApplication.java:96)
        at org.javaedge.time.commonmistakes.datetime.dateformat.CommonMistakesApplication.main(CommonMistakesApplication.java:47) 

    3 Java8计算日期时间

    • 有人喜欢使用时间戳进行计算,比如希望得到当前时间后30天:把new Date().getTime得到的时间戳加30天对应毫秒数
      ?
    • 得到的日期居然比当前日期还要早,根本不是后30天
      ?

    因为int发生了溢出!。

    • 应将30改为30L,使其为long:
      ?
    • 正确输出
      ?
    • Java 8前代码,建议使用Calendar:
      ?
    • 使用Java 8的日期时间类型,可以直接进行各种计算,更加简洁和方便:
      ?

    对日期时间做计算操作,日期时间API会比Calendar功能强大很多。

    3.1 minus/plus直接对日期加减

    ?

    3.2 with快捷时间调节

    • TemporalAdjusters.firstDayOfMonth得到当前月的第一天
    • TemporalAdjusters.firstDayOfYear()得到当前年的第一天
    • TemporalAdjusters.previous(DayOfWeek.SATURDAY)得到上一个周六
    • TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY)得到本月最后一个周五

    ?

    3.3 使用lambda自定义的时间调整

    • 为当前时间增加100天以内的随机天数:
      ?

    判断日期是否符合某个条件

    ?

    query查询是否匹配条件

    ?

    使用Java 8操作和计算日期时间虽然方便,但计算两个日期差时可能会踩坑:Java 8中有一个专门的类Period定义了日期间隔,通过Period.between得到了两个LocalDate的差,返回的是两个日期差几年零几月零几天。
    如果希望得知两个日期之间差几天,直接调用Period的getDays()方法得到的只是最后的“零几天”,而不是算总的间隔天数。

    比如,计算2020年12月12日和2020年10月1日的日期间隔,很明显日期差是2个月零11天,但获取getDays方法得到的结果只是11天,而不是72天:
    ?

    可使用ChronoUnit.DAYS.between解决这个问题:
    ?

    4 总结

    也许你认为java.util.Date类似于新API中的LocalDateTime。其实不是,虽然它们都没时区概念

    • java.util.Date类是因为使用UTC表示,所以没有时区概念,其本质是时间戳
    • LocalDateTime,严格上可以认为是一个日期时间的表示,而不是一个时间点

    因此,在把Date转换为LocalDateTime的时候,需要通过Date的toInstant方法得到一个UTC时间戳进行转换,并需要提供当前的时区,这样才能把UTC时间转换为本地日期时间(的表示)。反过来,把LocalDateTime的时间表示转换为Date时,也需要提供时区,用于指定是哪个时区的时间表示,也就是先通过atZone方法把LocalDateTime转换为ZonedDateTime,然后才能获得UTC时间戳:

    Date in = new Date();
    LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
    Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); 

    有人说新API很麻烦,还需要考虑时区,真麻烦。但并非因为API强行设计繁琐,而是UTC时间要变为当地时间,必须考虑时区!


    为什么阿里巴巴的程序员成长速度这么快?

    霸榜GitHub的Offer来了原理篇+框架篇,开放分享;

    50W年薪程序员需要的技术栈分析

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月25日

    程序员面试的时候突然遇到答不上的问题怎么办?

    前言

    今天给大家讲讲面试过程当中最长遇到的窘境,也是最能体现一个候选人临场应变能力的地方,那就是当我们在面试的过程当中,遇到的问题回答不上来的时候,该怎么办。

    误区

    在开始讲解之前,先纠正一个误区,那就是对于一场面试而言,最后的结果好坏并不完全取决于面试当中的问题是否都回答了上来。能不能录取和是否回答出所有问题并没有直接的联系。换句话说,我自己经历过的,无论是面试也好,还是面别人也罢,问题没答上来通过的,都答上来没通过的情况太多太多了。

    所以对待面试当中回答问题这件事情,可以稍微放平常心一点,不要过于以回答问题为导向。因为很有可能, 你像是背书一样回答出问题之后,面试官反而扣分更多。

    好了,下面我将从具体操作的角度讲讲该怎么做

    一.保持冷静,搜集信息

    这是第一条,也是最重要的一条。

    在面试的时候难免紧张,如果面试官的提问一下子毫无头绪,肯定会更加紧张。所以最重要的是保持冷静,千万不能自乱阵脚。

    当然,只冷静是不够的。冷静下来之后,有一件事一定要做,那就是再分析一下面试官的问题,看看有没有理解错,有没有什么信息缺失

    除了确认题意之外,其实我们还可以通过询问搜集一些信息。如果是算法题的话,可以试着问一下数据的范围和时间的限制。数据范围和时间限制有了,基本上就可以确定算法的复杂度了,复杂度确定了可以大大缩小算法的范围,解决问题就容易多了。

    二.杜绝沉默,适当表达

    这也是很重要的一点,很多人在面试的时候不把问题完全想出来,或者是不想到最优解就不肯罢休。我自己之前有段时间也这样,有时候能想到解法,但是自己感觉不是最优解,我就会一直想,一直到想出来才跟面试官说。

    后来当我自己成了面试官之后,我发现这种做法非常不可取。

    因为你不说话面试官并不能知道你的状态,他不知道你是完全没有思路,还是说已经有了想法,还是已经有了一个近似的解法。他得不到反馈,他就不能对你的能力和价值进行评估,所以直到最后一刻才开口的做法是不可取的。

    你要把面试当做一次探讨和沟通,即使一时没完全给出答案,也可以和面试官探讨,阐述你不成熟的想法、思路以及困惑。很多时候面试官的问题只是为了考察你具体的某个点,只要你答到了,哪怕题目没有完全解开也没有关系。有时候,你的想法可能面试官也没有料到,他会和你一起探讨,探讨的过程当中,也一样能够体现你的价值。

    所以不要吝啬开口,勇敢地表达你的想法,哪怕思路不成熟,哪怕只是隐约知道怎么做,也可以试着和面试官分享。

    三.回避问题,展示自己

    如果面试官问的并不是一个问题或者算法的解决思路,而是一个具体的问题,而这个问题你又刚好不知道,那该怎么办呢?

    这种情况的确比较棘手,因为你既不知道答案,也没有办法聊聊思路、旁敲侧击。在这个时候,就需要你用一点技巧,回避这个问题了。

    首先,你需要先把自己知道的说出来,不知道的或者比较模糊的最好别说。因为技术领域的概念比较多,很多名称比较近似,但南辕北辙,所以强行作答很有可能出现驴唇不对马嘴的事情,这是面试的大忌。知道多少说多少,可是万一实在不知道或者想不起来了,怎么办呢?

    想不起来,就是想不起来,千万不要撒谎。但是不撒谎并不意味着没有回旋的余地。你可以说,这个技术平时用的不多,我们某某领域,我对XX技术比较熟,不然我给你讲讲吧。

    不要小看了这一小段话,我们仔细分析一下,这一句话当中包含了很多内容。首先,你诚实地告知了面试官,这个问题可能答不上来。然后你告诉了面试官,虽然问题答不上来,但是你知道这个技术或者这个问题是什么方向的。最后你给了一个解决方案,虽然我不知道A,但是我知道近似的B,也能起到近似的效果。

    只要这里的A和你提供的B没有太大的出入,一般来说都没有问题。如果实在连近似的答案也没有,那么只能强行讲一些自己擅长的方向了。

    比如问你数据库,你实在没用过,强行说自己对JVM很熟悉,也不是不可以。至少要比一句我不知道要好得多。


    为什么阿里巴巴的程序员成长速度这么快?

    霸榜GitHub的Offer来了原理篇+框架篇,开放分享;

    [](https://blog.csdn.net/javache...50W年薪程序员需要的技术栈分析

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月24日

    面试 | 程序猿面试,Elasticsearch被坑被虐的体无完肤...

    Java相关

    问:Elasticsearch 使用 ES_JAVA_OPTS 环境变量来配置JVM,比较常用的配置为 Xms,最小堆内存,Xmx,最大堆内存,设置的建议是什么?答:这两个值的最佳实践是替换2g为使用物理机或者虚拟机的内存的一半

    分布式相关

    问:分布式一般使用几个节点:答:分布式一半使用奇数个节点,因为如果我们集群中有三个节点,ABC,如果A和B,C失联,那么B和C会发现连接不上A,就会标记A失联,而他们可以选举新的主节点,所以分布式系统一般都使用2n+1 其中n>0个节点,生产系统中,最少为3个节点。

    集群健康度

    集群健康度分为分片健康度,索引健康度,集群健康度,指标分为绿,黄,红,三个等级。

    分片健康度

    红:至少一个主分片没有被分配。黄:至少一个副本分配没有被分配 绿:主副分片都正常分配。

    索引健康度

    索引健康度是此分片中最差的健康度。

    集群健康度

    集群健康度是此集群上索引中最差的健康度。
    健康度相关API

     GET /_cluster/health 获取集群的健康状态
    GET /_cluster/health?level=indices 获取所有索引的健康状态
    GET /_cluster/health/<index> 获取单个索引的健康状态
    GET /_cluster/allocation/explain 返回第一个未分配分片的原因 

    集群不健康排查流程

    在节点离线以后,有可能因为节点数量不够,导致分片无法分配,此时需要增加新的分片,让其重新分配。
    索引配置错误,分片规则配置错误,导致无法分配,这个时候需要重新配置索引,重新配置分片。
    磁盘空间不足:当产生磁盘空间不足的时候,有可能也会导致分配失败,这个时候需要重新划分新的磁盘空间。出现的错误为 DANGLING_INDEX_IMPORTE
    当出现 EXISTING_INDEX_RESTORED 错误时候,索引被关闭,需要把索引删除,再恢复。

    节点诊断

    节点诊断API

    GET /_cat/nodes?v 查看节点到基本信息即负载情况
    GET /_nodes/stats/indices 查看节点的索引详情
    POST /_cache/clear 清除节点缓存

    节点内存问题

    Elasticserach 集群长时间GC可能会导致集群变慢,产生OOM,甚至产生离线,这个时候需要进行诊断,一般由以下这几种情况会产生节点内存OOM
    缓存占用过多内存。
    大量复杂的嵌套聚合可能引发频繁GC
    有些时候需要配置断路器用来限制请求的查询,避免出现大量的OOM

    Shard

    Elasticsearch把一个索引分成多个Shard存储。一般建议单个shard大小为20G到50G,对于普通搜索类的数据控制在20G,日志数据控制在50G,每个节点数据控制在2T。

    相关API

     GET /_cat/shards/<index> 查看 Shard 信息
    POST /<alias>/_rollover/<target-index> 当索引满足某些条件时(如数据量太大)自动切到新的索引,非常适合无法预估大小的时间序列类索引
    POST /<index>/_forcemerge 强制合并索引数据
    POST /<index>/_shrink/<target-index> 新建索引并减少主分片数量
    POST /<index>/_split/<target-index> 新建索引并增加主分片数量
    POST /_reindex 重建索引 

    深度分页

    分页有三种方式

    from + size

    from 定义数据偏移量,size定义数据获取量,类似于sql的offset和limit。

    scroll API

    scroll 类似于sql的游标,查询的时候指定scroll=时间参数使用,返回的结果带上scroll_id 下次查询的时候只需要指定scroll_id 即可。

     POST /<index>/_search?scroll=1m
    {
        "size": 100,
        "query": {
            "match" : {
                "title" : "elasticsearch"
            }
        }
    }
    
    POST /_search/scroll 
    {
        "scroll" : "1m", 
        "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" 
    } 

    Search After API

    Search After API 用作前一次结果作为下一次的查询条件,在查询体重使用search_after 参数,示例如下

     GET <index>/_search
    {
        "size": 10,
        "query": {
            "match" : {
                "title" : "elasticsearch"
            }
        },
        "search_after": [1463538857, "654323"],
        "sort": [
            {"date": "asc"},
            {"_id": "asc"}
        ]
    } 

    看完三件事??

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    Mr.Z 发布了文章 · 11月24日

    字节跳动总监总结的开发笔记火了!在知乎上已超5000赞!

    最近有幸在一位字节跳动总监手里扒到了这份开发笔记,将部分知识章节发布到了在知乎上竟然获得了5000+点赞!

    今天就拿出来分享给大家,不管你是学生,还是已经步入职场的同行,希望你们都要珍惜眼前的学习机会,奋斗没有终点,知识永不过时。

    如果觉得有收获的话,不要白嫖!点个赞/在看。除了Java各种技术专题知识、大厂面试真题,也包括近些年他开发和工作过程中的一些感悟、心得。

    **这份资料包括:

    IDEA、Java语法、面向对象、异常、常用类、集合、IO流、多线程、网络编程、JUnit、枚举、注解、反射机制、CSS、HTML、JavaScript、JQuery、ajax、Javaweb、MySQL、JavaEE、SSM框架、springboot、算法、Git、maven、Linux、设计模式、多线程与高并发、视频教程、视频源码、实战项目、电子书、简历模板、高频面试题等等资源。

    目录:

    • 5.1. 职业分析及定位
    • 5.2. 职业生涯经验和建议
    • 5.3. 程序员跳槽指南和简历技巧
    • 5.4. 程序员“高分”简历模板(800+套)
      1. 一线互联网公司面试真题合集(一)
      1. 一线互联网公司面试真题合集(二)
      1. BATJ面试攻略教程合集(2020版)
      1. 海量专业技术教程(初级/中级/高级)
      1. 目前主流企业使用最高频的面试题库
      1. Java程序员进阶职业规划
      1. 海量程序员必备电子书+思维导图(典藏版)
      1. 对标互联网“年薪50W+”的架构师成长路线指南
    1. 一线互联网公司面试真题合集(一)

    这套合集中面试题集包含了以下十几个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM,供大家查漏补缺。

    大厂面试真题

    1. 一线互联网公司面试真题合集(二)

    这套合集中面试题集包含了一线互联网公司近年的面试必问的Java岗面试题以及答案,也分享出来供大家查漏补缺。

    面试必问的Java岗面试题以及答案

    今年面试越来越难搞,很多小伙伴都在秋招中不太理想,想准备在明年金三银四跳槽中摩拳擦掌准备大面好几场,这份互联网面试题很适合工作1-5年的Java面试者,分别包含JVM,并发编程,MySQL,Tomcat,网络与IO及Spring系列等等,可以说掌握这些薪资涨10K还是可以的!

    1. BATJ面试攻略教程合集(2020版)

    这份面试攻略教程是由六位十余年一线互联网Java行业资深架构师共同分享的面试教程(非常的珍贵,其中包括:简历优化/包装,面试攻略...)

    资料获取方法:关注公众号【Java斗帝】回复666 免费获取

    1. 海量专业技术教程(初级/中级/高级)

    这份技术视频教程是由多位十余年一线互联网Java行业资深架构师进行分享的,每个人的技术擅长领域不同,所以也是从中给大家挑出了一些重要的教程(其中部分带源码,笔记)

    1. 目前主流企业使用最高频的面试题库

    目前主流企业使用最高频的面试题库(15W4658字!),都是 Java 版本升级之后,重新整理归纳的最新答案,会让面试者少走很多不必要的弯路。同时每个专题都做到了详尽的面试解析文档,以确保每个阶段的读者都能看得懂!

    1. Java程序员进阶职业规划

    一份好看,漂亮的简历,可以在面试官那里大大加分,这里也给大家一些大佬们的简历模板(仅供学习参考)

    1. 海量程序员必备电子书+思维导图(典藏版)

    关于电子书和思维导图,就是个人的从业多年的重要收藏了,其中很多书籍都是非常不错的,值得大家研读,这里仅作为学习之用,分享给大家。

    ?

    1. 对标互联网“年薪50W+”的架构师成长指南

    另外,还有一份对标互联网“年薪60W+”的资深架构师成长路线指南,如有需要也一起赠送给大家。大家可以跟着这份成长路线学习自己欠缺的技术,对你的职业发展有着提纲挈领的作用!

    -程序员年薪50W学习指南 点击观看

    看完三件事??

    ========

    如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

    点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

    关注公众号 『 Java斗帝 』,不定期分享原创知识。

    同时可以期待后续文章ing??

    查看原文

    赞 0 收藏 0 评论 0

    认证与成就

    • 获得 52 次点赞
    • 获得 1 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 1 枚铜徽章

    擅长技能
    编辑

    (??? )
    暂时没有

    开源项目 & 著作
    编辑

    (??? )
    暂时没有

    注册于 10月7日
    个人主页被 1.4k 人浏览

    bt365体育投注