【日記】自分の記事を機械翻訳して無断転載していたページの広告を剥がした

TL;DR

  • 日本語記事を機械翻訳で転載して広告収入を得ているサイトがそれなりに有るっぽい
  • 当該サイトがGoogle広告を使っている場合、DMCAテイクダウンを成立させれば検索から除外可能
    • この余波か当該サイトに広告が表示されなくなっていた
  • 見かけたらどんどん通報していくのが良さげ

本文

起きたこと

2020年11月末に、自分がQiitaへ投稿していた記事が機械翻訳されて無断転載されているのを発見しました。

そのサイトでは出典を記載しておらず、Google広告も貼っているようだったため、何とかしたいと思い知人に相談した所、「(下記ページから)Googleに報告するのが一番楽そう。」とアドバイスを頂きました。 www.google.com

このアドバイスに従って通報した結果DMCAテイクダウンが成立し、当該ページの検索からの除外と広告の停止が確認できました。

時系列

一度謎の理由で却下されましたが、反論を返信した所特に説明もなく通りました。

  • 2020/11/29: 通報
  • 2020/12/18: 却下通知が届く、即座に反論を返信
  • 2020/12/22: 通報が受理される
  • 2021/02/11: 広告が停止していることを確認(チェックしていなかったため、いつ止まったかは不明)

感想

最近ではStackOverflow機械翻訳ページが検索結果に跋扈しており辟易していますが、日本語記事が英語に機械翻訳・無断転載されているパターンもしばしば見受けられます。
そのようなサイトは百害あって一利なし、どんどん通報していくのがいいと思います。

報告は日本語で簡単にできますし、そのような形で広告費を搾取されている実態がGoogleに伝われば抜本的に対策もされていくことも期待できます(本当か?)

なお、通報後2ヵ月経ってそのサイトを確認した理由は、また自分の記事を無断転載している形跡が見つかったためです。
面倒ですが再度通報を行いました……。

最後に、的確なアドバイスをしてくれた知人に感謝します。

【Gradle】jmh-gradle-pluginでjava.lang.NoClassDefFoundErrorが出る場合の対処

TL;DR

Orikaの依存をjmhImplementationではなくimplementationで定義した所解決しました。
Orikaに限らず、ライブラリによってはjmhImplementationだと上手く動かないようです。

問題

jmh-gradle-pluginOrika 1.5.4を利用したベンチマークを作成していた所、gradle jmhでのベンチマーク実行時にjava.lang.NoClassDefFoundError: ma/glasnost/orika/impl/DefaultMapperFactory$Builderエラーで落ちる問題が発生しました。
スタックトレース全体は以下の通りです。

java.lang.NoClassDefFoundError: ma/glasnost/orika/impl/DefaultMapperFactory$Builder
        at com.mapk.kmapper.FiveArgsBenchmark.<init>(FiveArgsBenchmark.kt:24)
        at com.mapk.kmapper.jmh_generated.FiveArgsBenchmark_jmhType_B1.<init>(FiveArgsBenchmark_jmhType_B1.java:3)
        at com.mapk.kmapper.jmh_generated.FiveArgsBenchmark_jmhType_B2.<init>(FiveArgsBenchmark_jmhType_B2.java:3)
        at com.mapk.kmapper.jmh_generated.FiveArgsBenchmark_jmhType_B3.<init>(FiveArgsBenchmark_jmhType_B3.java:2)
        at com.mapk.kmapper.jmh_generated.FiveArgsBenchmark_jmhType.<init>(FiveArgsBenchmark_jmhType.java:2)
        at com.mapk.kmapper.jmh_generated.FiveArgsBenchmark_boundKMapper_jmhTest._jmh_tryInit_f_fiveargsbenchmark0_G(FiveArgsBenchmark_boundKMapper_jmhTest.java:497)
        at com.mapk.kmapper.jmh_generated.FiveArgsBenchmark_boundKMapper_jmhTest.boundKMapper_Throughput(FiveArgsBenchmark_boundKMapper_jmhTest.java:71)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:453)
        at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:437)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: ma.glasnost.orika.impl.DefaultMapperFactory$Builder
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        ... 19 more

mainメソッドを定義して実行した場合にはこの問題は発生せず、gradle jmhでのベンチマーク実行時にのみ発生しました。

