0%

## 寄生虫观后感

Posted on 2020-03-01 In 生活 , 影评 , 2020 Views: Disqus:

寄生虫这部电影在获得奥斯卡之前就有关注了，豆瓣评分很高，一开始看到这个片名以为是像《铁线虫入侵》那种灾难片，后来看到男主，宋康昊，也是老面孔了，从高中时候在学校操场组织看的《汉江怪物》，有点二的感觉，后来在大学寝室电脑上重新看的时候，室友跟我说是韩国国宝级演员，真人不可貌相，感觉是个呆子的形象。

但是你说这不是个灾难片，而是个反映社会问题的，就业比较容易往这个方向猜，只是剧情会是怎么样的，一时也没啥头绪，后来不知道哪里看了下一个剧情透露，是一个穷人给富人做家教，然后把自己一家都带进富人家，如果是这样的话可能会把这个怎么带进去作为一个主线，不过事实告诉我，这没那么重要，从第一步朋友的介绍，就显得无比顺利，要去当家教了，作为一个穷成这样的人，瞬间转变成一个衣着得体，言行举止都没让富人家看出破绽的延世大学学生，这真的挺难让人理解，所谓江山易改，本性难移，还有就是这人也正好有那么好能力去辅导，并且诡异的是，多惠也是瞬间就喜欢上了男主，多惠跟将男主介绍给她做家教，也就是多惠原来的家教敏赫，应该也有不少的相处时间，这变了有点大了吧，当然这里也可能因为时长需要，如果说这一点是因为时长，那可能我所有的槽点都是因为这个吧，因为我理解的应该是把家里的人如何一步步地带进富人家，这应该是整个剧情的一个需要更多铺垫去克服这个矛盾点，有时候也想过如果我去当导演，是能拍出个啥，没这个机会，可能有也会是很扯淡的，当然这也不能阻拦我谈谈对这个点的一些看法，毕竟评价一台电冰箱不是说我必须得自己会制冷对吧，这大概是我觉得这个电影的第一个槽点，接下去接二连三的，就是我说的这个最核心的矛盾点，不知道谁说过，这种影视剧应该是源自于生活又高于生活，越是好的作品，越要接近生活，这样子才更能有感同身受。

接下去的点是金基宇介绍金基婷去给多颂当美术家教，这一步又是我理解的败笔吧，就怎么说呢，没什么铺垫，突然从一个社会底层的穷姑娘，转变成一个气场爆表，把富人家太太唬得一愣一愣的，如果说富太太是比较简单无脑的，那富人自己应该是比较有见识而且是做 IT 的，给自己儿子女儿做家教的，查查底细也很正常吧，但是啥都没有，然后呢，她又开始耍司机的心机了，真的是莫名其妙了，司机真的很惨，窈窕淑女君子好逑，而且这个操作也让我摸不着头脑，这是多腹黑并且有经验才会这么操作，脱内裤真的是让我看得一愣愣的，更看得我一愣一愣的，富人竟然也完全按着这个思路去想了，完全没有别的可能呢，甚至可以去查下行车记录仪或者怎样的，或者有没有毛发体液啥的去检验下，毕竟金基婷也乘坐过这辆车，但是最最让我不懂的还是脱内裤这个操作，究竟是什么样的人才会的呢，值得思考。

金基泽和忠淑的点也是比较奇怪，首先是金基泽，引起最后那个杀人事件的一个由头，大部分观点都是人为朴社长在之前跟老婆啪啪啪的时候说金基泽的身上有股乘地铁的人的味道，简而言之就是穷人的味道，还有去雯光丈夫身下拿钥匙是对金基泽和雯光丈夫身上的味道的鄙夷，可是这个原因真的站不住脚，即使是同样经济水平，如果身上有比较重的异味，背后讨论下，或者闻到了比较重的味道，有不适的表情和动作很正常吧，像雯光丈夫，在地下室里呆了那么久，身上有异味并且比较重太正常了，就跟在厕所呆久了不会觉得味道大，但是从没味道的地方一进有点味道的厕所就会觉得异样，略尴尬的理由；再说忠淑呢，感觉是太厉害了，能胜任这么一家有钱人的各种挑剔的饮食口味要求的保姆职位，也是让人看懵逼了，看到了不禁想到一个问题，这家人开头是那么地穷，不堪，突然转变成这么地像骗子家族，如果有这么好的骗人能力，应该不会到这种地步吧，如果真的是那么穷，没能力，没志气，又怎么会突然变成这么厉害呢，一家人各司其职，把富人家唬得团团转，而这个前提是，这些人的确能胜任这四个位置，这就是我非常不能理解的点。

