記事の効率的な読み方を試行錯誤

最近、追う記事が多くてキャッチしきれなくなってきたので、スタイルを変えてみた。

もともと

TechCrunchとかはてぶとかTwitterとかで流れているものを、いちいち中身を追ってました。しかし、この方法だとどんどん流れるし、読んでて調べないとわからないことを調べているとどんどん流れていってしまいます。見る範囲が狭いときは、この方法でもよかったが、プログラミング、AWS、AI、マーケティング、英語、ビジネス、IR… とか増えていったときに、もう多すぎて流れていってしまって見落としが多いことに気づき、やり方を見直しを行いました。

Pocket

まず、読むだろう記事をPocketにストックしていくようにしました。以前はPocketを使っていたんですが、ここ2,3年全然つかっていなく、アップデートを確認してなかったんですが、音声再生の機能が格段にあがってました。コードが貼ってあるような記事はちょっと辛いのですが、それ以外のビジネス関係の読み物にはかなりあっていて、ほとんどこれで再生して聞いています。聞いている間に別の記事をストックしていくという感じで、短縮もできています。

Evernote or Notion

Pocketで格納した記事で残したいものは、さらにEvernoteとかNotionにシェアします。そうするとEvernote or NotionでWebクリップをしてくれるので残せます。

まとめ

気になったタイトルとかキーワードの記事はさっとPocketにためて、Pocketからまとめて読んだり、音声再生をして聞いたりして、残したいものはEvernoteかNotionにWebクリップすれば、かなりいいスクラップブックになるかなと思いました。他にもいいやり方があれば教えていただけるとー。

GraalVMのnative-imageを少し試してみる

GraalVMのnative-imageがそろそろ色々使えそうなので、試してみる。

