CourseraのThe Bits and Bytes of Computer NetworkingのWeek1を振り返る

前回CourseraのThe Bits and Bytes of Computer NetworkingのWeek4についての受講メモを書いたのでそれの続き。

全体 p0ny.hatenablog.com

前回 p0ny.hatenablog.com

Week1 概要

  • Introduction to Computer Networking

  • The TCP/IP Five-Layer Network Model

  • The Basics of Networking Devices

  • The Physical Layer

  • The Data Link Layer


コンピューターネットワーキング入門

イントロダクション

TCP/IP 5層ネットワークモデル

TCP/IP 5層ネットワークモデル

ネットワーク機器の基礎

ケーブル

  • 今日使用される殆どのネットワークケーブルは銅線とファイバーに分類される
    • 銅線
      • ネットワークケーブルの最も一般的な形式
      • プラスチック絶縁体内の銅線の複数のペアで構成される
      • 電圧を変換することでデータの0と1を表現する
    • ファイバー
      • 電圧を使用する銅線とは異なり、ファイバーケーブルは光のパルスを利用してデータの0と1を表現する
      • データ転送速度は銅線よりも速いが、高価で脆い

ハブ、スイッチ

ルーター

サーバーとクライアント

  • サーバー
    • データを要求するものにデータを提供するもの
  • クライアント
    • データを要求して受信するもの

物理層

ワイヤーを介してのビットの移動

  • ビット

    • コンピューターが理解できるデータの最小の表現、1または0によって表される
  • 変調

    • ケーブルを移動する電荷の電圧を変化させる方法

ツイストペアケーブル

  • 電線を2本対で撚り合わせたケーブル
  • 近年ではイーサネットの特にLANでの配線に使われる
  • 平行線よりノイズの影響を受けにくいのが最大の特徴

ネットワークポートとパッチパネル

  • ネットワークポート
    • 通常、コンピュータネットワークを構成するデバイスに直接接続されている
    • ネットワークポートにある2つのLED
      • リンクライト
      • アクティビティライト
  • パッチパネル
    • 多くのネットワークパネルを持つ機器

データリンク層

イーサネットMACアドレス

ユニキャスト、マルチキャスト、ブロードキャスト

  • ユニキャスト
    • 単一のアドレスを指定して、1対1で行われるデータ通信
  • マルチキャスト
    • 特定のアドレスを指定して、1対複数で行われるデータ通信
  • ブロードキャスト
    • 同じデータリンク内の全宛先を指定し、1対不特定多数で行われるデータ通信

イーサネットフレームの分析

  • データパケット
    • ネットワークリンクを介して送信されるバイナリデータの単一のセットのこと
  • イーサネットフレーム
    • イーサネットレベルのデータパケット、高度に構造化された情報の集まり
    • プリアンブル
    • イーサタイプフィールド
      • フレームの内容のプロトコルを記述するために使用される、16ビット
    • VLAN
      • 同じ物理装置において複数の論理LANを可能にする手法
    • ペイロード
      • 転送される実際のデータ、ヘッダー以外のすべての部分。
    • フレームチェックシーケンス

生産性向上のための個人的おすすめツール3選

たまにはライフハック系の記事でも。生産性向上のために日々愛用しているアプリを紹介します。それに加えて、個人的にこういう使い方をしているよ、というのを。

全体的な話として、これらのアプリは日常的にPCとiPhoneともにどちらからも使用していて、PCはブラウザの初回起動時に立ち上がるように、iPhoneについてはホームボタン上部の最も手の届きやすい場所に配置することでアクセス頻度を高めるような工夫をしている。

1. Evernote

evernote.com

ライフログの原点。2012年から使用しているので、かれこれ8年間にわたり使用していることになる。とりあえず何か雑多なことについてメモしたいなら積極的にEvernoteに書くようにしている。以前はTodo管理も含めすべてEvernote上で行っていたが、Todo管理の役割は徐々に後述するTodoistにオフロードしている。Evernoteの少し残念なところは、デスクトップアプリでは完全なmarkdownでの記述ができないところ(先日、Web版だと使用できることを知った)。

  • Evernoteは何を書いてもいい場所とする
    • 思考がまとまらない時は、Evernoteに書き下すことで整理されることが多い
    • 手記のようなもの
  • デイリーログとしての活用
    • Todo管理とは別に今日すること、したことをNarrativeに書き出していくことで、日々の生活にストーリー性が生まれる
    • 人生で何かスタックが起きた場合は1, 3, 5年という間隔で過去のログを見直すと意思決定に役立ってくれることが多い