然后说回这个标题，寄生虫，不知道是不是翻译过来不准确，如果真的是叫寄生虫的话，这个寄生虫智商未免也太低了，没有像新冠那样机制，致死率低一点，传染能力强一点，潜伏期也能传染，这个寄生虫第一次受到免疫系统的攻击就自爆了；还有呢，作为一个社会比较低层的打工者，乡下人，对这个审题也是不太审的清，是指这一家人是社会的寄生虫，不思进取，并且死的应该，富人是傻白甜，又有钱又善良，这是给有钱人洗地了还是啥，这个奥斯卡真不知道是怎么得的，总觉得奥斯卡，甚至低一点，豆瓣，得奖的，评分高的都是被一群“精英党”把持的，有黑人主角的，得分高；有同性恋的，得分高；结局惨的，得分高；看不懂的，得分高；就像肖申克的救赎，真不知道是哪里好了，最近看了关于明朝那些事的三杨，杨溥的经历应该比这个厉害吧，可是外国人看不懂，就像外国人不懂中国为什么有反分裂国家法，经历了鸦片战争，八国联军，抗日战争等等，其实跟外国对于黑人的权益的问题，因为有南北战争，所以极度重视这个问题，相应的中国也有自己的历史，请理解。

简而言之我对寄生虫的评分大概 5~6 分吧。

## gogs使用webhook部署react单页应用

Posted on 2020-02-22 Edited on 2020-02-23 In 持续集成 Views: Disqus:

众所周知，我是个前端彩笔，但是也想做点自己可以用的工具页面，所以就让朋友推荐了蚂蚁出品的 ant design，说基本可以直接 ctrl-c ctrl-v，实测对我这种来说还是有点难的，不过也能写点，但是现在碰到的问题是怎么部署到自己的服务器上去
用 ant design 写的是个单页应用，实际来说就是一个 html 加 css 跟 js，最初的时候是直接 build 完就 scp 上去，也考虑过 rsync 之类的，但是都感觉不够自动化，正好自己还没这方面的经验就想折腾下，因为我自己搭的仓库应用是 gogs，搜了一下主要是跟 drones 配合做 ci/cd，研究了一下发现其实这个事情没必要这么搞(PS：drone 也不好用)，整个 hook 就可以了, 但是实际上呢，这东西也不是那么简单
首先是需要在服务器上装 webhook，这个我一开始用 snap 安装，但是出现问题，run 的时候会出现后面参数带的 hooks.json 文件找不到，然后索性就直接 github 上下最新版，放 /usr/local/bin 了，webhook 的原理呢其实也比较简单，就是起一个 http 服务，通过 post 请求调用，解析下参数，如果跟配置的参数一致，就调用对应的命令或者脚本。

## 配置 hooks.json

webhook 的配置，需要的两个文件，一个是 hooks.json，这个是 webhook 服务的配置文件，像这样

    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
    45
    46
    47
    48
    49
    50
    51
    52
    [
      {
        "id": "redeploy-app",
        "execute-command": "/opt/scripts/redeploy.sh",
        "command-working-directory": "/opt/scripts",
        "pass-arguments-to-command":
        [
          {
            "source": "payload",
            "name": "head_commit.message"
          },
          {
            "source": "payload",
            "name": "pusher.name"
          },
          {
            "source": "payload",
            "name": "head_commit.id"
          }
        ],
        "trigger-rule":
        {
          "and":
          [
            {
              "match":
              {
                "type": "payload-hash-sha1",
                "secret": "your-github-secret",
                "parameter":
                {
                  "source": "header",
                  "name": "X-Hub-Signature"
                }
              }
            },
            {
              "match":
              {
                "type": "value",
                "value": "refs/heads/master",
                "parameter":
                {
                  "source": "payload",
                  "name": "ref"
                }
              }
            }
          ]
        }
      }
    ]