対処

元々はjmhImplementationで依存を定義していましたが、これをimplementationに修正した所問題が解決しました。
本題とは外れますが、slf4j-simpleを導入しているのは、別の警告の抑制のためです。

dependencies {
-    jmhImplementation("ma.glasnost.orika:orika-core:1.5.4")
+    implementation("ma.glasnost.orika:orika-core:1.5.4")

    implementation("org.slf4j:slf4j-simple:1.7.25")

【JMH】Windows環境で実行するコアを指定してベンチマークのスコアを安定させたかった話

TL;DR

  • JMHベンチマークスコアが安定しなかった
    • (正確に特定はしていないが)全体の実行に5時間かかる内容であるため、途中でバックグラウンド処理が走った結果が原因と推定
  • start /affinity ${マスク} ${呼び出すプログラムと引数}とすることで、ベンチマークを実行するコアを限定することで、少なくともベンチマーク中のCPU使用率は安定すると思われる

本文

背景と課題

最近ProjectMapK/FastKFunctionとして、KFunction(Kotlinのリフレクションにおける関数)を高速呼び出しするライブラリを作成しています。

github.com qiita.com

このライブラリのウリは高速性であり、その証明のためにJMHベンチマークを作成しました。
一方、このベンチマークで触っていない部分の結果までそれなりにブレることがしばしば有りました。

このベンチマークは実行に5時間以上かかるため、気軽に何度も実行できません。
また、そもそもそうやって結果がブレるのであればベンチマークの信頼性も揺らいでしまいます。

ということで、何とかこの結果を安定させられないものか検討していました。

対策

Windowsでは、start /affinity ${マスク} ${呼び出すプログラムと引数}とすることで、プログラムを利用するコアとその数を制限することができます。
例えば、今回行うベンチマークのコマンドはstart /affinity 00000111 gradle jmh --no-daemonというようになります。

00000111がマスクで、1を指定すると該当するコアがプロセスに占有されます。
gradle ...以降は、実行するプログラムに関する指定です。

指定の有無でCPU使用率がどうなるかをタスクマネージャーで見た様子が以下です。
指定無しでは使用率が100%に張り付かないコアが出ている一方、指定有りでは綺麗に3コアの使用率が張り付いています。

f:id:wrongwrongwrongwrong163377:20210109235749p:plain
/affinity無し
f:id:wrongwrongwrongwrong163377:20210110000101p:plain
/affinity有り

ベンチマークが利用するスレッド数などを変更して確認した所、スレッド数 = 指定コア数であれば指定したコアの利用率が100%に張り付き、スレッド数の方が少ない場合利用が100%に張り付かなくなるようでした。
ベンチマークスコアの安定性という観点では、CPU周波数の変動なども加味すると使用率が安定していた方が良いはずなので、指定有りで実行した方がスコアが安定すると言えると思います(本当に安定するのかは確認できていません!)。

参考にさせて頂いた記事

www.atmarkit.co.jp ss64.com

1年を振り返る

昨日はアウトプット面から1年を振り返りをしましたが、今日は1年間の生活面を振り返ります。

wrongwrong163377.hatenablog.com

1年の雑感

まず今年1年の感想ですが、始めた自作ライブラリの開発をずっとやっていたのと、コロナによる変化の年というのが大きいです。

私事関連

私事の方は、今年1年を通して多くの余暇を自作ライブラリの開発につぎ込んでいました。
1月24日に最初のコミット(本当は試作とかでもう少し前から色々やっていた気がしますが)をして以降、色々なことを学びながら開発を続けましたが、残念ながら結局1年やっても開発完了には程遠いような結果となりました。
様々なことを学んでこれましたし、ここは来年も詰めていきたいと思っています。

何かに熱中して全力を傾けるというのは久々でしたし、ここまで長く集中していられるとは思いませんでした。
仕事だけでは得られない貴重な経験が出来ているかなと思っています。
願わくば来年はもう少しユーザーが増えてスターとかもついてくれたら嬉しいなー……(とは言え現状新規開発を入れれてなかったりするので、その辺もやっていかなきゃですが)。

記事を盗作された

自作ライブラリもコロナも殆ど関係ありませんが、記事を盗作というか無断で翻訳・転載されたのはかなり大きな出来事でした。

こういうことをやらかす人間は翻訳して出せばバレないと思ってるんでしょうね。
学生時代からずっとアウトプットを続けていますが、こういうことに気付いたのはこれが初めてでした。

正直ソースさえ書いて貰えれば自分の書いた記事を翻訳して転載する(& それをコンテンツにアフィリエイトで稼ぐ)程度は黙認してもいいかなと思っていますが、それも無いのは流石にNGだよね、と。

知り合いにアドバイスも貰い、相手が入れている広告がGoogle広告だったため下記窓口より通報し、先日DMCAテイクダウンが成立しました。 support.google.com

とは言え、成立したのは通報したURL4件に対してのみで、サイトそのものを止めたりはできていません。
この辺はやったもん勝ちだなあと強く思います。

仕事関連

仕事の方は、コロナでリモートワークが解禁されたというのがとても大きく感じています。
個人的にはリモートワークが合っていたみたいで、効率を落とすことなく成果を出し続けることができたかなと思います。
転職するにしても、リモート可能な、東京に縛られず柔軟な働き方ができる会社がいいなと感じるようになりました。

ただ、「この状況でも、フルリモートでも十分働ける」ことが分かったのは良かったですが、世の中が不安定になったり、会社もその影響を受けたり、運動不足で太ったりと、強く色々なストレスを感じた1年だったなとも思います。
この状況は来年に入っても早々解決することは無さそうで、暗い気分がぬぐえませんが、それでもやっていくしかないんでしょうね。

仕事の内側の事情は、まず何と言っても勤続3年目に突入しました。
何となく2年で転職するもんだと思っていたので、結構驚いています。
成果面では、去年の暮れから自分の働きかけで導入したKotlinがいい感じに成果を上げてきたのと、チームリーダーのような役割を強く求められるようになってきたなというのが有ります。

Kotlin関連

Kotlinに関しては、やっぱり導入して良かったなと強く思います。
Javaより簡潔で安全なコードが書けますし、特にnull安全周りは良い設計を考えるという意味でも役に立ちました。

Kotlinだからこれができない」というような困り方はしませんでしたし、「Javaなんて書いてるなら即刻Kotlinに移行すべき」と思う程度にはJavaで開発していたことを後悔しています(まあ状況や自分の実力を考えればタイミングはあそこしか無かったんだろうとも思っていますが)。

チームリーダー的な役割について

入社以来本来のチームリーダーが忙殺される状況が続いており、「それなら自分がやれることはやる」と宣言したのが去年の10月末頃でした。
そこから1年間、メンバーが入れ替わったり増えたり、案件の兼ね合いで他チームにヘルプに入って貰ったりしながらチームリーダーの真似事をしてきました。

今持っている主な役割は以下の通りです。

  • 主なチームメンバー(自分含む)6人 + 2人のタスク割り振り/やっていくタスクとその順番の検討
  • ヘルプに入って貰っている他チームとのやり取り
  • 進んでいる案件全体の把握と相談
  • (自分の持っている案件の開発)

チームリーダーとしてのタスク全てをやっているわけではありませんが、かと言ってコーダーとしてのタスクが減っている訳でもないので、正直大変だなと思っています。
メンバーもこの1年で3人増え、並行して走る案件も増えましたし、ヘルプに入って貰っている他チームとのやり取りも新しく増えました。
自分がやらなきゃならない開発も多い中でそれらのタスクも回していくのは正直かなり辛かったです。

個人的には、若い間に年を食ってからも使えるような技術的な基礎体力を付けるべきと思っていて、その意味では多少不満も感じる1年でした。

それでも、去年末は現状よりも少人数かつ案件2並行程度の負荷でガタガタになっていたことを振り返ると、曲がりなりにも現状を回せているのは成長でしょうか。
加えて、最近はこの状況にメンバーが慣れてきた上、今まで自分が抱えていたタスクを持っていって貰えてもいるので、負荷も下がってきてはいます。
自分が入社以来関わってきたプロダクトに対してそれなりの責任は果たしたいのと、来年はまた状況が大きく変わる部分も有るので、一旦はまだ現職で力を尽くしていくことになるかなと。

終わりに

残念ながら来年に入ってもすぐにコロナの猛威が去ることは無さそうです。
辛いことも続きますが、少なくとも仕事の方は来年3月末でひと段落を迎えそうなので、まずはそこを目指して成長していけたらと思います。

来年の今頃にはもっといろいろなことが良くなっていたらいいな……。

【ブログ94本】1年のアウトプットを振り返る【自作ライブラリ公開】

早いものでもう1年が終わろうとしています。
ということで去年に引き続き、今年のアウトプットから1年を振り返っていきます。

wrongwrong163377.hatenablog.com

アウトプットまとめ

まず今年1年で行った主なアウトプットです。

以下いくつか抜き出して見ていきます。

公開したライブラリ

この1年間はひたすらKotlin向けのマッピングライブラリを作ってました。

github.com github.com github.com github.com

最初はもっとスター付かないかなとか色々思ってましたが、まあそんなにうまくは行きませんでした。
とは言えまだ楽しんで開発できているので、来年も自分の納得できる所まで開発しようと思っています。
リフレクションとか沼過ぎて開発終わんねえ気も……

Qiita

今年は若干アウトプットの量と幅が減った気がします。

qiita.com

これらが減った理由は、ライブラリ開発の方にリソースを割いていたのもありますが、仕事は同じプロダクトに関わって3年目に入り、0 -> 1の新しいことへの取り組みが少なかったので、そちらの方が影響が大きかったと思います。
来年は仕事でももっと新しいことに取り組む機会が有ればいいですね。

紹介したい記事

OSS以外では以下の取り組みを一番アピールしたいです。
入社以来初めてのアルゴリズム力が無ければ解けない問題への取り組みだったので、やり切れたのは非常に嬉しかったです。

qiita.com

はてな

今年の初めにPCを組んだので新しくブログを立てました。
が、当初思ってたよりも更新できず……。

やることが多いと自作PCとかの方は後回しになっちゃうなと強く感じます。
今年も全然ゲームができなかったので、PC周りに興味を向けにくいのというのも大きいですね……せっかくいいモニタ買ったのに。

wrongwrong-pc-parts.hatenablog.com

このブログの方はQiitaに書かなくてもいいようなプログラミングに関わる内容に絞りました。

wrongwrong163377.hatenablog.com

はてなの方も去年に比べるとアウトプット量は少し減ってしまいましたね。

終わりに

1年のアウトプットを振り返りました。

一番大きかったのはやはり自作ライブラリの公開ですね。
まだ大きく使ってもらえる程にはなっていないので、来年も引き続き育てていきたいと思います。

ブログへのアウトプットは、技術系の内容が恐らく80本弱だったので、去年立てた目標は達成できませんでした。 振り返ってみると、2017年からは4年連続で50本以上、2018年からは3年連続100本程度のアウトプットが継続できているのは我ながら結構すごいとは思いますが、やっぱり目標を達成できないのは残念ですね。
ということで、来年もブログが合計100本位、内技術系の内容が80本位書けるよう色々やっていこうと思います。
後はリフレクションネタをまとめた同人誌とか作れたらなー……なんて。

【GitHub】Branch protection ruleでRestrict who can push to matching branchesが効かなかった話

TL;DR

  • Include administratorsしない場合、自分がadminならRestrict who can push to matching branchesは機能しない

やりたかったこと

間違えてフォーク元にpushする事故を防ぐためBranch protection ruleを調べていた所、Restrict who can push to matching branchesという機能を見つけました。
これは下記の通り、push可能なユーザーを制限する機能という記述が有ります。

f:id:wrongwrongwrongwrong163377:20201002104732p:plain

一方、自分が試した所、この項目だけを弄ってもpushできてしまっていました。

対処

下記画像の通り、Include administratorsすることで問題を解決できました。
今回は全員がpushできないようにすることが目標だったので、ひとまずこれで解決しました。

f:id:wrongwrongwrongwrong163377:20201002104930p:plain

【プログラミング】Intellij IDEAでVueファイルの@エイリアスが解決できなかった問題への対処

TL;DR

  • Webpackのコンフィグファイル名を間違えていた

原因/対処法

Cmd + Shift + aPreferences -> Language & Frameworks -> JavaScript -> Webpackを開き、webpack configuration fileを確認した所、webpack.config.jsとなっているべき所がwebpack.common.jsとなっていたことが原因でした。
ファイル名を直した所機能するようになりました。

参考にさせて頂いた記事