propyonの日記

情報科学を学ぶ黄色いネズミ

あなたがものを渡すときに考慮しなければならない3つの渡し方

tags: 情報

どうも.コンピュータサイエンスを極める前にRuby on Railsを極めないとインターン先でやばい,ピカチュウです

今回はプログラミングにおける渡し方を整理したいと思います

題名は中身がない記事にありそうな雰囲気を意識しました.想像通り中身はないのでご安心ください

プログラミングにおける渡し方

プログラミングにおける変数の渡し方は以下の3つがあります

  • 値渡し
  • ポインタ(アドレス)渡し
  • 参照渡し

(渡し方なんてどうでもいいと思った人は,好きな人にプレゼントを着払いで渡せばいいと思います)

渡し方というのはコンピュータのメモリを理解すればすんなり理解できるので,サンプルコードと表をセットで説明したいと思います

その前に...メモリとは?

コンピュータには主記憶装置,通称メモリ(memory)というものがあります

このメモリにはそれぞれアドレスというのが割り振られています

そして,そのアドレス上で値を保持するのがプログラミングにおける変数の役割です

そのメモリをどう扱うかが渡し方によって異なるわけです

値渡し

サンプルコードはC言語です

int x = 1; # xのアドレスを確保し,そのアドレスの指す値に1を入れている
int y = x; # yのアドレスを確保し,そのアドレスの指す値にxのアドレスが指す値,1を入れている
変数名 アドレス
x m1 1
y m2 1

値渡しは上のように変数(y)のあるアドレスに指す値に,他の変数(x)の値を代入する際に渡すことです

ここではアドレスのやり取りはなく,値のやり取りのみが行われます

ポインタ(アドレス)渡し

C言語において,ポインタとして宣言されるとアドレス,値どちらの値も示すことができます

一方,単に整数として宣言された場合はそのアドレスの指す値を示します

ポインタの宣言,ポインタ以外アドレスを指す方法,アドレスの指す値を指す方法です

int* x; # 宣言
&x; # アドレス
*y; # 値

サンプルコードはC言語です

int x = 1; # xのアドレスを確保し,そのアドレスの値に1を入れている
int* y; # ポインタ型であるyのアドレスを確保している
y = &a; # yのアドレスにxのアドレスを入れている(xとyのアドレスを同じにした)
*y = 2 # yのアドレスの値に2を代入している
変数名 アドレス
x m1 1
y m2 m1

ここでは,ポインタとして宣言されたyの値に

参照渡し

サンプルコードはRubyです

x = 1
y = x
変数名 アドレス
x m1 1
y m1 1

参照渡しはアドレスをコピーして渡すやり方です

この渡し方でバグを生んだことしかないのです

次にその一例を載せておきます

Rubyでソート関数を書いたときの話

このなんたら渡しというのは別に変数に変数を代入するときだけでなく,関数に代入するときも関係します(仮引数に変数を代入していると考えるといいと思います)

Rubyの場合,配列,ハッシュを引数とする関数へは参照渡しが行われます

以下のようなバブルソートを用意します

引数にa(配列)とn(配列の要素数)を受け取ります

def bubble_sort(arr, n)
  flag = true
  while flag
    flag = false
    (1..n - 1).reverse_each do |i|
      next unless arr[i] < arr[i - 1]

      arr[i], arr[i - 1] = arr[i - 1], arr[i]
      flag = true
    end
  end
  arr
end

この関数でソートしてみると以下のような結果になります

arr = [*(1..10)].reverse!
# => [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
sorted_arr = bubble_sort(arr)
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
puts sorted_arr
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

そうです,引数の配列もひっくり返ってしまっています

このように意図しない副作用が起きてしまうので注意が必要です

ちなみに

sorted_arr = bubble_sort(arr.dup)

のように引数に複製した配列を与えると配列を意図しない形でソートせずに返すことが可能です

まとめ

プレゼントを渡す時は渡し方にも拘ろう

RemacsをUbuntuにインストール

tags: 情報

Remacsとは

Remacsのリンク

EmacsをRustで書き換えようというOSSです

Emacsの拡張性は非常に高く僕もよく使うエディタですが,それをRustで改良しようというコンセプトが面白いですね

Remacsのインストール

Rustをインストールしていない場合

UNIX系の場合は下のコマンドでrustupをインストールします1

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

インストールはインストーラーの指示にしたかってください

Rustのインストールが済んでいる場合

Cコンパイラや周辺環境をインストールします