这是个跟 github搭配的示例，首先 id 表示的是这个对应 hook 的识别 id，也可以看到这个 hooks.json 的结构是这样的一个数组，然后就是要执行的命令和命令执行的参数，值得注意的是这个`trigger-rule`,就是请求进来了回去匹配里面的，比如前一个是一个加密的，放在请求头里，第二个 match 表示请求里的 ref 是个 master 分支，就可以区分分支进行不同操作，但是前面的加密配合 gogs 使用的时候有个问题(PS: webhook 的文档是真的烂)，gogs 设置 webhook 的加密是用的

> 密钥文本将被用于计算推送内容的 SHA256 HMAC 哈希值，并设置为 `X-Gogs-Signature` 请求头的值。

这种加密方式，所以 webhook 的这个示例的加密方式不行，但这货的文档里居然没有说明支持哪些加密，神TM，后来还是翻 issue 翻到了, 需要使用这个`payload-hash-sha256`

## 执行脚本 redeploy.sh

脚本类似于这样

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/bin/bash -e

    function cleanup {
          echo "Error occoured"
    }
    trap cleanup ERR

    commit_message=$1 # head_commit.message
    pusher_name=$2 # pusher.name
    commit_id=$3 # head_commit.id

    cd ~/do-react-example-app/
    git pull origin master
    yarn && yarn build

就是简单的拉代码，然后构建下，真实使用时可能不是这样，因为页面会部署在 nginx 的作用目录，还需要 rsync 过去，这部分可能还涉及到两个问题第一个是使用 rsync 还是其他的 cp，不过这个无所谓；第二个是目录权限的问题，以我的系统ubuntu 为例，默认用户是 ubuntu，nginx 部署的目录是 www，所以需要切换用户等操作，一开始是想用在shell 文件中直接写了密码，但是不知道咋传，查了下是类似于这样 `echo "passwd" | sudo -S cmd`，通过管道命令往后传，然后就是这个`-S`, 参数的解释是`-S, --stdin read password from standard input`,但是这样么也不是太安全的赶脚，又看了下还有两种方法，

- 就是给root 设置一个不需要密码的命令类似于这样，

      1
      2
      myusername ALL = (ALL) ALL
      myusername ALL = (root) NOPASSWD: /path/to/my/program

- 另一种就是把默认用户跟 root 设置成同一个 group 的

## 使用

真正实操的时候其实还有不少问题，首先运行 webhook 就碰到了我前面说的，使用 snap 运行的时候会找不到前面的 hooks.json配置文件，执行`snap run webhook -hooks /opt/hooks/hooks.json -verbose`就碰到下面的`couldn't load hooks from file! open /opt/hooks/hooks.json: no such file or directory`，后来直接下了个官方最新的 release，就直接执行 `webhook -hooks /opt/hooks/hooks.json -verbose` 就可以了，然后是前面的示例配置文件里的几个参数，比如`head_commit.message` 其实 gogs 推过来的根本没这玩意，而且都是数组，不知道咋取，烂文档，不过总比搭个 drone 好一点就忍了。补充一点就是在 debug 的时候需要看下问题出在哪，看看脚本有没有执行，所以需要在前面的 json 里加这个参数`"include-command-output-in-response": true`, 就能输出来脚本执行结果

## Maven实用小技巧

Posted on 2020-02-16 In Java , Maven Views: Disqus:

Maven 翻译为”专家”、”内行”，是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型（缩写：POM）概念，Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。

Maven 是一个项目管理工具，可以对 Java 项目进行构建、依赖管理。