余談だけど、先日ライフログEvernoteからNotionに移行しようとしたがうまくいかなかった。NotionとEvernoteではアプリの設計思想が大きく異なるので、移行というよりかはそれぞれを使い分けるのがよいかなという結論にいたった。あまり使い込んでいないので正しいかはわからないけど、Notionは蓄積したログを体系化して再整理するのに向いているのかなと思った、まるで個人Wikiを作るかのように。

2. Todoist

todoist.com

Todoの管理はすべてTodoistでおこなっている。UI・UXが非常に洗練されており、とくにタスクに対してコメントできる機能が便利で課金をしている。年間利用で3000円ほどなのでお財布にも優しい。WebとiOSアプリともに使用している。アプリ開発の背景にはGetting Things Doneの思想がある。

  • タスクは消化してから消すのではなく、消化を始める際に意思表明として消す(重要!!)

  • タスク消化にどの程度時間を要するかを5分-15分-30分-1時間でラベリングをする

  • とりあえず思いついたことについてはInboxに期限なしのタスクとして突っ込む

    • 別途Inboxのタスクを定期的に見直す習慣を設ける(定期タスクとして作成する)
      • 何度も見直していくうちに、メインタスクに昇格するタスクと棄却されるタスクに分類される
    • Inboxは消化できないのが当たり前なので、どれだけ溜まっててもよい。消化できないのが当たり前。
  • Todoistを確認する、というタスクを定期タスクとして設けている

不満点ではないけど、最近はTrelloのようにカンバン方式でTodoを管理するのも悪くないと思い始めてるので、これはTodoistでは難しいものがある。

3. Marinara

github.com

Todoistのタスク消化にはMarinaraというChrome拡張のポモドーロアプリを使っている。日々のタスク消化すべてにポモドーロテクニックを用いている訳ではなく、主に30分や1時間のラベリングがされている比較的重めのタスクを実行する場合に使用することが多い。

ポモドーロテクニックについては以前にも記事を書いた。

p0ny.hatenablog.com

ポモドーロアプリは他にもいろんな種類があるが、今のところどれが自分に一番フィットするか色々と試行錯誤している暗中模索の段階。自分はブラウザベースで仕事をすすめていくことが多いため、Chrome拡張という点でこのMarinaraが1つの落とし所として馴染んだ。

以前は、Flat TomatoというiOSアプリを使用していた。

www.flatpomodoro.com

まとめ

Evernoteに日々の雑多な情報をまとめ、その情報をベースに具体化されたタスクをTodoistに追加していき、そのタスクの消化にはMarinara(ポモドーロ・テクニック)を使う!

CourseraのThe Bits and Bytes of Computer NetworkingのWeek4を振り返る

前回CourseraのThe Bits and Bytes of Computer Networkingについて紹介記事を書いたが、コースのWeek毎に学んだことをメモ書き程度に振り返る。訳合ってWeek4からの投稿になるが、最終的には全てのWeekについてまとめる予定。

p0ny.hatenablog.com

Week4 Overview

Introduction to Network Services

  • Introduction to Network Services

Name Resolution

  • Why do we need DNS?

  • The Many Steps of Name Resolution

  • DNS and UDP

  • Sergio IT Great Field

Name Resolution in Practice

  • Resource Record Types

  • Anatomy of a Domain Name

  • DNS Zones

Dynamic Host Configuration Protocol

Network Address Translation

  • Basics of NAT
  • NAT and the Transport Layer
  • NAT, Non-Routable Address Space and the Limits of IPv4
  • Supplemental Reading forIPv4 Address Exhaustion

VPNs and Proxies

  • Virtual Private Networks
  • Proxy Services

