サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
中東情勢
yaruki-strong-zero.hatenablog.jp
文字コードの円記号問題を復習したのでメモ。 円記号問題 参考) 円記号 - Wikipedia ざっくり 例えばmacのvscodeにて、文字コードをshift-jisに設定して[¥]を入力して保存したあと、一度閉じて再度Shift JIS指定で開くと[¥]で保存したはずなのに[\]が表示されている。 何故こんなことが起こるのかというと、shift-jisでは[¥]と[\]は同一の文字であるから。 文字を表すバイト列は[¥]も[\]も5cになる。 バイト列5cを[¥]として表示するか、[\]として表示するかはフォントやエディタによりけりという感じ。 つまり、shift-jisで[¥]と入力すると、5cというバイト列で保存され、次に読み込みされた際には[\]として表示されたという感じ。 shift-jisとUnicode間での変換を行う際の問題 shift-jisに対して、unicodeでは
データの削除機能において、何らかの理由でデータは残しておきたい場合には「削除フラグ」が使われがちだが、これは絶対にやめたい。 この場合は「削除テーブル」を用意してそちらにデータを移し、元テーブルからはレコード削除を行うようにするべきだと思っている。 それについて書く。 削除フラグを使うと事故りやすい シチュエーション:販売終了商品が削除フラグ=1でテーブルに残っている 例えばある商品が販売されていたが、今は販売されていない商品が以下のようなテーブルとレコードで表現されているとする。 id 商品名 価格 削除フラグ 1 ガム 100 1 2 キャンディ 120 0 id: 1のガムは今はもう販売されていないので削除フラグが1(true)になっている。 しかし、商品購入履歴などで必要なのでデータはそのまま残っている。 商品テーブルに削除商品があることを常に意識してないとすぐ事故る 「取り扱い商
例えばユーザー名の重複登録をNGとする場合、こんな感じでバリデーションと登録処理を書くことが多い。 ※疑似コードです begin name = "山田太郎" // dbからデータを取ってみて存在しないことを確認する user = getUserByName(name) if user != null { return false } createUser(name) commit return true でもこれだと名前が重複したユーザーが登録されてしまう可能性がある。 理由はこちら: yaruki-strong-zero.hatenablog.jp 防ぐには テーブルにユニーク制約をつけて、再実行処理を組み入れる これが一番確実。 ユニーク制約があることで重複データが登録されようとしてもエラーになり絶対に入らない。 重複エラーでアプリが落ちるのを避けたければ再実行処理を入れる。 name
postgres のtimestampはタイムゾーンをもってない 。 だからデータを入れるとき、取得するときにタイムゾーンを気にしないといけない。 timestamp with time zoneで定義すべきかなと思う。 基本的にシステム内部で時間を扱うときは統一的にUTCで扱い、出力時に用途に応じて変換してやるのが良いとおもってる。 参考) www.m3tech.blog
フルリモート勤務になってほぼ家で仕事するのでデスク周り環境整備としてまず昇降デスクを購入した。 買ったのはこれ。 FLEXISPOT スタンディングデスク 電動式昇降デスク 高さ調節 メーカー5年保証 人間工学 パソコンデスク ブラック ゲーミングデスク E7B FLEXISPOTAmazon FLEXISPOT スタンディングデスク天板 昇降デスク天板 DIY用天板 (メイプル, 160*70) FLEXISPOTAmazon 3ヶ月ほど利用して、結果から言うと「かなり快適」だったのでオススメしたくて書いてみる。 購入にいたるまで そもそも持っていた机がかなりショボくて、狭いしガラス天板なのでモニターアームもつけられなくて何かしら買いたいとは思っていた。 どんな机を買おうかとぼんやり考えてたら「昇降デスクおすすめ」みたいな声がちらほら聞こえるようになって気になってた。 ただ、結構値が張る
Goのnilチェックで躓いたのでメモ。 nilチェックは value == nilだとだめな場合がある こんな挙動になる type Nameable interface { GetName() string } type Human struct { name string } func (h *Human) GetName() string { return h.name } func IsNilHuman(human Nameable) bool { if human == nil { return true } else { return false } } func main() { if IsNilHuman(nil) { println("nilだ") // こっちにはいる(イメージ通り) } else { println("nilではない") } var nilHuman *
システム運用アンチパターン読んだ。 システム運用アンチパターン ―エンジニアがDevOpsで解決する組織・自動化・コミュニケーション 作者:Jeffery D. SmithオライリージャパンAmazon あまりゆっくり時間とれなくて結構時間かけて少しづつ読んだのでもう忘れてるところもあったり、ちょっとうまく読み取れなかったところもあったりして間違った理解あるかもだが、印象に残った部分だけ書いてみる。 何が目的なのかを見失わないようにする いくつかエピソードがあったが「何が目的なのかを見失わないようにする」というものが共通してあった気がする。 アラート通知 例えば、アラート通知が頻発するような状態だと人は次第にそれを無視するようになる。 なんのためにアラート通知を出しているのかと言うともちろんアラートの発生原因である問題を確認・解決するためなので、アラート通知を発生させまくることによってそれ
dockerコンテナを使ってローカルで開発作業をするとき、local側のディレクトリとコンテナ側のディレクトリを共有してコンテナ側で生成されるファイルを永続化したりする事がある。 このとき、コンテナ側で生成されたファイルがroot権限で作成されたりするとlocal側での取り扱いがめんどくさい。(sudoしないとファイルを削除できなかったり) ローカル側のUID, GIDとコンテナ側でのUID, GIDを揃えられるようにDockerfileやdocker-composeを用意しておくと、このあたりがスムーズに行くようになる。 #Dockerfile FROM ubuntu:20.04 ARG USERNAME=app ARG GROUPNAME=app ARG UID=1000 ARG GID=1000 RUN groupadd -g $GID $GROUPNAME && \ useradd
spring bootの使い方を勉強しててざっくりの使い方は分かったが、印象としては黒魔術的というか「なぜこれでwebリクエストを受けられてレスポンスを返せるのか」が全くわからなかった。 全くわからなかった原因として、Spring Bootは構成としてかなり上部レイヤーに位置していて、その下にはSpring FrameworkやJava Servletなどが存在しており、これらの知識が不足している事があった。 裏で何が行われているかをなんとなくでも知っておきたかったので調べた。 分かったことをメモとして記載する。 (想像で補完している部分もあるので間違いがあったら教えてほしいです。) Spring Web MVC Spring BootでWebアプリケーションを書く際、以下のようなコードをControllerに書く。 @Controller public class HelloContro
postでidを以下の様に複数送った時、 id = 1 id = 2 Go echoでスライスで取得するには以下のようにすると取れた func (cont *Controller) Create(c echo.Context) error { ..... params, err := c.FormParams() if err != nil { //パラメータ取得に失敗 c.Error(err) return err } ids := params["id"] // []string{"1", "2"} ....... FormValue("id")だと"1"しかとれない。
Goで金額計算するのでdecimal型を探したが、基本ライブラリには無いようなのでどうしようか悩んでいた。 基本ライブラリにmath.bigパッケージがあり、Floatの精度を自由に決められるようなものがあったのでそれで行けるかと思ってたけど(不必要に外部ライブラリを使いたくなかった)考え方が根本から間違ってたのでまとめる。 (結局はdecimal型を提供してくれるライブラリを採用した。 decimal - GoDoc) 参考: 料率計算における小数の扱いについて なぜBigDecimalを使わなければならないのか | Java好き float型で精度をたっぷり用意すれば金額計算でも使える? 「float型は誤差が出る」というのは知ってたので金額計算は使えないという認識はあった。 でも基本ライブラリにdecimalが無いのでどうしようか悩んでる時、ふと 今回扱うのはせいぜい少数第2位くらい
僕はテスト駆動開発(以下TDD)の信者だ。 TDDを学びだした最初は「TDDのメリット」とは「テストコード」が同時に出来上がり回帰テストが可能になる事だと思っていた。 しかしすぐに「TDDで開発を行うとシステムの複雑性が下がりやすい」事こそが最大のメリットであると気がついた。 その事について書く。 TDDで開発しない場合 構造に対して興味が薄い人が作業した場合、以下のような感じでコードが書かれている事が良くある。 # userのtypeを更新する(コード構造イメージを示すだけで、処理自体に特に意味はない) X処理() { # DBからデータ取得する処理 user = load() if user.status == 1 { user.type = 1 } else { user.type = 2 } # DB保存処理 save(user) } データの取得や永続化と処理がごっちゃに実装され
GoでDBアクセスする為のサンプルコードを探すとどこもこんな感じ func main() { # dbコネクション(pool)を取得 pool, err = sql.Open("driver-name", *dsn) if err != nil { // This will not be a connection error, but a DSN parse error or // another initialization error. log.Fatal("unable to use data source name", err) } defer pool.Close() # poolを使ってDBアクセスするコード ...... } Openしたコネクションはアプリ終了時にdefer によってClose()処理されて終わる。理解した。 すべてmain()に処理があったり、数個の関数で
やりたかったこと IDが重複しないことを確認してから、DBにレコードを追加したかった。(IDの自動インクリメントは使わないものとする) ユニーク制約があるので、重複登録しようとしてもエラーになるのだが、 予めチェックしてエラーにならないようにしたかった。 トランザクション分離レベルをSERIALIZABLEにすれば可能だと思っていた SERIALIZABLEはwikipediaによると 複数の並行に動作するトランザクションそれぞれの結果が、いかなる場合でも、それらのトランザクションを時間的重なりなく逐次実行した場合と同じ結果となる。 とのこと。 「時間的重なりなく逐次実行した場合と同じ結果となる」のだから だから特に問題なく目的が達成できると思っていた。 だが出来なかった。 以下実行イメージ お題:【TableAにID=100が存在しないことを確認してからID=100のレコードをTable
みずほ銀行の本を読んでいて、バッチ処理は鬼門だなと感じた。 みずほ銀行システム統合、苦闘の19年史 史上最大のITプロジェクト「3度目の正直」 作者:日経コンピュータ,山端 宏実,岡部 一詩,中田 敦,大和田 尚孝,谷島 宣之発売日: 2020/02/14メディア: Kindle版 システム障害はなぜ二度起きたか みずほ、12年の教訓(日経BP Next ICT選書) 作者:日経コンピュータ発売日: 2014/02/28メディア: Kindle版 個人的な経験でもバッチ処理で悩まされた事は多いので俺的バッチ処理ベストプラクティスを考える。 考慮不足もあるかもしれないので、もしなんかあればツッコミがほしい感じ。 その1:できるだけバッチ処理は減らす その2:1処理1トランザクションにする その3:異常発生時、正常に処理できるものは処理してしまうようにする その4:バッチ処理再実行時、未処理デ
こんがらがったシステムの保守開発で苦労した経験から新規開発では「シンプルな構成・シンプルな実装にしよう」という話が出る。 目指す方向としては間違って無いように思えるのに、それだけだとうまく行かない。 「保守しやすい構造」とはそれなりに多くの知識が必要なので、これらの知識を持たず単純に「シンプルな構成・シンプルな実装」を目指すと失敗する。 「保守しやすい構造」を作るには「どういう構造が保守しやすいのか?」を学ぶ必要がある。 これについて書く。 「シンプル」を目指したつもりが複雑になって失敗する例 まずは、ありがちな失敗例を示す。 実装する処理を減らしてシンプルにしたら複雑化した コードの複雑さを減らすため、実装する機能を絞った。 コード量が減ったのでシンプルになった。 しかしここで削られた機能の処理は結局はどこかでやる必要があった為、後日別の場所(連携する別システム側など)に実装された。 や
Dockerを使ったサービス構築は aws ECSのほうがいろいろ便利そうだけど、 とりあえず基本を理解するためにEC2インスタンスを立てて、 Dockerをインストールしnginxイメージでコンテナを作成しブラウザからのアクセスできることを確認してみた。 EC2インスタンスを立てる 無料枠で試すので マシンイメージ(AMI)は 「Amazon Linux 2 AMI (HVM), SSD Volume Type」 タイプはt2.microを指定。 セキュリティグループは、ssh用の22番とHTTP用の80番を許可したものを指定する。 EC2インスタンスに入ってDockerをインストールする インスタンスが立ち上がったら、public DNSを確認してsshログインする。 user名は[ec2-user]だったので(デフォルト?変更できる?) ssh ec2-user@[DNSアドレス]
例えば「ユーザー名」など重複を許さない項目はDBへ登録クエリを投げる前にバリデーションで重複チェックするが、普通にやっていると「重複チェックをパスしたのに、DB登録実行時点では重複が発生している」となるケースが存在する。 「重複チェック」と「DB登録実行」が同一トランザクション内に記載されていても起こる。 ※ファントムリードが起こるために発生する。 二人(A君、B君)が別の画面から同時に同じユーザー名で登録を実行した場合 A君:重複チェック => OK(重複は存在しない) B君:重複チェック => OK(重複は存在しない) A君:DB登録実行 => OK(重複は存在しない) B君:DB登録実行 => NG(A君の登録したユーザー名と重複) この状況を防ぐには、「重複チェック」の際に対象テーブルに対してテーブルロックをかける必要がある。 そうすれば、イメージ通りの挙動になる。(が、非推奨)
「俺が考える最強の契約管理システムを作る」というタイトルのYoutube動画を投稿している。 [再生リスト] 俺が考える最強の契約管理システムを作る - YouTube こんなん。 youtu.be 作業リポジトリも公開してます。 GitHub - mixmaru/my_contracts: 俺が考える最強の契約管理システム なんでそんなことをやってるか? 作りたいシステムがあったので、作るついでに録画して公開することで「作業量は同じでアウトプットが2倍になってお得」みたいな考え。 どうやってるか? Ubuntuデスクトップに「SimpleScreenRecorder」をインストールして録画してる。 ショートカットキーで録画スタートストップ出来る。 最初は見られたくないところ(簡単な英単語を翻訳にかけてるところとか。。)は録画ストップしてたけど、最近はあまり気にしなくなってきた。長々と調べ
デフォルトのLogging設定だと 実行時エラーが起こった時に、 Debug=Trueの場合: ブラウザ上にエラーメッセージとスタックトレースが表示される。 Debug=Falseの場合: ブラウザ上にはnginxのstatusコードのみ。 となっていて、本番環境でエラーが起こった場合の原因を探りにくい。 adminとしてメールアドレスを設定しておくと、そこにメールが飛ぶようにデフォルト設定されているらしいが、 ファイルに出力したいと思ったので下記設定を行った。 ※ec2上Docker運用でこのログファイルをec2<->コンテナで同期させた場合、パーミッションがrootになってしまいDjangoからログが書き込まれなかった。要調査。 ↑調査したところ、ちゃんと書き込まれていた。構文エラーのときにはロガー自体が動作しないのでログに書き込まれないという状態だった。 パーミッションがrootにな
macキーボードを認識させる デフォルトでは英数・かなキーおしても認識していなかったので下記設定を行った。 参考) https://qiita.com/koreyou/items/341e1fac95c72d9743ad sudo dpkg-reconfigure keyboard-configuration を実行して、下記を選択 Apple アルミニウムキーボード (JIS) Japanese Japanese - Japanese (Macintosh) No toggling No temporaly switch The default for the keyboard 英数・かなキーでIME切り替えできるようにする ubuntu画面の右上の入力切替で「日本語(Mozc)」を選択する。(なければ追加する。) 同じく画面右上の入力切り替えドロップダウンメニューの中から「ツール」->
必要になる数値 [見積もり行数(行)] テーブルの総行数の見積もり。 そのテーブルが最大でどれくらいの行数になるのかの見積もり [平均行サイズ(バイト)] テーブルの行長が可変の場合、そのテーブルの平均行サイズ [ページサイズ(バイト)] 扱われるデータ単位であるページのサイズ。 [ページヘッダサイズ(バイト)] ページのヘッダ領域(ユーザーデータが入らない)のサイズ [空き領域率(%)] ページに、ここに指定されたパーセンテージ領域が空き領域として確保される。 [バッファサイズ(ページ)] メモリ上にバッファとして保持しておくページ数(下記計算では未使用) [データ所要量(バイト)] テーブルの総バイト数 データ所要量を求めるには? 1ページあたりで使えるサイズを求める 1ページあたりで使えるサイズ = (ページサイズ - ページヘッダサイズ)* (1 - 空き領域率) 1ページあたりに
ぼやっとは理解してたけど、この記事を見て知識が定着した気がする。 DI・DIコンテナ、ちゃんと理解出来てる・・? - Qiita この記事ではDIとDIコンテナとサービスロケータについて触れてたけど、 ここではDIについてだけ改めて自分でまとめてみる。 サンプルケース 例えばこんなコードがある。 ※phpぽいけど疑似コードです。 class Human { public void function __construct(string name) { this->brain = new Database() # DBアクセスライブラリ this->name = name } # 覚える public void function memolize(string keyword, string some_string){ this->brain.save(keyword, some_strin
Djangoのmodelからデータを取り出す方法をまとめとく 参考) クエリを作成する | Django documentation | Django ※こっちのほうがいい感じにまとまっているかも Django データベース操作 についてのまとめ - Qiita データ構造 from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def __str__(self): return self.name class Author(models.Model): name = models.CharField(max_length=200) email = models.EmailField() def __
cypressとは? https://www.cypress.io/ ブラウザを操作してwebアプリのテストを自動実行できる。 seleniumとかと同じようなカテゴリに属すると思う。(ただし、クロスブラウザテストは現状できない) seleniumよりも環境構築が簡単で気軽に試せる感じ。npm install cypress webのelementの取得周りもけっこう使いやすい印象だった。 インストールや実行についてはこのあたりを参考に。 Installing Cypress | Cypress Documentation cypressを触ってみた - Qiita まだ全然使いこなせていないが、やったことをメモしとく。 テストの書き方 Rspecっぽく書ける。 cypress/integration/text_spec.js describe('ログイン画面', () => { befo
参考)Active Record マイグレーション - Rails ガイド $ bin/rails db:migrate 最新状態までマイグレートする $ bin/rails db:migrate VERSION=20080906120000 指定のバージョンまでマイグレートする $ bin/rails db:rollback 一つ前に戻す $ bin/rails db:rollback STEP=3 3つ前に戻す $ bin/rails db:migrate:redo STEP=3 3つ前に戻して再度migrationを実行しなおす $ bin/rails db:reset DBをdropして再度設定する $ bin/rails db:drop db:setup と同等 ↑※マイグレーションを再実行しているのではなく、schema.rbから反映しているだけ。 ※schema.rbにはトリ
$ pipenv lock でエラーが出るようになった。 pipenvのバージョンは2018.4 ※以前は出てなかったのでmacのupdateが問題だった? TypeError: 'module' object is not callable issueが上がっていた。 github.com 修正されたようなのでpipenvを2018.10にアップデートしたら解消した。 $ pip install -U pipenv
herokuデプロイに必要で雰囲気で使っていたが、 ちょっと調べたのでまとめておく。 pipenv バージョン 2018.7.1 PipfileとPipfile.lockの違い Pipfileはどういうパッケージをどのバージョンで入れたいかを指定するファイルで、 実際に入ったパッケージの詳細な状態情報がPipfile.lock。 Pipfile [packages] django = "*" (最新版を入れたい場合) django = "==2.0.0"(特定バージョンを入れたい場合) django = "==2.*" (2の最新バージョンを入れたい場合)Pipfile.lock "django": { "hashes": [ "sha256:97886b8a13bbc33bfeba2ff133035d3eca014e2309dff2b6da0bdfc0b8656613", "sha256
joins, includes, eager_load, preloadはよく似た状況を作り出すがいまいち理解し切れなかったので整理。 参考) ActiveRecordのjoinsとpreloadとincludesとeager_loadの違い - Qiita N+1問題を回避し、かつ、、 where条件に関連テーブルのカラムを使いたい場合はeager_load、 joinを使いたくない場合はpreload N+1問題は考慮せず、単にwhere条件に関連テーブルのカラムを使いたい場合はjoinsを使うのが良さげかと思った。 ◆joins Post.joins(:comments).where("comments.id = 1") ・関連テーブルデータ先読みはしない ・inner joinを使った絞り込みをしたい時 ・joinして1クエリを発行する 先読みしないのでN+1問題の解決にはならない
次のページ
このページを最初にブックマークしてみませんか?
『yaruki-strong-zero.hatenablog.jp』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く