Java Silver合格への道 ~コンスタントプール~
こんにちは。たろすです。
今回はコンスタントプールについて説明します。
a == b
Javaではa == bと書くとaとbが同一かを判定し、同一であればtrue、同一でなければfalseを返します。
つまり以下のようなプログラムを実行すると「false」と表示されます。
public class Main { public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ Food a = new Food("gohan"); Food b = new Food("cake"); System.out.println(a == b); } }
どこからどう見ても別のオブジェクトですからね。
それでは次のプログラムはどうでしょうか。
public class Main { public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ Food a = new Food("gohan"); Food b = new Food("gohan"); System.out.println(a == b); } }
実はこの場合も「false」と表示されます。
コンスタントプール
String型の場合はダブルクォーテーションで括られた文字列を記述するだけでインスタンス化できます。
つまり、わざわざnewしなくてもインスタンス化できるため以下のように書くことができます。
public class Main { public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ String a = "gohan"; String b = "gohan"; System.out.println(a == b); } }
しかし、このプログラムを実行すると「true」と表示されます。
なぜこのような挙動をするかというとコンスタントプールという仕組みがあるからです。
コンスタントプールは文字列リテラルを定数値としてインスタンスとは異なるメモリに保存し、どの変数から参照されても同じ文字列の場合は同じ場所を参照することでメモリの消費を減らす仕組みです。
つまりこのプログラムでは変数aも変数bもコンスタントプール内の同じ場所を参照しているため、aとbは同一であると判定されたわけです。
一方で、newした場合は新しいインスタンスが作られるため、以下のプログラムを実行すると「false」と表示されます。
public class Main { public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ String a = new String("gohan"); String b = new String("gohan"); System.out.println(a == b); } }
つまりこの書き方はメモリを無駄に消費しているので、実際にはやらないほうが良いです。
おわりに
今回はコンスタントプールについて説明しました。
String型の比較はequals()を使うのが普通なので意外とこの仕組みは知らないかもしれませんね。
【Java】パスワードのハッシュ化とログイン認証
こんにちは。たろすです。
今回は安全なアプリを開発するために重要なパスワードのハッシュ化について説明します。
ハッシュ化のアルゴリズムとしては「bcrypt」を使用します。
解説
認証関連はAutuUtilクラスに実装されています。
まずはSpring Securityを使うために以下をインポートします。
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
パスワードのハッシュ化
/** * ユーザーを登録する * @param user * @return */ public boolean registerUser(UserSample user) { BCryptPasswordEncoder bcpe = new BCryptPasswordEncoder(); // ハッシュ化 String encodeedPassword = bcpe.encode(user.getPassword()); user.setPassword(encodeedPassword); int result = userLogic.insertUser(user); if (result > 0) { return true; } return false; }
ハッシュ化するときにはBCryptPasswordEncoder.encode()メソッドを呼びます。
引数は生のパスワード(ハッシュ化する前のパスワード)です。
ログイン認証
/** * ログイン処理を行う * @param user * @return */ public boolean login(UserSample user) { // IDをキーにユーザー情報を取得 UserSample compUser = userLogic.getUserById(user.getId()); BCryptPasswordEncoder bcpe = new BCryptPasswordEncoder(); // 入力されたパスワードとDBのパスワード(ハッシュ化済み)を比較 if (bcpe.matches(user.getPassword(), compUser.getPassword())) { loginUser.setUser(compUser); return true; } return false; }
ユーザーから入力されたパスワードとDBに登録されているハッシュ化されたパスワードが一致しているかを確認するにはBCryptPasswordEncoder.matches()を使います。
第一引数は生のパスワード(ユーザーから入力されたパスワード)、第二引数はハッシュ化されたパスワード(DBに登録されたパスワード)です。
スポンサーリンク
実行
実行するとトップページが開くので「新規登録」を押します。
ID、名前、パスワードをすべて入力して「登録」を押します。
DBに登録されました。
パスワードはちゃんとハッシュ化されています。
先程登録したIDとパスワードを入力して「ログイン」を押します。
登録した名前が表示されます。
【Python】Twitter APIで一方的にフォローしている人を洗い出して自動フォロー解除する
こんにちは。talosです。
TwitterなどのSNSで一方的にフォローしているのって悲しいですよね。
だからと言って一人ひとり解除するのは面倒くさい…
なのでTwitter APIを使って一方的にフォローしている人を洗い出し、フォロー解除します。
環境
言語:Python
ライブラリ:tweepy
方針
1.フォローしている人とフォロワーをリストアップする
2.1で作成したリストを比較してフォローしている人のリストにだけ存在する人をリストアップする
3.2で作成したリストのユーザーをフォロー解除する
フォローしている人とフォロワーをリストアップする
CK、CS、AT、ASにはそれぞれご自身で取得したAPI KEY、API secret key、Access token、Access token secretを入れてください。
また、「フォロワー取得」と「フォローしている人取得」で呼んでいるtweepy.Cursor()のidのところにご自身のアカウント名(@からはじまるやつ)を入れてください。
「CSV出力」をするフォルダはご自身の環境に合わせて決めてください。
import tweepy import pandas as pd CK = '****' # API KEY CS = '****' # API secret key AT = '****' # Access token AS = '****' # Access token secret auth = tweepy.OAuthHandler(CK, CS) auth.set_access_token(AT, AS) api = tweepy.API(auth, wait_on_rate_limit=True) cols = ['id'] # フォロワー格納用DataFrame followers_ids = pd.DataFrame([], columns=cols) # フォローしている人格納用DataFrame followings_ids = pd.DataFrame([], columns=cols) # フォロワー取得 itr = tweepy.Cursor(api.followers_ids, id='****', cursor=-1).items() for follower_id in itr: record = pd.Series([follower_id], index=followers_ids.columns) followers_ids = followers_ids.append(record, ignore_index=True) # フォローしている人取得 itr = tweepy.Cursor(api.friends_ids, id='****', cursor=-1).items() for following_id in itr: record = pd.Series([following_id], index=followings_ids.columns) followings_ids = followings_ids.append(record, ignore_index=True) # CSV出力 followers_ids.to_csv('../csv/followers.csv') followings_ids.to_csv('../csv/followings.csv')
これを実行するとフォロワーのIDをリスト化したCSVファイルとフォローしている人のIDをリスト化したCSVが作成されます。
フォロワーのリスト
フォローしている人のリスト
なおここでいうIDはアカウント名とは異なります。
現時点ではIDが誰のものかわかりませんが、後ほどわかるのでここでは置いておきます。
スポンサーリンク
一方的にフォローしている人をリストアップする
こちらもフォルダを三か所で指定しているので、ご自身の環境に合わせて修正してください。
import tweepy import pandas as pd CK = '****' # API KEY CS = '****' # API secret key AT = '****' # Access token AS = '****' # Access token secret auth = tweepy.OAuthHandler(CK, CS) auth.set_access_token(AT, AS) api = tweepy.API(auth, wait_on_rate_limit=True) # フォロワーのリストを読み込む followers_ids = pd.read_csv('../csv/followers.csv', index_col=0) # フォローしている人のリストを読み込む followings_ids = pd.read_csv('../csv/followings.csv', index_col=0) # 一方的にフォローしている人格納用DataFrame oneside_follow = pd.DataFrame([], columns=['id', 'name', 'screen_name', 'description']) # フォローしている人リストに存在していてフォロワーリストに存在していないユーザーを抽出 for following_id in followings_ids['id']: if following_id not in followers_ids['id'].values: # ユーザーの情報を取得 user = api.get_user(following_id) record = pd.Series([user.id, user.name, user.screen_name, user.description], index=oneside_follow.columns) oneside_follow = oneside_follow.append(record, ignore_index=True) # CSV出力 oneside_follow.to_csv('../csv/oneside_follow.csv')
これを実行すると一方的にフォローしている人の情報をリスト化したCSVが作成されます。
IDだけでなくユーザー名やアカウント名、自己紹介文も出力するようにしたので、確認してフォロー解除したくない人は消しておきましょう。
一方的にフォローしている人をフォロー解除する
こちらもフォルダを二か所で指定しているので、ご自身の環境に合わせて修正してください。
import tweepy import pandas as pd CK = '****' # API KEY CS = '****' # API secret key AT = '****' # Access token AS = '****' # Access token secret auth = tweepy.OAuthHandler(CK, CS) auth.set_access_token(AT, AS) api = tweepy.API(auth, wait_on_rate_limit=True) # 一方的にフォローしている人リストを読み込む oneside_follow = pd.read_csv('../csv/oneside_follow.csv', index_col=0) # フォロー解除済みユーザー格納用DataFrame removed_users = pd.DataFrame([], columns=['id', 'name', 'screen_name', 'description']) # フォロー解除 for remove_id in oneside_follow['id']: user = api.destroy_friendship(remove_id) record = pd.Series([user.id, user.name, user.screen_name, user.description], index=oneside_follow.columns) removed_users = removed_users.append(record, ignore_index=True) # CSV出力 removed_users.to_csv('../csv/removed_users_'+ datetime.datetime.now().strftime('%y%m%d%H%M%S') + '.csv')
これを実行するとフォロー解除し、フォロー解除したユーザーのリストを作成します。
実際にフォローが外れているか確認してみてください。
令和2年度応用情報技術者試験振り返り
こんにちは。talosです。
先日受験した令和2年度秋期応用情報技術者試験の結果が出たので振り返っていきます。
春期の試験が中止に
新型コロナウイルス感染症が流行し、春期の試験が中止になりました。
そのときは受かる自信があったので非常に残念でした。
(今思うとあのときの実力では受からなかったと思います)
返金されたのは不幸中の幸いでした。
試験当日
感染予防のため1人1机でした。
神経質の私としては非常によかったです。
周りに物音を立てる人や貧乏ゆすりする人もいなかったので最高のコンディションで挑めました。
午前問は過去問からかなりの数が出ていたので余裕でした。
やはりやるべきは過去問です。
しかし午後になり恐ろしいことが起こります。
得点源だった情報システム開発がアジャイルについての問題で一問もわかりませんでした。
急遽念のため勉強しておいたデータベースを解きました。
ちなみに午後問は以下を解きました。
・情報セキュリティ
・プログラミング
・データベース
・プロジェクトマネジメント
・システム監査
スポンサーリンク
自己採点
数日後、解答速報を見て自己採点してみました。
予想得点 | |
---|---|
午前 | 87.5点 |
午後 | 65~73点 |
解答を発表している会社によって正解は違うため多少の幅はあるものの、60点以上はとれそうです。
余程のことがなければ大丈夫そうだと安心しました。
結果は…
クリスマス、合否が発表されました。
結果は合格です。
得点は以下のようでした。
得点 | |
---|---|
午前 | 88.75点 |
午後 | 70.00点 |
午前分野別得点 | 得点 | 満点 | 得点率 |
---|---|---|---|
ストラテジ系 | 23.75点 | 25.00点 | 95.0% |
マネジメント系 | 11.25点 | 12.50点 | 90.0% |
テクノロジ系 | 53.75点 | 62.50点 | 86.0% |
なぜが午前の点数が予想と違いますね。
問題によって配点が違うのでしょうか。
午後は概ね予想通りです。
初心者に贈るアルゴリズム論
こんにちは。talosです。
プログラミング初心者に是非読んでいただきたいアルゴリズムの記事のまとめです。
基本情報技術者試験・応用情報技術者試験対策まとめ
こんにちは。talosです。
今後も追加していく予定です。
Java Silver合格への道 ~X進表記~
こんにちは。talosです。
今回はX進表記についてです。
種類
10進表記
特別な表記はしません。
int d = 100;
おわりに
今回はX進表記について説明しました。
場合によってはそこそこ使うかもしれませんね。