Introduction to Network Services

Introduction to Network Services

  • Week4のねらい
    • DNSルックアップに関連する多くのステップを特定し、 最も一般的なDNSレコードタイプを理解する
    • DHCPによってネットワーク管理がより簡単になることを理解する
    • NATがネットワークをより安全に維持することを理解する
    • VPNとプロキシはセキュリティを確保するのに役立つことを理解する

Name Resolution

Why do we need DNS?

  • なぜDNSが必要か?
    • コンピューターは0と1の数字によって会話を行う(2進数)。人間は2進数の読み取りは容易ではない
    • IPアドレス(v4)は32ビットの2進数表記だが、4オクテットの10進数表記であらわされるのも可読性のため
      • それ以上に人間はアドレスを数字よりも言葉として覚える方が上手なため

The Many Steps of Name Resolution

DNS and UDP

Name Resolution in Practice

Resource Record Types

  • レコードタイプの種類
    • Aレコード
    • AAAAレコード
    • CNAMEレコード
    • MXレコード
      • 目的のサーバーに電子メールを配信するために使用される
    • SRVレコード
      • さまざまな特定のサービスの場所を定義するために使用される

Anatomy of a Domain Name

DNS Zones

  • DNSゾーンとは
    • DNSにおいて、委任によって作られる管理の単位

Dynamic Host Configuration Protocol

Overview of DHCP

  • DHCPとは
    • DHCPは単一のネットワーク上の多数のネットワークデバイスについて、どのIPをどのマシンに割り当てるという役割を担う
    • ネットワーク上のホストの構成プロセスを自動化する
  • 割り当ての3つの方法
    • 動的割り当て
    • 自動割り当て
    • 固定割り当て

DHCP in Action

Network Address Translation

Basics of NAT

  • NATとは
    • 1つのIPアドレスを受け取り別のアドレスに変換する
  • NATの主な目的
    • セキリュティ保護の観点から
    • 利用可能なIPv4スペースの限られた量を維持するため

NAT and the Transport Layer

NAT, Non-Routable Address Space and the Limits of IPv4

  • IPv4のアドレス枯渇について
    • NATではルーティング不可なアドレス空間を使用して、数百、さらには数千のマシンが単一のパブリックIPを所持することが可能
    • IPv6によってIPv4のアドレス枯渇問題は解決されるが、世界規模で実装するにはまだ時間がかかるため、NATがそれまでの1つの対策となりうる

VPNs and Proxies

Virtual Private Networks

  • VPNの利用目的
    • 企業はできるだけネットワークを安全に保ちたい
    • ローカルエリアネットワーク(LAN)に物理的に存在しているデバイスであれば、ネットワークを安全に保つことは容易いが、現実的な事情としてすべての従業員が常にオフィスにいるとは限らない
      • 従ってVPNの最も一般的な使用例は、従業員がオフィスにいないときに社内ネットワークにアクセスする場合
  • VPNの仕様
    • VPNはトンネリングプロトコル
      • VPN接続を確立する時、VPNトンネルが確立されたと表現する
    • VPNは2段階認証が一般的になった最初のテクノロジーである
      • ユーザー名とパスワードに加え、一時的なセキリュティトークンを用いて認証を行う
    • VPNはあくまで一般的な技術概念であり、厳密に定義されたプロトコルではない
      • そのため、VPNには多くのユニークな実装が存在する
  • VPNの最も重要なポイント
    • 実際には物理的に接続されていないネットワークに対して、さも物理的に接続されているかのように振る舞う

Proxy Services

  • プロキシサービスとは
    • クライアントに代わって動作するサーバー
      • サーバーはリクエストを受けて別のサービスにアクセスする
  • プロキシサービスの利点
    • 匿名性、セキリュティ、コンテンツフィルタリング、パフォーマンスの向上など
  • リバースプロキシとは
    • クライアントサイドからは単一のサーバー/フロントエンドのように見えるサービス
      • その背後では、リクエストを多数の物理サーバーに分散している
      • DNSラウンドロビンの概念と同じく、ロードバランシングの一種
  • プロキシの最も重要なポイント
    • プロキシは、クライアントと別のサーバーの間で仲介者として機能する

