CourseraのThe Bits and Bytes of Computer NetworkingのWeek1を振り返る
前回CourseraのThe Bits and Bytes of Computer NetworkingのWeek4についての受講メモを書いたのでそれの続き。
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アドレス
- 個々のネットワークインターフェイスに紐付けされたグローバルで一意の識別子
- 2つの16進数の6つのグループであらわされる48ビットの数値
ユニキャスト、マルチキャスト、ブロードキャスト
- ユニキャスト
- 単一のアドレスを指定して、1対1で行われるデータ通信
- マルチキャスト
- 特定のアドレスを指定して、1対複数で行われるデータ通信
- ブロードキャスト
- 同じデータリンク内の全宛先を指定し、1対不特定多数で行われるデータ通信
イーサネットフレームの分析
生産性向上のための個人的おすすめツール3選
たまにはライフハック系の記事でも。生産性向上のために日々愛用しているアプリを紹介します。それに加えて、個人的にこういう使い方をしているよ、というのを。
全体的な話として、これらのアプリは日常的にPCとiPhoneともにどちらからも使用していて、PCはブラウザの初回起動時に立ち上がるように、iPhoneについてはホームボタン上部の最も手の届きやすい場所に配置することでアクセス頻度を高めるような工夫をしている。
1. Evernote
ライフログの原点。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
Todoの管理はすべてTodoistでおこなっている。UI・UXが非常に洗練されており、とくにタスクに対してコメントできる機能が便利で課金をしている。年間利用で3000円ほどなのでお財布にも優しい。WebとiOSアプリともに使用している。アプリ開発の背景にはGetting Things Doneの思想がある。
タスクは消化してから消すのではなく、消化を始める際に意思表明として消す(重要!!)
タスク消化にどの程度時間を要するかを5分-15分-30分-1時間でラベリングをする
とりあえず思いついたことについてはInboxに期限なしのタスクとして突っ込む
- 別途Inboxのタスクを定期的に見直す習慣を設ける(定期タスクとして作成する)
- 何度も見直していくうちに、メインタスクに昇格するタスクと棄却されるタスクに分類される
- Inboxは消化できないのが当たり前なので、どれだけ溜まっててもよい。消化できないのが当たり前。
- 別途Inboxのタスクを定期的に見直す習慣を設ける(定期タスクとして作成する)
- Todoistを確認する、というタスクを定期タスクとして設けている
不満点ではないけど、最近はTrelloのようにカンバン方式でTodoを管理するのも悪くないと思い始めてるので、これはTodoistでは難しいものがある。
3. Marinara
Todoistのタスク消化にはMarinaraというChrome拡張のポモドーロアプリを使っている。日々のタスク消化すべてにポモドーロテクニックを用いている訳ではなく、主に30分や1時間のラベリングがされている比較的重めのタスクを実行する場合に使用することが多い。
ポモドーロテクニックについては以前にも記事を書いた。
ポモドーロアプリは他にもいろんな種類があるが、今のところどれが自分に一番フィットするか色々と試行錯誤している暗中模索の段階。自分はブラウザベースで仕事をすすめていくことが多いため、Chrome拡張という点でこのMarinaraが1つの落とし所として馴染んだ。
以前は、Flat TomatoというiOSアプリを使用していた。
まとめ
Evernoteに日々の雑多な情報をまとめ、その情報をベースに具体化されたタスクをTodoistに追加していき、そのタスクの消化にはMarinara(ポモドーロ・テクニック)を使う!
CourseraのThe Bits and Bytes of Computer NetworkingのWeek4を振り返る
前回CourseraのThe Bits and Bytes of Computer Networkingについて紹介記事を書いたが、コースのWeek毎に学んだことをメモ書き程度に振り返る。訳合ってWeek4からの投稿になるが、最終的には全てのWeekについてまとめる予定。
Week4 Overview
Introduction to Network Services
- Introduction to Network Services
Name Resolution
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のねらい
Name Resolution
Why do we need DNS?
- なぜDNSが必要か?
- コンピューターは0と1の数字によって会話を行う(2進数)。人間は2進数の読み取りは容易ではない
- IPアドレス(v4)は32ビットの2進数表記だが、4オクテットの10進数表記であらわされるのも可読性のため
- それ以上に人間はアドレスを数字よりも言葉として覚える方が上手なため
The Many Steps of Name Resolution
Name Resolution in Practice
Resource Record Types
- レコードタイプの種類
Anatomy of a Domain Name
DNS Zones
Dynamic Host Configuration Protocol
Overview of DHCP
- DHCPとは
- 割り当ての3つの方法
- 動的割り当て
- 自動割り当て
- 固定割り当て
DHCP in Action
Network Address Translation
Basics of NAT
NAT and the Transport Layer
NAT, Non-Routable Address Space and the Limits of IPv4
- IPv4のアドレス枯渇について
VPNs and Proxies
Virtual Private Networks
Proxy Services
- プロキシサービスとは
- クライアントに代わって動作するサーバー
- サーバーはリクエストを受けて別のサービスにアクセスする
- クライアントに代わって動作するサーバー
- プロキシサービスの利点
- 匿名性、セキリュティ、コンテンツフィルタリング、パフォーマンスの向上など
- リバースプロキシとは
- プロキシの最も重要なポイント
- プロキシは、クライアントと別のサーバーの間で仲介者として機能する
おわりに
どこかで加筆する予定...
rustlingsでRustの基本的な読み書きに慣れる
Rustことはじめの一環として、GoでいうところのA tour of Goに相当するものがRustでもないのだろうかと考えていた。そこで、rustlingsというRustの基本的な読み書きに慣れるための良さそうなエクササイズ集がGitHubにあることを知り、早速トライしてみることにした。
使ってみる
リポジトリの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の場合だとコンパイルエラーとなる。おそらく、以下のようなエラーメッセージが表示されるはず。
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の受講を終えた。このコースはネットワークがテーマであり、前提知識は一切無くても受講することが可能である(但し言語はすべて英語、英語字幕アリ)。
コース内容
コースは全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
- The Network Layer
- Subnetting
- Routing
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
まずはOSI参照モデルを基本として、物理層から順にその仕組みについて辿っていき、その後はDNSやDHCP、NAT、VPNとプロキシについて学ぶ。ネットワークの接続方式についてもカバーされている。そして、コースの終盤にはIPv6やクラウドといった最新のネットワーク技術、dig
やnslookup
といったコマンドを使ったトラブルシューティングのHow toについても触れられている。
参考書籍
当初は補助教材として、この分野ではド定番とも言えるマスタリングTCP/IP 入門編を読もうと思ったが、無理に背伸びはせず平易に書かれていそうな書籍を幾つか選んだ。
- 作者:福永 勇二
- 発売日: 2016/03/29
- メディア: 単行本
また、コースで躓いた際に非常に役立ってくれたオンラインリソースも追加で載せておく。
感想
さすがにこのコースを一巡しただけで「ネットワークを完全に理解した!」とはならないが、もし今後ネットワークで分からない事があれば、まずはこのコースのどこかにその答え、あるいはそのための糸口があるのではないかと思えるほど充実したコース内容であった。また、ネットワークの知識については日々断片的に仕入れてはいたものの、どこかでそれを体系的に整理、あるいは束ねてくれるような機会を欲していたので、このThe Bits and Bytes of Computer Networkingはその最良の機会となってくれた!
1. Two SumのRustの解答を読み解く①
今年はRustをじっくりと学びたいと思っていたので、LeetCodeのHello worldとも言うべき問題Two SumをRustで書くとどうなるのだろうか、とふと思った。
当の問題の解法(最適なアルゴリズム)は既に知っているので、では言語の学習に、と全く0の状態からガイドを見ながら解いてみることにした。しかしながら、かなり厳格な言語であるようで、全くコンパイルが通らずエラー地獄となってしまった。
そこで、Discussion Forumで掲載されていた解答コードのリーディングを行うことにした。
1. Two Sum
数値を含んだ配列とtargetという数値が与えられるので、配列内の2つの数値を足し合わせた値がtargetに等しくなる場合を探る。同じ数値を二度使うことは不可で、こうしたtargetに等しい組み合わせが最低でも1つあることが保証されている。そして、それぞれの足し合わせた数値のインデックスを配列にして返すことが期待される。
Brute Force
いわゆる二重ループを用いて解く方法。おそらくLeetCodeでこの問題を初めて解く場合、大半の人がこのアプローチを取ると思う。ひとときのAC(Accepted)に安堵してしまい、後々この問題の本質の価値に気付く、というのは多くのLeetCoderが経験するお約束のパターン。
時間計算量は言わずもがな。空間計算量は。
このトピックで掲載されていたコードをそのまま引用する。
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 }
型のキャスト
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 }
次回はもう一つのアプローチ、ハッシュマップを用いたアルゴリズムの場合のコードについて、リーディングを行いたい。
余談
このコードの実行速度は36 ms
でメモリ使用量は2.2MB
だった。
ハッシュマップを用いたのアルゴリズムアプローチを用いてPythonで提出した結果が履歴に残っており、実行速度は48 ms
でメモリ使用量は14.1 MB
であった。Rustがいかに高速な言語であるということを思い知らされる!(インタプリタ言語とコンパイル言語を比較するのはやや不適切な気もするけど...)
参考
49. Group Anagramsを解いた
49. Group Anagrams
文字列を含んだ配列が与えられるので、アナグラムが同一の文字列でグルーピングする。
My Answer
時間計算量は、空間計算量はとなった。
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の数字に対応付けて、それらの出現回数をカウントしたものをキーとする。
サンプルコードは以下のとおり。
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()
自分が提出したコードのソートのの処理部分をに置き換えることができるので、若干の改良が見込める。
また、サンプルコードからは以下のTipsが得られた。
- アルファベットを数字で対応付けたいとき
ord("a")
から差分を用いる。 defaultdict(type)
を使って辞書を生成することで、キーの存在の有無の判定を省略することができる。values()
はdict_values
のクラスを返す。例えば今回はlist(hoge.values())
などでreturnすることも可能。