$ sudo apt install build-essential automake clang libclang-dev
$ sudo  apt install texinfo libjpeg-dev libtiff-dev \
   libgif-dev libxpm-dev libgtk-3-dev libgnutls28-dev \
   libncurses5-dev libxml2-dev libxt-dev

これが終わったら本体のインストールです

$ git clone https://github.com/remacs/remacs.git

remacsディレクトリに移りビルドします

$ ./autogen.sh
$ ./configure --enable-rust-debug
$ make

ところが

$ ./autogen.sh

を実行しようとすると以下のエラーが発生する

Checking Rust toolchain install ...
Remacs requires the rustup command to be installed in order to build. Please see https://www.rustup.rs/; Aborting.

rustuprustもインストールしたはずなのになんで...?

どうやらrustupをダウロードするときに

$ source $HOME/.cargo/env

というコマンドを打たないといけなかったらしいです

Remacsの実行

RUST_BACKTRACE=1 src/remacs

上のように実行します

RUST_BACKTRACE=1はとりあえず付けたほうがよいらしいです

-qというオプションをsrc/remacsのあとに付けることも可能です.emacs.dを無視してくれるオプションらしいです

使った感想

-qオプションを付けないで起動すると下のようなエラーメッセージが

Warning (package): Unnecessary call to ‘package-initialize’ in init file

Remacsではパッケージをinitializeしなくてもいいのかな?

とりあえずコーディングや拡張に関してEmacsと変わらないように感じました

使ってみて困った点があったらIssueに上げてみようと思います

"Customized Machine Learning-Based Hardware-Assisted Malware Detection in Embedded Devices"を読んだ

tags: 論文

Title: Customized Machine Learning-Based Hardware-Assisted Malware Detection in Embedded Devices

推測できること

組み込みデバイスにおいて,機械学習を利用しハードウェアで補助されたそれぞれのデバイスごとのマルウェア検知に関する論文?

Abstract

アブストアブスト

  • 組み込みデバイスはソフトウェアでマルウェアを検知しようとすると計算資源が少ないので困難
  • そこでハードウェアを使った方法がある
  • その検知の正確性を高める他に機械学習を応用してHPC(Hardware Performance Counter)の特徴からマルウェアを特定する

推測できること

  • 機械学習の手法とこれから述べられるのかな

結論

  • HPCの4つの特徴を用いるだけでよく,省エネである
  • 伝統的なHMDに比べて精度が最大29%も上がっている
  • 複雑な分類アルゴリズムの方が精度は高いが,簡単な分類アルゴリズムの方が占有ユニットあたりの精度は高い

結局どんな論文だったのか

何についての論文か

先行研究と比べた強み

  • ハードウェアを用いることで
    • ハードウェアを操作するほうが難しく堅牢さに繋がる
    • ハードウェアのコストに比べてマルウェアを検知する遅延が小さい
  • 今までは

技術や手法のキモはどこか

  • ハードウェア関連
    • HPCのたった4つの特徴のみを使う
  • 3つの手法
    • Experimental Setup and Data Collection
      • 普通にデータを集める
    • Feature Reduction
      • 重要なHPCを探して4つに絞った
    • Malware Detection Approach
      • まずは走っているアプリケーションの種類を特定する
      • その後にマルウェアを検知するためのcustomizedされた分類器が登場する
    • Application Class Prediction
      • SVMを使う(教師有り学習)と精度が低いので他のものを使った

どうやって有効と示したのか

  • Malware Detection Accuracy
  • Hardware Overhead Analysis
    • 遅延と専有するハードウェアのエリア占有度で測定
  • Efficiency of ML Classifiers in Proposed HMD

議論はあるのか

特に無し

わからなかった点

次に読むべき論文は

特に無し

読むのにかけた時間

2時間

論文を読む際のフォーマット

論文どう読みますか?

皆さんは論文を読む時どのように読みますか?

僕は

abstract->conslusion->その間

という風に読みます

このように読むことで最初にどこに力点をおいて読めばいいかということがわかります

加えて,conclusionまでがつまらない場合はその論文を読まなければ良いということがわかり無駄に論文を読まずに済みます

以下は自分が論文を読む時にメモに使うフォーマットです

色々の人の読み方を参考にしました

なぜこの記事を書いたのか

(書くことがないからです)

# 論文まとめフォーマット

###### tags: `論文`

## Title

### 推測できること

## Abstract

### アブストのアブスト

### 推測できること

## 結論

## 結局どんな論文だったのか

### 何についての論文か

### 先行研究と比べた強み

### 技術や手法のキモはどこか

### どうやって有効と示したのか

### 議論はあるのか

### わからなかった点

### 次に読むべき論文は

## 読むのにかけた時間