Javaやってる人は SDK Man は入ってると思うので、それ前提でメモします。
(SDK Man のインストールはこちら -> https://sdkman.io/ )

GraalVM のインストール

まずは、GraalVMのインストールを行う。

$ sdk install java 20.0.0.r11-grl

GraalVMを使ってnative-imageをinstallする

GraalVMのパッケージツールでnative-imageをinstallする。

$  gu install native-image

これでnative-imageのinstallが完了。

かんたんなJavaコードを書く

Sample.java

class Sample {
  public static void main(String[] args) {
   System.out.println("Hello World");
  }
}

Javaをコンパイルする。

$ javac Sample.java

コンパイルすると、classファイルができる。

Sample.class

native-imageでコンパイルする


$ native-image Sample sample // 最後のファイル名を指定しないと、デフォルトで小文字になる

下記、ファイルができる。

Sample

このファイルは実行できる。

./sample

比較する

JavaVMでの実行とnative-imageでの実行を比較する

$ time ./sample
real    0m0.007s
user    0m0.003s
sys     0m0.003s

======

$ time javac Sample
real    0m0.179s
user    0m0.110s
sys     0m0.035s

JavaVMの起動速度が入ってしまっていると思うが、結構違う。
JVMの起動後にどのくらい違うのかはまた次回。
あと、こんな1ファイルで使う人もいないと思うので、Jar での作成方法もまた次回。

MyBatisが色々てんこ盛りになっていい感じになっている件

久しぶりにSpringBootの環境構築をやろうかと思い、ORMをどうするか選定していたところ、MyBatisが結構進化していたので、メモ。

MyBatis3DynamicSql

  • XMLが不要になる
  • コード量が小さくなる
  • JavaでタイプセーフにSQLがかける(JOOQみたい)
  • https://mybatis.org/generator/quickstart.html

こんな感じでかけます。

        List<TableCode> records = mapper.selectByExample()
                .where(id, isEqualTo(3))
                .build()
                .execute();       

        List<TableCode> records = mapper.selectByExample()
                .where(id, isEqualTo(3))
                .or(description, isLike("f%"))
                .build()
                .execute();    

        List<TableCode> records = mapper.selectByExample()
                .where(id, isLessThan(10), and(description, isEqualTo("foo")))
                .or(description, isLike("b%"))
                .orderBy(id.descending())
                .build()
                .execute(); 

JOOQみたいに、タイプセーフでSQLがかけるのはとてもすごい進化だと思います。

FreeMarker Tempalte

前に書いたとおりのFreeMarker Templateは健在。XMLがいやでFreeMarkerにしたけど、複雑なクエリはやはりJavaコードじゃなくて、素のSQLの方がいいイメージなので、継続して使用します。

sample.ftl

select
 *
from
  sample_table
where
  id = <@p name="param.id" />

こんな感じでかける。

from句とかを別のftlファイルにして、includeして使うことも可能です。

Thymeleaf Template

Doma2とかでやっている2WaySQLがThymeleaf Templateで実現している。Doma2より書き方は野暮ったいけど、一応2waySQLはできる。

SELECT * FROM names
  WHERE 1 = 1
  /*[# th:if="${not #lists.isEmpty(ids)}"]*/
    AND id IN (/*[# mb:p="ids"]*/ 1 /*[/]*/)
  /*[/]*/
  ORDER BY id

MyBatis Migrate

これは前からあったみたいなんだが、Flywayの陰に隠れて知らなかった。
機能的には十分っぽいので、試してみる。

詳細 => https://mybatis.org/migrations/

Mybatis Log Plugin (Intellijのみ)

これがあると、条件分岐があって、引数のバインドが全部終わったSQLを出力してくれるので、デバッグに便利です。
必需品かと思います。(Domaは標準でありますが)

https://plugins.jetbrains.com/plugin/10065-mybatis-log-plugin

最後に

タイプセーフでSQLかけるし、2WaySQLあるし、Migrateあるし、なんかMyBatisで全部OKなんじゃないかとおもいました。おそらくThymeleafは

NginxのCache設定

Nginx + SpringBoot の構成で環境を構築している。

まだ、静的ファイル(.css,.js,.jpg,.gif,.map) はCDNを使わない感じでなんとでもなる規模だが、アクセス数が増えていくと、ちょっとSpringBootだけだとレスポンスが遅くなってきたので、対策する。

静的ファイルはSpringBootで返して、Nginxでキャッシュする設定にする。

SpringBootは設定は特になし。

Nginxに下記の設定を行う。


server { location / { // 省略 proxy_ignore_headers Cache-Control Expires; proxy_cache cachezone; proxy_cache_valid 404 5m; // 省略 add_header X-Cache $upstream_cache_status [always]; } }

proxy_ignore_headers Cache-Control Expires; この設定が必要です。

キャッシュがヒットしてるかどうかは、add_header で確認できますが、HTTPステータスが正常系しか動作しません。
add_headeralways をつけると、どのHTTPステータスでもでてくので、確認できます。

このようにすると、ある程度の規模までは、CDN使わずに、サクサクいけます。
最近ではHTTP/2でコネクション数の上限もほとんど気にしなくていいですし。

IntelliJでNuxt.jsのdebugできるようにする(chrome/opera)

IntelliJでNuxt.jsをdebug(breakpoint)できるようにしたくて、設定するメモ。

nuxt.config.jsを変更する

下記の3行を追加する


extend(config, ctx) { if (ctx.isDev && ctx.isClient) { //追加 config.devtool = 'eval-source-map' //追加 } //追加 // 省略 }

$ npm run dev を実行する

Chromeのプラグインをインストールする

下記のプラグインをインストールする

https://chrome.google.com/webstore/detail/jetbrains-ide-support/hmhgeddbohgjknpmjagkdomcpobmllji?hl=ja

インストール後にデバッグするタブで下記のアイコンを右クリックする

その後、inspect in IDEA をクリックする

下記のバーがでてきたらデバッグモードになる

breakpointを貼って、そのURLまで遷移すれば、ステップ実行ができるようになります。

IntellijのNuxt.jsでimportのailiasを設定したい

Intellijのvueとかjsのサポートがかなりよくなってきたので、1IDEで完結した欲求がでてきました。
vscodeだとある程度勝手に認識してくれるんだけど、Intellijはできないみたいで設定してあげる必要がある模様。

nuxt.config.jp

module.exports = {
  resolve: {
    extensions: ['.js', '.json', '.vue', '.ts'],
    root: path.resolve(__dirname),
    alias: {
      '@core': path.resolve(__dirname + '/src_core'),
      '@web': path.resolve(__dirname + '/src_web'),
    }
    // 省略
  },

このrootaliasを追加すればいける模様。(resolveを書いてなかったらそれも追加で)

import sampleRepos from "@core/modules/repository/sampleRepos
import samplePage from "@web/modules/repository/samplePage

これがジャンプできるようになる。便利

Intellijでdebug実行すると warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

ブートストラップクラスパスが追加されているため、共有はブートローダークラスでのみサポートされます

ということらしいが、intellijでしか警告がでない。

Intellij Idea > preference > Build, Execution,Deployment > Async Stack TraceInstrumenting agent をunlockすれば、でなくなる。

intellijでdebugするとこの警告がでてくる warning: forcing TieredStopAtLevel to full optimization because JVMCI is enabled

OpenJDK 64-Bit GraalVM CE 19.3.0 warning: forcing TieredStopAtLevel to full optimization because JVMCI is enabled

JVMCIが有効になっているため、TieredStopAtLevelを完全に最適化する こういうことらしいが、gradle bootRun では発生しない。Intellijで発生する。

IntelliJの設定かなにかだろうと思い設定を確認

Run/Debug Configurations の中に Enable launch optimization があり、これをunlockすると警告がでなくなった

Vue.jsのcomputedで引数を使いたい

Vuejsで便利なcomputedですけど、引数取りたいって思うタイミングがあり検証。
ちなみに引数とりたいタイミングは、ループでテーブル作成してるときとかです。

lambda式(アロー関数)を使えばできました。

<template>
  <div id="app">
    <p>sample('a'):{{sample('a')}}</p>  // <- 使用箇所
    <p>sample('r'):{{sample('r')}}</p>  // <- 使用箇所
  </div>
</template>

<script>
export default {
  name: "App",
  computed: {
    sample() {
      return r => r === "a";   // <-  ここでアロー関数を実行
    }
  }
};
</script>

出力結果はこちら。

sample('a'):true

sample('r'):false

computed特有のキャッシュ等が効かないらしいけど、methodとwatchでやるんだったらあんまりかわらなくて、computedですっきりかけた方がいいかなと思うので採用します。

mapとflatmapのメモ

mapとflatmapのメモ.

map: 個数が変わらない。2個渡したら2個返ってくる
flatmap: streamに変換させて、それを合成する。戻ってくるのはstreamが1つ。flatmapはstreamを合成してくれる感じのいいやつ。

@RunWith(JUnit4.class)
public class SampleTest {
    @Test
    public void test() {

        // map
       Arrays.asList("a,b,c", "d,e")
            .stream()
            .map(e -> Arrays.stream(e.split(",")))
            .forEach(System.out::println);

        // flatmap
        Arrays.asList("a,b,c", "d,e")
            .stream()
            .flatMap(e -> Arrays.stream(e.split(",")))
            .forEach(System.out::println);
    }
}

出力結果は下記

# map
java.util.stream.ReferencePipeline$Head@18ce0030
java.util.stream.ReferencePipeline$Head@4445629

# flatmap
a
b
c
d
e