おわりに

どこかで加筆する予定...

rustlingsでRustの基本的な読み書きに慣れる

Rustことはじめの一環として、GoでいうところのA tour of Goに相当するものがRustでもないのだろうかと考えていた。そこで、rustlingsというRustの基本的な読み書きに慣れるための良さそうなエクササイズ集がGitHubにあることを知り、早速トライしてみることにした。

github.com

使ってみる

リポジトリのREADMEでガイドされているOS毎のインストール手順を行ったら、コマンドラインからrustlingsのディレクトリに移動する。rustlingsのディレクトリ内には、コンパイルエラーを誘発する不正なrsファイルが沢山含まれており、それら一つ一つが問題である。

rustlings watchで起動することで、ターミナル上に(特定の問題の)エラーメッセージが表示されるので、該当する問題のrsファイルをVS Codeのようなエディタで開きデバッグを行っていくのが一連の流れ。

回答の手順

例えば以下の問題についてのエラーメッセージが表示されていたとする。

// variables3.rs
// Make me compile! Execute the command `rustlings hint variables3` if you want a hint :)

// I AM NOT DONE

fn main() {
    let x = 3;
    println!("Number {}", x);
    x = 5;
    println!("Number {}", x);
}

これはJavaScriptのような言語に慣れ親しんだ人からすると、一見正常なコードに見えるかもしれないが、Rustの場合だとコンパイルエラーとなる。おそらく、以下のようなエラーメッセージが表示されるはず。

f:id:p0ny:20200322225844p:plain

Rustは変数の宣言を行う際にmutというキーワードでミュービリティを宣言しない限りは、その変数の束縛を変更することが許可されない(デフォルトでは変数の宣言時にはすべてイミュータブル)。したがって、最初のxの変数宣言時にmutを含める必要がある。

let mut x = 3;

エラー箇所を修正すると、rustlingsがコードの変更を自動で検出して正誤判定をしてくれる。正答した後は、// I AM NOT DONEコメントアウト箇所を削除することで、次の問題をrustlingsがガイドしてくれる。

もし、問題がわからない場合は以下のコマンドを実行することでヒントが表示される救済措置もある。

rustlings hint exercise_name

ちなみにローカルで環境を構築するのが面倒な人向けに、Rust Playgroundを使ったWEB版もある。

雑感

現在、rustlingsの全項目のうち大体7割ほどの問題を解きおえた。rustlingsは言語機能毎に問題のセクションが分かれており、なおかつ難易度順に問題のガイドを行ってくれるので、Rustビギナーのステップアップのための教材としてはこの上なく最適だ。

Rustについてはまだ触り始めて間もないということもあり、コンパイルを通すので精一杯というのが正直なところ。個人的にRustはコンパイルエラー時のメッセージがかなり丁寧且つ的確なので、毎回のコンパイルエラー時に学びがある所がとても気に入っている。

rustaceanを目指してどんどん問題を解いていこう!🦀

CourseraのThe Bits and Bytes of Computer Networkingの受講を終えた

CourseraでGoogleが提供しているITサポート専門家の養成を支援するためのトレーニングコース、The Bits and Bytes of Computer Networkingの受講を終えた。このコースはネットワークがテーマであり、前提知識は一切無くても受講することが可能である(但し言語はすべて英語、英語字幕アリ)。

www.coursera.org

コース内容

コースは全6週で構成される(なので大体2ヶ月が修了の目安である)。1つの動画は大体5分から10分ほどで視聴できるようになっている親切設計。そして各週の最後に理解度チェックのための確認テストがある。今回は課金をせず無料受講を選択したため、一部のリソースにはアクセス出来なかったが特に支障はなかった。

各週で取り扱うテーマは以下のとおり。

Week1 - Introduction to Networking

  • The TCP/IP Five-Layer Network Model
  • The Basics of Networking Devices
  • The Physical Layer
  • The Data Link Layer

Week2 - Network Layer

Week3 - Transport and Application Layers

  • The Transport Layer
  • The Application Layer

