まだらもよう

Qiitaに投稿できないメモ書きなど

Nuxt.jsでdotenv

https://github.com/nuxt-community/dotenv-module

install

$ yarn add @nuxtjs/dotenv

nuxt.config.js

{
  modules: [
    '@nuxtjs/dotenv',
 ]
}

プロジェクトルートにenvfileを作成

API_URL=https://example.com:1337

これでcontext.envprocess.envに追加される。

クライアントでも使用できるように、https://ja.nuxtjs.org/api/configuration-env/を参考に以下を設定

nuxt.config.js

  env: {
    baseUrl: process.env.BASE_URL || 'http://localhost:3000',
    apiUrl: process.env.API_URL || 'http://localhost:1337'
  }

1. Two Sum

https://leetcode.com/problems/two-sum/

整数の配列が与えられたとき、それらが特定のターゲットになるように2つの数のインデックスを返します。

各入力は厳密に 1つの解を持つと仮定することができ、同じ要素を2回使用することはできません。

Example:

Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

Answer: ハッシュテーブルを使う

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    // (key: numsの値, value: index)
    const map = new Map();
    
    for (let i = 0; i < nums.length; i++) {
        if (map.has(target - nums[i])) {
            return [map.get(target - nums[i]), i]
        } else {
            map.set(nums[i], i)
        }
    }
};

データ構造

データ構造とは、データの順番や位置関係を定めたもの。データをメモリに保存していく際、目的にあったデータ構造にすることで、処理効率を高めることができる。

リスト

  • 各データがポインタを持ち、ポインタは次のデータを示す。
  • ポインタを頭から辿ることしかできないので、アクセスに時間がかかる。順番にデータを辿ることをシーケンシャルアクセスという。
  • 追加や削除は、ポインタを操作するだけなので簡単。
  • アクセスするときはO(n)。追加・削除はO(1)。
  • 普通のリストは、最後尾のデータはポインタを持っていないが、先頭のデータを指すポインタを持たせることで環状リストになる。
  • 普通のリストは、次のデータを指すポインタを1つ持っているが、前のデータを指すポインタも持たせることで双方向リストになる。(ポインタを2つ持つ)

配列

  • 添字を使って直接データにアクセスできる。このことをランダムアクセスという。
  • アクセスは簡単だが、追加や削除は後述の理由で時間がかかる。
  • 追加する時は、まず配列の最後に空間を追加し、追加したい場所まで1つずつデータをずらし、空いた空間にデータを追加する。
  • 削除する時は、まずデータを削除し、空いた空間に1つずつデータをずらして埋めていき、空いた空間が最後になったらその空間を削除する。
  • アクセスするときはO(1)。追加・削除はO(n)。

スタック

  • Last In First Out(LIFO)。後入れ先出しのデータ構造。
  • データを追加することをpush, 取り出すことをpopという。
  • 常に最新のデータにアクセスしたいときに有効

キュー

  • First In First Out(FIFO)。先入れ先出しのデータ構造。
  • データ追加をエンキュー、取り出すことはデキューという。

ハッシュテーブル

  • データをハッシュ化 -> mod演算 -> その結果によって配列のどこに格納するかを決定する
  • 適当に配列の最初からデータを挿入していくと、取り出すとき線形探索するしかない
  • ハッシュ化〜mod演算をもとに格納場所を決定していれば、取り出すときにハッシュ化〜mod演算することで格納場所を特定できる
  • 格納する場所が衝突してしまった場合、データをリスト化する。

ヒープ

  • 木構造の1種で、データを自由に追加できるが、取り出せるのは最小値からのみ。最小値を頻繁に取り出す場合に便利。
  • 子は親より必ず小さい。ノードは2つまで子を持てる。
  • データを追加するときは、一番下の段に左詰め。無理なら新たな段を作る。親と子を比較し、親>子であれば親と子を入れ替える。入れ替えが発生しなくなるまで繰り返す。
  • データを取り出したとき、一番上の数字(一番小さい数字)が取り出される。その後ヒープが再構築される。
  • 再構築の手順は、最後尾の数(一番下の段で一番右)を、一番上に移動する。親>子の場合、より小さい子と入れ替える。入れ替えが発生しなくなるまで繰り返す。
  • 取り出すのはO(1)。取り出した後の再構築、データの追加はO(log n)。

2分探索木

  • 木構造の一種で、ノードは2つまで子を持てる。
  • そのノードのデータは、そのノードの左部分木のどの数よりも大きい。
  • そのノードのデータは、そのノードの右部分木のどの数よりも小さい。
  • よって2分探索木の最小値は、最上部から見て左部分木の末端。最大値は、右部分木の末端。

TrustProxy

信頼するヘッダ、プロキシを設定しておかないと、httpならhttpsにリダイレクトするようにしたとき、無限ループする

ELBはIPアドレスが固定ではない。ELBだとX-***というヘッダになるので、それを信頼するようにする。
X-***というヘッダはWeb標準ではなく独自のもの。

$_SERVER['HTTP_*']はユーザーが送ってくるから基本信頼できない。

eval(\Psy\sh());が動かないときの対処方法

【laravel5】 tinkerを利用してpryのように楽にデバッグする! - Qiita
の、スクリプト中にeval(\Psy\sh());を埋め込んでデバッグする、をやろうと思ったのだが、以下のエラーでうまく動かなかった。

Writing to //.config/psysh is not allowed.

解決方法は、php artisan serveコマンドを打つときに、以下のようにhostを0.0.0.0とすること。

$ php artisan serve --host 0.0.0.0

上記のエラーはDockerコンテナ内でphp artisan serveコマンドを打つと発生するっぽい。

docker-composeで起動するコンテナの名前

{プロジェクト名}_{サービス名}_{連番}
  • プロジェクト名
    デフォルトではdocker-compose.ymlがあるディレクトリ名。環境変数COMPOSE_PROJECT_NAMEで変更可能。
  • サービス名
    docker-compose.ymlに書いたサービス名。
  • 連番
    スケールする際に連番で付与される。

PHPのmkdirとパーミッション

参考:
PHP: mkdir - Manual
【PHP】mkdirのパーミッション(属性)の指定が機能しない原因 – ysklog

PHPのmkdir関数で指定できるパーミッションはumaskの影響を受けるため、指定した通りにならないことがある。
よって以下の方法で調整する必要がある。

  • mkdir関数の作成前にumask関数でumaskを変更する
  • madir関数で作成後にchmod関数でパーミッションを変更する

ただしumaskを変更することは影響範囲が大きいため、chmod関数で後から変更することが推奨される。