Maven 也可被用于构建和管理各种项目，例如 C#，Ruby，Scala 和其他语言编写的项目。Maven 曾是 Jakarta 项目的子项目，现为由 Apache 软件基金会主持的独立 Apache 项目。

maven也是我们日常项目中实用的包管理工具，相比以前需要用把包下载下来，放进 lib 中，在平时工作中使用的话，其实像 idea 这样的 ide 工具都会自带 maven 工具和插件

### maven的基本操作

- `mvn -v`
  查看 maven 信息
- `mvn compile`
  将 Java 编译成 class 文件
- `mvn test`
  执行 test 包下的测试用例
- `mvn package`
  将项目打成 jar 包
- `mvn clean`
  删除package 在 target 目录下面打出来的 jar 包和 target 目录
- `mvn install`
  将打出来的 jar 包复制到 maven 的本地仓库里
- `mvn deploy`
  将打出来的 jar 包上传到远程仓库里

### 与 composer 对比

因为我也是个 PHP 程序员，所以对比一下两种语言，很容易想到在 PHP 的 composer 跟 Java 的 maven 是比较类似的作用，有一点两者是非常相似的，就是原仓库都是因为某些原因连接拉取都会很慢，所以像 composer 会有一些国内源，前阵子阿里也出了一个，类似的 maven 一般也会使用阿里的镜像仓库，通过在 setting.xml 文件中的设置

    1
    2
    3
    4
    5
    6
    7
    8
    <mirrors>
        <mirror>
            <id>aliyun</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>

这算是个尴尬的共同点，然后因为 PHP 是解释型脚本语言，所以 php 打出来的 composer 包其实就是个 php 代码包，使用SPL Autoload等方式加载代码包，maven 包则是经过编译的 class 包，还有一点是 composer 也可以直接使用 github 地址作为包代码的拉取源，这点也是比较大的区别，maven使用 pom 文件管理依赖

### maven 的个人小技巧

- maven 拉取依赖时，同时将 snapshot 也更新了，就是 `mvn compile`加个`-U`参数，如果还不行就需要将本地仓库的 snapshot 删掉，
  这个命令的 help 命令解释是 -U,–update-snapshots Forces a check for missing releases and updated snapshots on
  remote repositories，这个在日常使用中还是很经常使用的
- maven 出现依赖冲突的时候的解决方法
  首先是依赖分析，使用`mvn dependency:tree`分析下依赖关系，如果要找具体某个包的依赖引用关系可以使用`mvn dependency:tree -Dverbose -Dincludes=org.springframework:spring-webmvc`命令进行分析，如果发现有冲突的依赖关系，本身 maven 中依赖引用有相对的顺序，大致来说是引用路径短的优先，pom 文件中定义的顺序优先，如果要把冲突的包排除掉可以在 pom 中用

      1
      2
      3
      4
      5
      6
      <exclusions>
        <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </exclusion>
      </exclusions>

  将冲突的包排除掉
- maven 依赖的 jdk 版本管理
  前面介绍的`mvn -v`可以查看 maven 的安装信息
  比如

      1
      2
      3
      4
      5
      Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
      Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec
      Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre
      Default locale: zh_CN, platform encoding: UTF-8
      OS name: "mac os x", version: "10.14.6", arch: "x86_64", family: "mac"

  这里可以看到用了 mac 自带的 jdk1.8，结合我之前碰到的一个问题，因为使用 homebrew 升级了 gradle，而 gradle 又依赖了 jdk13，因为这个 mvn 的 Java version 也变成 jdk13 了，然后 mvn 编译的时候出现了 `java.lang.ExceptionInInitializerError: com.sun.tools.javac.code.TypeTags`这个问题，所以需要把这个版本给改回来，但是咋改呢，网上搜来的一大堆都是在 pom 文件里的
  source和 target 版本

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <build>
        <plugins>
      <plugin>
      	<groupId>org.apache.maven.plugins</groupId>
      	<artifactId>maven-compiler-plugin</artifactId>
      	<configuration>
      		<source>1.8</source>
      		<target>1.8</target>
      		<encoding>UTF-8</encoding>
      	</configuration>
      </plugin>
        </plugins>
      <build>

  或者修改 maven 的 setting.xml中的

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <profiles>
            <profile>
                <id>ngmm-nexus</id>
              <activation>
                <jdk>1.8</jdk>
              </activation>
              <properties>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
                <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
            </properties>
            </profile>
      </profiles>

  但是这些都没啥用啊，真正有办法的是建个 `.mavenrc`，这个顾名思义就是 maven 的资源文件，类似于 `.bashrc`和`.zshrc`，在里面添加 MAVEN_HOME 和 JAVA_HOME,然后执行 `source .mavenrc`就 OK 啦