Week4 - Networking Services

  • Name Resolution
  • Dynamic Host Configuration Protocol
  • Network Address Translation
  • VPNs and Proxies

Week5 - Connecting to the Internet

  • POTS and Dial-up
  • Broadband Connections
  • WANs
  • Wireless Networking

Week6 - Troubleshooting and the Future of Networking

  • Verifying Connectivity
  • Digging into DNS
  • The Cloud
  • IPv6

まずはOSI参照モデルを基本として、物理層から順にその仕組みについて辿っていき、その後はDNSDHCP、NAT、VPNとプロキシについて学ぶ。ネットワークの接続方式についてもカバーされている。そして、コースの終盤にはIPv6クラウドといった最新のネットワーク技術、dignslookupといったコマンドを使ったトラブルシューティングのHow toについても触れられている。

参考書籍

当初は補助教材として、この分野ではド定番とも言えるマスタリングTCP/IP 入門編を読もうと思ったが、無理に背伸びはせず平易に書かれていそうな書籍を幾つか選んだ。

絵で見てわかるITインフラの仕組み 新装版

絵で見てわかるITインフラの仕組み 新装版

また、コースで躓いた際に非常に役立ってくれたオンラインリソースも追加で載せておく。

www5e.biglobe.ne.jp

感想

さすがにこのコースを一巡しただけで「ネットワークを完全に理解した!」とはならないが、もし今後ネットワークで分からない事があれば、まずはこのコースのどこかにその答え、あるいはそのための糸口があるのではないかと思えるほど充実したコース内容であった。また、ネットワークの知識については日々断片的に仕入れてはいたものの、どこかでそれを体系的に整理、あるいは束ねてくれるような機会を欲していたので、このThe Bits and Bytes of Computer Networkingはその最良の機会となってくれた!

1. Two SumのRustの解答を読み解く①

今年はRustをじっくりと学びたいと思っていたので、LeetCodeのHello worldとも言うべき問題Two SumをRustで書くとどうなるのだろうか、とふと思った。

当の問題の解法(最適なアルゴリズム)は既に知っているので、では言語の学習に、と全く0の状態からガイドを見ながら解いてみることにした。しかしながら、かなり厳格な言語であるようで、全くコンパイルが通らずエラー地獄となってしまった。

そこで、Discussion Forumで掲載されていた解答コードのリーディングを行うことにした。

1. Two Sum

leetcode.com

数値を含んだ配列とtargetという数値が与えられるので、配列内の2つの数値を足し合わせた値がtargetに等しくなる場合を探る。同じ数値を二度使うことは不可で、こうしたtargetに等しい組み合わせが最低でも1つあることが保証されている。そして、それぞれの足し合わせた数値のインデックスを配列にして返すことが期待される。

Brute Force

いわゆる二重ループを用いて解く方法。おそらくLeetCodeでこの問題を初めて解く場合、大半の人がこのアプローチを取ると思う。ひとときのAC(Accepted)に安堵してしまい、後々この問題の本質の価値に気付く、というのは多くのLeetCoderが経験するお約束のパターン。

時間計算量は言わずもがなO(N^{2})。空間計算量は O(1)

このトピックで掲載されていたコードをそのまま引用する。

impl Solution {
    pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
        for ind in (0..nums.len() - 1)
        {
            for comp_ind in (ind+1..nums.len())
            {
                if nums[ind] + nums[comp_ind] == target
                {
                    return vec![ind as i32, comp_ind as i32];
                }
            }
        }
        return vec![0;2];        
    }
}

今回は、ループ、ベクタ、キャストの3つについて取り上げたい。

ループ

Rustのループはloop while forの3つがあるようだが、そのうちの1つforループの処理については、以下のように記述することができる。

for x in 0..10 {
    println!("{}", x);
}

0..nと書けるのが特徴で、Pythonでいうところのrange(0, n)だ。forループといえば、以下のような記述が標準だけど、どうやらRustでは非推奨らしい。Pythonに慣れ親しんだ自分としては少し助かる。

for (x = 0; x < 10; x++) {
    printf( "%d\n", x );
}

理由は以下のとおり。

