ランダムにクローリングして適当にテキストを抽出してtwitterに投稿するだけのBotの要件

概要

  • 初期設定したURLからランダムにリンクを1つ選んでアクセスする
  • アクセスしたページ内のテキストノードからテキストをランダムに選ぶ
  • テキストとURLをくっつけてtwitterに投稿する
  • アクセス先のページからまたランダムにリンクを1つ選んでまたテキストを選んでtwitterに投稿する
  • ひたすら繰り返す
  • 別途Webアプリを作って履歴を見られるようにする

各機能の概要

URLにアクセスしページ内から次にアクセスするURLを取得する

  • 基本的にはページ内のリンク全てからランダムに1つ選択するだけ。aタグのhref以外は辿らない。
  • ただし、なるべくいろんなページにいって欲しいので、過去にアクセスしたURLとドメインが等しいページには遷移しない
  • 次に遷移できるURLが見つからなくなった場合は、そのことをtwitterに投稿する(「死亡した」と呼ぶ)。その際、別のURLを選択して再度クローリングを開始する//TODO 選択基準は? //TODO html以外のページに飛んでしまうと確実に死亡するのでは?

ページ内からランダムにテキストを選ぶ

  • //TODO どうやって選ぶ?なるべくセリフっぽいものを抽出したい
  • テキストがないページに行ったらどうする?
  • とりあえずDOMからテキストを保持していてかつ子を持っていないノードをランダムに1つ抽出するだけでいいかな・・・

URLとテキストをくっつけてtwitterに投稿する

  • フォーマットだけ決める。基本的にはひたすら投稿するだけ

履歴閲覧

  • アクセスしたページ、抽出したテキスト及び、死亡の履歴が閲覧できる
  • 日時での抽出、ページングくらいはできるようにしたい
  • テキストでの検索はいらない。出てきた単語数のランキングとか見れると楽しいかも

Effective Javaを読んでいる㉔

非チェック警告を潰せ

ふつうに潰せるやつはつぶそうね

はい

潰せないやつは@SuppressWarnings("unchecked")でつぶせ

でかいスコープに@SuppressWarningsつけるな
出来る限り小さいスコープにつけろ!!!!!!

宣言にしかつけられないからスコープを縮めるためにソースを変えろ!!!
return節でのメソッド呼び出しとかにつけたくなったら一旦変数に格納してそっちにつけろ!!methodの宣言につけるな!!!
コメントをかけ!!!!!!!なんで@SuppressWarningsを許容したのかを!!!

Effective Javaを読んでいる㉓

総称型のクラスを型パラメータなしで使うな

List list = new BookList;  
list.add(new Magazine());
Book book = (Book)list.get(0);

コンパイル通っちゃうけど実行時にキャストできなくてエラーになる。

ListとList¥<Object¥>の違い(なんか型パラメータの部分がマークダウンに引っかかって表示が狂うので¥つけてる エスケープされない理由は謎)

List

総称型のチェックをしない

List¥<Object¥>

総称型のチェックをする

   public static void main(String[] args) throws IOException{
        List rawList = new ArrayList();
        List<Object> objectList = new ArrayList<>();
        
        List<String> stringList = new ArrayList<>();
        
        rawList = stringList;//コンパイルが通る
        objectList = stringList;//コンパイルが通らない(List<String>はList<Object>のサブタイプではない)
    }

総称型のルールにおいて、ListはListのサブタイプとなる。

何がはいってくるかわかんない場合はunbounded wildcard type(非境界ワイルドカード型)

例外

       Class clazz = List.class;//これはできるが
        Class clazz2 = List<String>.class;//これはできない

<<<instanceofが使えない>>>
rawでinstanceofして非境界ワイルドカード型にすぐキャストするのがよい

<<<<<実行時にジェネリクスの情報は消えるからこんなんなる>>>>>

非境界ワイルドカード型についてはこれをみました
Java総称型のワイルドカードを上手に使いこなすための勘所 - 達人プログラマーを目指して

Effective Javaを読んでいる㉒

staticメンバよりstaticでないメンバを選べ

enclosing class→内部クラスに対して外側のクラス

4つのネストされたクラス

static member classes

  • enclosing classのstaticなメンバである
  • enclosing classのすべてのメンバにアクセスできる。

nonstatic member classes

  • enclosing classのインスタンスに紐付いている。
  • enclosing classのインスタンス内にしか存在できない
  • 関係ないクラスから、あるクラスを別のインターフェースとして見せるのに使いがち(HashMapのEntrySetの実装とか.entrySet()の中で匿名クラスじゃダメなのか?実装量が多いからそうしてるだけ?)
  • 内部クラスがenclosing classに対して完全に依存してる時だけこれを使うべき?
  • 内部クラスがenclosing instanceに対して依存していなくても、内部クラス→enclosing instanceの参照を持つので内部クラスへの参照が生きているとenclosing instanceへのGCが行われない(HashMapのEntryがnonstatic member classesだとEntryだけの参照が残っているのにMapがGCされない)

anonymouse classes

  • 名前が無い
  • 宣言されるコンテキストにあわせてどこから見えるのか変わる
  • 宣言された場所でしかインスタンス化できない
  • instanceofが使えない(名前がないから)
  • 複数のインターフェースを実装できない
  • クラスを継承しつつインターフェースを実装できない
  • 新たに定義したメソッドを呼べない(名前がないから)

local classes

  • メソッドの中で宣言されるやつ
  • ローカル変数が宣言できる場所なら宣言できる。スコープも同じ

Effective Javaを読んでいる㉑

戦略を表すのに関数オブジェクトを使え

  1. 何についての戦略なのか?を表すインターフェースを作る
  2. 実装クラスを作る
  3. 利用者はインターフェースの形で宣言された変数に実装クラスを突っ込む
注意点

匿名クラスの形で実装する場合インスタンスが何回も作られる構造にしてしまうと無駄なインスタンスが作られまくる

匿名クラス生成用のstaticメソッドを作る→そのメソッドから定数に匿名クラスを突っ込む→そいつを使うようにすれば↑が解決できる

JJUG CCC 2016 Fallにいってきた

見たセッション

SpringはどうやってDIしているのか

SpringはどうやってDIしているのか · Issue #35 · jjug-ccc/call-for-paper-2016fall · GitHub
・スキャンの対象はclassファイルを直接解析して判定してる
インスタンスはClassLoaderから読み込んで生成してる

メンバーのスキルアップ、どうしてる? -Java 100本ノックで新加入メンバーを鍛えてみた-

GitHub - JustSystems/java-100practices: Java 100本ノック

だめなコードは「ん?」ってなるけど良いコードは引っかからないから褒めるときこそ意識が必要
あと配られてた100本ノックのサンプルがわかったのでほっとした
Java8でこのときに潰される1stをひろう仕組みがあったような気がするけどそれについては忘れた

どうしようJUnit 5

どうしようJUnit5 - SSSSLIDE

JUnitでいろいろしようとしたことないからとりあえずいろいろしてみようとおもった

Effective Javaを読んでいる⑳

タグ付けされたクラスよりもクラス階層を

このクラスはこういう意味だよ的なフィールドを作ってその値で動作を変えるくらいなら、共通部分だけ抽象クラスに切り出して意味ごとにサブクラスを作れよ、と

f:id:inabajunmr:20160103131036j:plain