## G1收集器概述

Posted on 2020-02-09 In Java , JVM , C++ , GC Views: Disqus:

G1: The Garbage-First Collector, 垃圾回收优先的垃圾回收器，目标是用户多核 cpu 和大内存的机器，最大的特点就是可预测的停顿时间，官方给出的介绍是提供一个用户在大的堆内存情况下一个低延迟表现的解决方案，通常是 6GB 及以上的堆大小，有低于 0.5 秒稳定的可预测的停顿时间。

这里主要介绍这个比较新的垃圾回收器，在 G1 之前的垃圾回收器都是基于如下图的内存结构分布，有新生代，老年代和永久代（jdk8 之前），然后G1 往前的那些垃圾回收器都有个分代，比如 serial，parallel 等，一般有个应用的组合，最初的 serial 和 serial old，因为新生代和老年代的收集方式不太一样，新生代主要是标记复制，所以有 eden 跟两个 survival区，老年代一般用标记整理方式，而 G1 对这个不太一样。
看一下 G1 的内存分布
可以看到这有很大的不同，G1 通过将内存分成大小相等的 region，每个region是存在于一个连续的虚拟内存范围，对于某个 region 来说其角色是类似于原来的收集器的Eden、Survivor、Old Generation，这个具体在代码层面

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    // We encode the value of the heap region type so the generation can be
     // determined quickly. The tag is split into two parts:
     //
     //   major type (young, old, humongous, archive)           : top N-1 bits
     //   minor type (eden / survivor, starts / cont hum, etc.) : bottom 1 bit
     //
     // If there's need to increase the number of minor types in the
     // future, we'll have to increase the size of the latter and hence
     // decrease the size of the former.
     //
     // 00000 0 [ 0] Free
     //
     // 00001 0 [ 2] Young Mask
     // 00001 0 [ 2] Eden
     // 00001 1 [ 3] Survivor
     //
     // 00010 0 [ 4] Humongous Mask
     // 00100 0 [ 8] Pinned Mask
     // 00110 0 [12] Starts Humongous
     // 00110 1 [13] Continues Humongous
     //
     // 01000 0 [16] Old Mask
     //
     // 10000 0 [32] Archive Mask
     // 11100 0 [56] Open Archive
     // 11100 1 [57] Closed Archive
     //
     typedef enum {
       FreeTag               = 0,

       YoungMask             = 2,
       EdenTag               = YoungMask,
       SurvTag               = YoungMask + 1,

       HumongousMask         = 4,
       PinnedMask            = 8,
       StartsHumongousTag    = HumongousMask | PinnedMask,
       ContinuesHumongousTag = HumongousMask | PinnedMask + 1,

       OldMask               = 16,
       OldTag                = OldMask,

       // Archive regions are regions with immutable content (i.e. not reclaimed, and
       // not allocated into during regular operation). They differ in the kind of references
       // allowed for the contained objects:
       // - Closed archive regions form a separate self-contained (closed) object graph
       // within the set of all of these regions. No references outside of closed
       // archive regions are allowed.
       // - Open archive regions have no restrictions on the references of their objects.
       // Objects within these regions are allowed to have references to objects
       // contained in any other kind of regions.
       ArchiveMask           = 32,
       OpenArchiveTag        = ArchiveMask | PinnedMask | OldMask,
       ClosedArchiveTag      = ArchiveMask | PinnedMask | OldMask + 1
     } Tag;