Rustでは意図的に「Cスタイル」 for ループを持ちません。経験豊富なC開発者でさえ、 ループの各要素を手動制御することは複雑であり、また間違いを犯しやすいのです。

せっかくなので、if文を少し調べつつFizzBuzzを書いてみた。

fn main() {
    for i in 1..101 {
        if i % 3 == 0 && i % 5 == 0 {
            println!("{} : {}",i, "FizzBuzz!")
        } else if i % 3 == 0 {
            println!("{} : {}",i, "Fizz!");
        } else if i % 5 == 0 {
            println!("{} : {}", i, "Buzz!")
        }
    }
}

https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/loops.html

ベクタ

ベクタとは、動的あるいは拡張可能な配列である(PythonのリストやGoのスライスに相当)。vec!というマクロによってベクタの生成が可能。今回は入力で与えられたベクタ、numsのサイズを取得したいので、len()を呼び出している。

以下、サンプルコード。

fn main() {
  let v = vec![1, 2, 3, 4, 5];
  println!("{}", v.len()) // 5
}

std::vec::Vec - Rust

型のキャスト

asによって型を安全にキャストすることが可能。今回は出力の形式がVec<i32>で関数内で指定されているので、ベクタ内の要素の型はi32にする必要がある。i32は32ビットの符号付整数型。

以下、サンプルコード(型を呼び出すメソッドについては省略)。

use std::any::type_name;

fn type_of<T>(_: T) -> &'static str {
    type_name::<T>()
}

fn main() {
  let x: i32 = 5;
  println!("{}", type_of(x)); // i32

  let y = x as i64;
  println!("{}", type_of(y)); // i64
}

as - Rust

次回はもう一つのアプローチ、ハッシュマップを用いたアルゴリズムの場合のコードについて、リーディングを行いたい。

余談

このコードの実行速度は36 msでメモリ使用量は2.2MBだった。

ハッシュマップを用いたO(N)アルゴリズムアプローチを用いてPythonで提出した結果が履歴に残っており、実行速度は48 msでメモリ使用量は14.1 MBであった。Rustがいかに高速な言語であるということを思い知らされる!(インタプリタ言語とコンパイル言語を比較するのはやや不適切な気もするけど...)

参考

doc.rust-jp.rs

49. Group Anagramsを解いた

49. Group Anagrams

leetcode.com

文字列を含んだ配列が与えられるので、アナグラムが同一の文字列でグルーピングする。

My Answer

時間計算量はO(n * mlogm)、空間計算量はO(n * m)となった。

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        dic = {}
        for s in strs:
            sorted_s = "".join(sorted(s))
            if sorted_s not in dic:
                dic[sorted_s] = [s]
            else:
                dic[sorted_s].append(s)
        return [dic[s] for s in dic]

与えられた文字列を(アルファベット順に)ソートし、ソートした文字列をKeyとして辞書に格納していく。後は、辞書からそのまま取り出した値を指定の配列の形で返してやればよい。

実行速度は100 msとなり、全体の72.20 %の参加者より速い結果となった。

Best Answer

Categorize by Count

解説のページを見ると、さらによいと思われるアプローチが存在した。アルファベットを0から25の数字に対応付けて、それらの出現回数をカウントしたものをキーとする。

https://leetcode.com/problems/group-anagrams/Figures/49_groupanagrams2.png

サンプルコードは以下のとおり。

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        ans = collections.defaultdict(list) 
        for s in strs: # n
            count = [0] * 26 # m
            for c in s:
                count[ord(c) - ord('a')] += 1
            ans[tuple(count)].append(s)
        return ans.values()

自分が提出したコードのソートのO(mlogm)の処理部分をO(m)に置き換えることができるので、若干の改良が見込める。

また、サンプルコードからは以下のTipsが得られた。

  • アルファベットを数字で対応付けたいときord("a")から差分を用いる。
  • defaultdict(type)を使って辞書を生成することで、キーの存在の有無の判定を省略することができる。
  • values()dict_valuesのクラスを返す。例えば今回はlist(hoge.values())などでreturnすることも可能。

参考

qiita.com

note.nkmk.me