`hotspot/share/gc/g1/heapRegionType.hpp`

当执行垃圾收集时，G1以类似于CMS收集器的方式运行。 G1执行并发全局标记阶段，以确定整个堆中对象的存活性。标记阶段完成后，G1知道哪些region是基本空的。它首先收集这些region，通常会产生大量的可用空间。这就是为什么这种垃圾收集方法称为“垃圾优先”的原因。顾名思义，G1将其收集和压缩活动集中在可能充满可回收对象（即垃圾）的堆区域。 G1使用暂停预测模型来满足用户定义的暂停时间目标，并根据指定的暂停时间目标选择要收集的区域数。

由G1标识为可回收的区域是使用撤离的方式(Evacuation)。 G1将对象从堆的一个或多个区域复制到堆上的单个区域，并在此过程中压缩并释放内存。撤离是在多处理器上并行执行的，以减少暂停时间并增加吞吐量。因此，对于每次垃圾收集，G1都在用户定义的暂停时间内连续工作以减少碎片。这是优于前面两种方法的。 CMS（并发标记扫描）垃圾收集器不进行压缩。 ParallelOld垃圾回收仅执行整个堆压缩，这导致相当长的暂停时间。

需要重点注意的是，G1不是实时收集器。它很有可能达到设定的暂停时间目标，但并非绝对确定。 G1根据先前收集的数据，估算在用户指定的目标时间内可以收集多少个区域。因此，收集器具有收集区域成本的合理准确的模型，并且收集器使用此模型来确定要收集哪些和多少个区域，同时保持在暂停时间目标之内。

注意：G1同时具有并发（与应用程序线程一起运行，例如优化，标记，清理）和并行（多线程，例如stw）阶段。Full GC仍然是单线程的，但是如果正确调优，您的应用程序应该可以避免Full GC。

在前面那篇中在代码层面简单的了解了这个可预测时间的过程，这也是 G1 的一大特点。

## 2019年终总结

Posted on 2020-02-01 In 生活 , 年终总结 , 2019 Views: Disqus:

今天是农历初八了，年前一个月的时候就准备做下今年的年终总结，可是写了一点觉得太情绪化了，希望后面写个平淡点的，正好最近技术方面还没有看到一个完整成文的内容，就来写一下这一年的总结，尽量少写一点太情绪化的东西。

### 跳槽

年初换了个公司，也算换了个环境，跟前公司不太一样，做的事情方向也不同，可能是侧重点不同，一开始有些不适应，主要是压力上，会觉得压力比较大，但是总体来说与人相处的部分还是不错的，做的技术方向还是Java，这里也感谢前东家让我有机会转了Java，个人感觉杭州整个市场还是Java比较有优势，不过在开始的时候总觉得对Java有点不适应，应该值得深究的东西还是很多的，而且对于面试来说，也是有很多可以问的，后面慢慢发现除开某里等一线超一线互联网公司之外，大部分的面试还是有大概的套路跟大纲的，不过更细致的则因人而异了，面试有时候也还看缘分，面试官关注的点跟应试者比较契合的话就很容易通过面试，不然的话总会有能刁难或者理性化地说比较难回答的问题。这个后面可以单独说一下，先按下不表。
刚进公司没多久就负责比较重要的项目，工期也比较紧张，整体来说那段时间的压力的确是比较大的，不过总算最后结果不坏，这里应该说对一些原来在前东家都是掌握的不太好的部分，比如maven，其实maven对于java程序员来说还是很重要的，但是我碰到过的面试基本没问过这个，我自己也在后面的面试中没问过相关的，不知道咋问，比如dependence分析、冲突解决，比如对bean的理解，这个算是我一直以来的疑问点，因为以前刚开始学Java学spring，上来就是bean，但是bean到底是啥，IOC是啥，可能网上的文章跟大多数书籍跟我的理解思路不太match，导致一直不能很好的理解这玩意，到后面才理解，要理解这个bean，需要有两个基本概念，一个是面向对象，一个是对象容器跟依赖反转，还是只说到这，后面可以有专题说一下，总之自认为技术上有了不小的长进了，方向上应该是偏实用的。这个重要的项目完成后慢慢能喘口气了，后面也有一些比较紧急且工作量大的，不过在我TL的帮助下还是能尽量协调好资源。

### 面试

后面因为项目比较多，缺少开发，所以也参与帮忙做一些面试，这里总体感觉是面的候选人还是比较多样的，有些工作了蛮多年但是一些基础问题回答的不好，有些还是在校学生，但是面试技巧不错，针对常见的面试题都有不错的准备，不过还是觉得光靠这些面试题不能完全说明问题，真正工作了需要的是解决问题的人，而不是会背题的，退一步来说能好好准备面试还是比较重要的，也是双向选择中的基本尊重，印象比较深刻的是参加了去杭州某高校的校招面试，感觉参加校招的同学还是很多的，大部分是20年将毕业的研究生，挺多都是基础很扎实，对比起我刚要毕业时还是很汗颜，挺多来面试的同学都非常不错，那天强度也很大，从下午到那开始一直面到六七点，在这祝福那些来面试的同学，也都不容易的，能找到心仪的工作。

### 技术方向

这一年前大半部分还是比较焦虑不能恢复那种主动找时间学习的状态，可能换了公司是主要的原因，初期有个适应的过程也比较正常，总体来说可能是到九十月份开始慢慢有所改善，对这些方面有学习了下，

- spring方向，spring真的是个庞然大物，但是还是要先抓住根本，慢慢发散去了解其他的细节，抓住bean的生命周期，当然也不是死记硬背，让我一个个背下来我也不行，但是知道它究竟是干嘛的，有啥用，并且在工作中能用起来是最重要的
- mysql数据库，这部分主要是关注了mvcc，知道了个大概，源码实现细节还没具体研究，有时间可以来个专题（一大堆待写的内容）
- java的一些源码，比如aqs这种，结合文章看了下源码，一开始总感觉静不下心来看，然后有一次被LD刺激了下就看完了，包括conditionObject等
- redis的源码，这里包括了Redis分布式锁和redis的数据结构源码，已经写成文章，不过比较着急成文，所以质量不是特别好，希望后面再来补补
- jvm源码，这部分正好是想了解下g1收集器，大概把周志明的书看完了，但是还没完整的理解掌握，还有就是g1收集器的部分，一是概念部分大概理解了，后面是就是想从源码层面去学习理解，这也是新一年的主要计划
- mq的部分是了解了zero copy，sendfile等，跟消息队列主题关系不大🤦‍♂️
  这么看还是学了点东西的，希望新一年再接再厉。

### 生活

住的地方没变化，主要是周边设施比较方便，暂时没找到更好的就没打算换，主要的问题是没电梯，一开始没觉得有啥，真正住起来还是觉得比较累的，希望后面租的可以有电梯，或者楼层低一点，还有就是要通下水道，第一次让师傅上门，花了两百大洋，后来自学成才了，让师傅通了一次才撑了一个月就不行了，后面自己通的差不多可以撑半年，还是比较有成就感的😀，然后就是跑步了，年初的时候去了紫金港跑步，后面因为工作的原因没去了，但是公司的跑步机倒是让我重拾起这个唯一的运动健身项目，后面因为肠胃问题，体重也需要控制，所以就周末回来也在家这边坚持跑步，下半年的话基本保持每周一次以上，比较那些跑马拉松的大牛还是差距很大，不过也是突破自我了，有一次跑了12公里，最远的距离，而且后面感觉跑十公里也不是特别吃不消了，这一年达成了300公里的目标，体重也稍有下降，比较满意的结果。

### 期待

希望工作方面技术方面能有所长进，生活上能多点时间陪家人，继续跑步减肥，家人健健康康的，嗯