21世紀の錬金術:Web2.0バブルで一儲けする方法
学生4年間で学んだことそのままです。
外部の人間や経験ある人間から見れば周到に仕組まれた道を進んでいることが明白でも、内部で働く人間には気づきにくいこと、そして上場が簡単にできてしまう日本の新興市場が問題でしょうか。もし、Web2.0ブームに乗ってアイデア一つ・WEBサービス一本で起業するならばExit戦略はM&A(買収)されることに見据えるのが普通だろう。
関連
ポールグレアムはハッカーでなくて
l'essentiel est invisible pour les yeux
21世紀の錬金術:Web2.0バブルで一儲けする方法
学生4年間で学んだことそのままです。
外部の人間や経験ある人間から見れば周到に仕組まれた道を進んでいることが明白でも、内部で働く人間には気づきにくいこと、そして上場が簡単にできてしまう日本の新興市場が問題でしょうか。もし、Web2.0ブームに乗ってアイデア一つ・WEBサービス一本で起業するならばExit戦略はM&A(買収)されることに見据えるのが普通だろう。
関連
ポールグレアムはハッカーでなくて
specの場合はmodelテストのほうが良さげ
Index: slow_query_logger.rb
===================================================================
--- slow_query_logger.rb (revision 5)
+++ slow_query_logger.rb (revision 6)
@@ -116,10 +116,11 @@
if __FILE__ == $0
# get all controlelrs name
- controller_pattern = Pathname.new(File.join(RAILS_ROOT, 'app', 'controllers', '*.rb'))
- controllers_list = FileList.new(controller_pattern.to_s)
- controllers_list.map! { |path| File.basename(path).sub('.rb', '') }
-
+ controller_pattern = Pathname.new(File.join(RAILS_ROOT, 'app', 'controllers', '*.rb'))
+ model_pattern = Pathname.new(File.join(RAILS_ROOT, 'app', 'models', '*.rb'))
+ controllers_list = FileList.new(controller_pattern.to_s).map! { |path| File.basename(path).sub('.rb', '') }
+ models_list = FileList.new(model_pattern.to_s).map! { |path| File.basename(path).sub('.rb', '') }
+
# Clear the slow query log
ActiveRecord::Base.slow_query_logger.clear
@@ -127,14 +128,19 @@
unittest_functional_test_file = File.join(RAILS_ROOT, 'test', 'functional', "#{controller}_test.rb")
rspec_controller_spec_file = File.join(RAILS_ROOT, 'spec', 'controllers', "#{controller}_spec.rb")
- # check for unit test or spec file of rspec
+ # checks for unit test or spec file of rspec
if File.exists?(unittest_functional_test_file)
require unittest_functional_test_file
elsif File.exists?(rspec_controller_spec_file)
require rspec_controller_spec_file
-# rails_spec = Pathname.new(File.join(RAILS_ROOT, 'script', 'rails_spec')).cleanpath.to_s
-# cmd = rails_spec + " " + Pathname.new(rspec_controller_spec_file).cleanpath.to_s
-# system cmd
end
+
+ # checks for file of RSpec model's spec
end
+
+ # Checks for file of RSpec model's spec
+ models_list.each do |model|
+ rspec_model_spec_file = File.join(RAILS_ROOT, 'spec', 'models', "#{model}_spec.rb")
+ require rspec_model_spec_file if File.exists?(rspec_model_spec_file)
+ end
end
class IndexController < ApplicationController::Base
def index
@me = session[:user]
@my_loves_friends = cache(:key => "index_controller_loves_friends", :expire => 10.minutes) do
@me.find_loves_users(:limit => 10)
end
end
end
はてぶやdel.icio.usで意見をもらったので、ActiveRecord::QueryCacheにキャッシュの削除に関する設定をできるように実装した。
使用方法
:expire_methodsでキャッシュを削除するメソッドを指定する。指定できるメソッドは、ActiveRecord#after_○○のメソッド名。
class Person
query_cache :expiry => 3.minutes, :expire_methods => [:create, :update, :destroy]
end
def query_cache(options)
options.assert_valid_keys([:expiry, :expire_methods])
write_inheritable_attribute('query_cache_expiry', options[:expiry] || 0)
[options[:expire_methods]].flatten.each do |method|
__send__("after_#{method}") { __send__(:delete_all_query_cache) }
end unless options[:expire_methods].nil?
end
ActiveRecord::QueryCache
ActiveRecordの富豪っぷりに困っている。キャッシュの仕組みが用意されているみたいだが過去の遺物となり使用されていない様子。(See Class::ActiveRecord::QueryCache) だから作った。
ActiveRecordの富豪っぷり
- SQL単位ではなくActiveRecord#findに渡された引数をキーとしてキャッシュを保存する。
- キャッシュの保存先にはmemcachedのみ対応。(2007/4/22現在)
- メソッド単位でキャッシュのexpiryを設定することはできない。クラス単位で指定する。(改良するかも)
% sudo apt-get memcached
% sudo gem install memcached-client
% svn co http://shindaita.stiq.net/svn/cache_on_rails/query_cache.rb /path/to/raisapp/lib
# config/enviroment.rb
require 'query_cache'
CACHE = MemCache.new 'localhost:11211', :namespace => 'rakuto.blogspot.com', , :multithread => true
CACHE = MemCache.new 'localhost:11211', :namespace => 'rakuto.blogspot.com'
class Person < ActiveRecord::Base
query_cache :expiry => 10.minutes
end
p Person.find(:all, :conditions => "name like '%'", :cacheable => true)
Person.delete_all_query_cache
class Person
query_cache :expiry => 3.minutes, :expire_methods => [:create, :update, :destroy], :silence => false
end
- キャッシュ戦略についてもう少しバリエーションを増やしたい。
- memcached以外のCacheStoreへの対応。
- キャッシュの削除戦略が普通はどうするものなのかよくわからない。詳しい人教えてください。
AR#findに第一引数(:all, :first)のみ渡した場合のbug fix. (Revision 8)
こちらのChangeset 6197でRailsアプリ名を含むランダムなsession_keyを使用するようになったので、Mobile on Railsもそれに対応した。
Mobile on Rails
Index: workspace/mobile_on_rails/lib/mobile/controller.rb
===================================================================
--- workspace/mobile_on_rails/lib/mobile/controller.rb (revision 65)
+++ workspace/mobile_on_rails/lib/mobile/controller.rb (revision 66)
@@ -31,7 +31,7 @@
def rewrite_options_with_session_id(options)
if request && request.mobile?
- session_key = ::ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_key] || '_session_id'
+ session_key = self.class.read_inheritable_attribute("session_options")[0][:session_key] || '_session_id'
if request && request.session.session_id
options = options.dup
options.update session_key => request.session.session_id
限りなく少ないのに笑った。
SlowQueryLogger
仕方が無いので自己リンク。
2はてぶ
1クリップ
8デリ
テストを実行してEXPLAIN情報からボトルネックとなるクエリをソース中で使用されている箇所とともに、書き出すアイデアは面白いと思ったのになぁ。。
VaryなCacheへの対応・複数DB対応・ボトルネック測定など組み込んで洗練させて、
Scaling Rails Suiteとして出せばもっとうける?
P.S
yuin元気かな?
経営者像に正解は無いし実に色々と存在する。業種により成果をあげる経営者像は異なるだろうし、時代によっても変化するだろう。忠誠を激しく要求するようなスティーブジョブスのような経営者もいれば、ある意味無駄なルールは無視できるエッジのきいた人間を望むようなCEOもいる。
おそらくこれは経営者のバックグラウンドに依存するところが大きい。
UIEJの社長は営業出身でシリコンバレーで働きグリーンカードも持っている。そして、人脈や恩義・忠誠を非常に大事にしているように感じる。UIEのCEOは今でもプログラマであり型破りな意見を言う。相手が偉い人であったりクライアントであろうと自分の考えは突き通す人に見える。
ドリコムを辞めて1年になるがその間の変化はとても大きいようだ。
外野からの見物になるため、メディアを通じて誇張された認識なども含むかもしれない。しかし、「会社はファンのための物」と語るCEOは、外部ではなく社内にファンを作れているのだろうか?
上場企業で自由な社風という甘い言葉に誘惑されて入社した世間知らずの新卒の"ファン"などではなく、「CEOが示すビジョンを実現するためなら、倒れようとプログラムを書きつづける」というような明日の売り上げとなる技術を開発する優秀な技術者のファンを獲得できているのだろうか?
私がドリコムが一番失敗したと思うことはIPOではなく人事に対する散財だ。
経験が豊富な人間や優秀な技術者が転職したいと思える会社つくりではなく、なぜ新卒の採用なのか?魅力のある会社を作りプロモーションをかければ優秀な人間は自然と集まってくる。IPOで得た資金を散財しただけに見合う社員を集めれたのだろうか?その資金を優秀な技術者が集まる会社の風土作りへ当てていたらどういう社員が転職してきただろうか?
過去に成功したビジネスを捨てきることができず、売り上げが上がらない→営業力が足りないとの意思決定→PUSHの営業体制のため人材を整える→急速な人材確保のためにIPOで得た資金が大量に使われるというスパイラルにはまり、本来のコアコンピタンスであった技術や技術者が持つマインドに対するトップマネジメントの理解などどこかに忘れ去られているように感じる。
今の売り上げを確保するための社員だけでなく、明日の売り上げを作り上げる技術者が必要である。パイの合計が決まっている市場でゼロサムゲームをしていては企業の未来は無い。パイが無くなれば新たなパイがある市場に飛びつくことになる。
ドリコムに優秀な技術者がいるが、CEOの示すビジョンで彼らのマインドを魅了し引き止める事ができなくなった際には、優秀な技術者の大規模な流出が起こりえるかもしれない。そうなった時には、目先の売り上げに飛びつき、株式交換により外部の小さなベンチャーの買収を繰り返し、自社の営業力を使って売り上げを計上し上場させ有価証券売却益を本社の売り上げに付け替えるという図式しか考えられない。
私はそのような企業に何の魅力も感じない。
どうしても気になるもう一点が企業の情報統制の甘さである。
毎日が文化祭みたいな会社と書き、社内の写真やミーティングの内容などを赤裸々につづっている新卒社員のブログを時々拝見するが、まともな情報管理体制を引けているのか疑問である。
自由な社風で自分達が主役などという甘い言葉は、経験もあり実績もある優秀な社員が集まった上で初めて形になるものだろう。自由を履き違えてはいけない。
大和証券では新卒社員が5分遅刻した際に、上長がブチきれ机を蹴飛ばしその社員の胸ぐらをつかみかかり罵倒し、その後見せしめとしてその日一日中新卒社員で「遅刻に対して」というお題でMTGが開かれた話を友達から聞いた。新卒社員に対してこの上長が取った行動は正しかったと思う。
PS
私がIPOから学んだ事は、IPOをするために何をするかではなくIPOで得ることのできる資金で何をするかを見据えIPOすることだ。言われてみれば当たり前のことである。
写真は今日自宅に届いたテーブルの写真(写真は別のショッピングサイトのもの)。赤色がポイントとなっていてとてもカッコイイ。
追記
社内のマネジメント体制が確立していない企業が、なぜ企業にも大きな教育コストを割くことになる新卒の採用にこだわるのか?と考えた時の答えは、一つしか思いつかなかった。「新卒を採用しているという事」自体が急成長中の企業であるということを示すためのプロモーションだったのだろう。明らかにプロモーションすべき方向を誤ったように見える。企業のプロモーションも手がけた人事であっただけに、人事担当者の責任は重い。
久々に面白いモノを作った。
SlowQueryLogger
RailsではActiveRecordを利用してガンガン富豪プログラムを書きがちなため、適切にインデクスを張っていないとすぐに重たくなるので、Rails中で発行された遅いクエリをロギングするプログラムを作った。
ActiveRecordの参照系クエリを発行するメソッドをEXPLAINにより実行解析情報を取得しロギングしてから通常の参照クエリを発行するように拡張し、Rails付属のUnit::TestのfunctionalテストまたはRSpecのコントローラーのSpecファイルを実行する。最終的には、filesortか一時テーブルを使用しているクエリがログファイルに書き出される。
つまり、functional testを定義したファイルかRSpecのcontrollerのスペックファイルがあれば特に何も用意する必要はない。
現在MySQL限定だが、次のような情報もあわせてロギングするためSlow Query Logを見るよりもずっと解析が容易になる。
% svn co http://shindaita.stiq.net/svn/slow_query_logger/
% mv slow_query_logger/slow_query_logger.rb /railsapp/script/
% chmod +x /railsapp/script/sloq_query_logger.rb
% ./script/slow_querry_logger.rb
/var/www/rails_app/config/../app/models/user.rb:250:in `find_hoge'
SQL: EXPLAIN SELECT entries.`id` AS t0_r0, entries.`user_id` AS t0_r1, entries.`title` AS t0_r2, entries.`body` AS t0_r3, entries.`created_on` AS t0_r4, entries.`updated_on` AS t0_r5, entries.`group_id` AS t0_r6, entries.`unread_flag_for_self` AS t0_r7, entries.`comments_num` AS t0_r8, entries.`deleted_at` AS t0_r9, entries.`deleted_flag` AS t0_r10, entries.`last_updated_on` AS t0_r11, entries.`last_comment_id` AS t0_r12, entries.`photo_key` AS t0_r13, groups.`id` AS t1_r0, groups.`name` AS t1_r1, groups.`owner_id` AS t1_r2, groups.`public_level` AS t1_r3, groups.`category_id` AS t1_r4, groups.`photo_id` AS t1_r5, groups.`introduction` AS t1_r6, groups.`created_on` AS t1_r7, groups.`updated_on` AS t1_r8, groups.`users_num` AS t1_r9, groups.`official_flag` AS t1_r10, groups.`entry_num` AS t1_r11, groups.`deleted_flag` AS t1_r12 FROM entries LEFT OUTER JOIN groups ON groups.id = entries.group_id WHERE (( entries.deleted_flag = false ) AND ( group_id IN (NULL) )) ORDER BY entries.updated_on DESC LIMIT 5
select_type : SIMPLE
key_len : 5
type : ref
id : 1
Extra : Using where; Using filesort
possible_keys : entries_group_id_index,index_entries_on_group_id_and_created_on
table : entries
rows : 23
ref : const
key : entries_group_id_index
/var/www/rails_app/config/../app/models/user.rb:260:in `find_hoge_hoge'
SQL: EXPLAIN SELECT events.`id` AS t0_r0, events.`group_id` AS t0_r1, events.`title` AS t0_r2, events.`date` AS t0_r3, events.`supplement_date` AS t0_r4, events.`location_id` AS t0_r5, events.`supplement_location` AS t0_r6, events.`user_id` AS t0_r7, events.`description` AS t0_r8, events.`created_on` AS t0_r9, events.`updated_on` AS t0_r10, events.`deleted_at` AS t0_r11, events.`deleted_flag` AS t0_r12, events.`comments_num` AS t0_r13, groups.`id` AS t1_r0, groups.`name` AS t1_r1, groups.`owner_id` AS t1_r2, groups.`public_level` AS t1_r3, groups.`category_id` AS t1_r4, groups.`photo_id` AS t1_r5, groups.`introduction` AS t1_r6, groups.`created_on` AS t1_r7, groups.`updated_on` AS t1_r8, groups.`users_num` AS t1_r9, groups.`official_flag` AS t1_r10, groups.`entry_num` AS t1_r11, groups.`deleted_flag` AS t1_r12 FROM events LEFT OUTER JOIN groups ON groups.id = events.group_id WHERE (( events.deleted_flag = false ) AND ( group_id IN (NULL) )) ORDER BY events.updated_on DESC LIMIT 5
select_type : SIMPLE
key_len : 5
type : ref
id : 1
Extra : Using where; Using filesort
possible_keys : index_events_on_group_id,index_events_on_deleted_flag_and_updated_on
table : events
rows : 1
ref : const
key : index_events_on_group_id
LOGGING_PATERN_FOR_EXTRA_FIELD = /(filesort|temporary)/
参考
5.2.1. EXPLAIN 構文(SELECT に関する情報の取得)
7.2.1. Optimizing Queries with EXPLAIN
第5章 MySQL の最適化
Chapter 7. Optimization
通勤途中にあり引っ越してきた時から気になっていた海路ドマーニというお店に行って来ました。帰りに前を通る度にガーリックとオリーブオイルのとてもいい匂いがします。
シャルドネ (ボトル) 3990円
牛肉のカルパッチョ 970円
アサリのガーリックオイル 1890円
フキノトウとサザエのオイルパスタ 1600円
サザエの苦味をベースにしたオイルパスタ。
うにのクリームソースパスタ 1680円
バニラアイスにエスプレッソ 800円
どれもおいしかったけどせもりなのパスタにあったような感動が無かった。
また世田谷価格なのか価格設定が20%高い気がした。後、少し味が濃かった。
ただ一人でボトル一本あけてまだ頼もうとすると同じワインをグラス一杯分サービスしてくれた。こういう時いつもお店の人に覚えてもらえるので得だなと思う。
地中海料理でおいしかったのは京都のノルマンディがとてもおいしかった。もう随分と昔の気がするがBOCCA del VINOと共にまた行きたい。
渋谷にあるすし善というお店に連れて行ってもらった。
常連さんを大切にするためマスメディア等での紹介は行っていないみたい。このようなお店はネットなどでは見つけられないため、常連として通っている人に連れて行って貰うしか知る術がありません。こんな名店に連れて行ってくれた方にとても感謝します。
どの品もとてもおいしかった。
何よりもうれしかったのが日本酒が豊富でとてもおいしい事とお酒がすすむおつまみをたくさん出してくれること。日本酒は酔鯨(高知)以外初めて飲むものばかりでした。酔鯨も大好きなので注文しました。
黒龍
石鎚
久平次
鯨酔(高知)
鯛(おろしポン酢)
ウニ(ご飯と共に)
タコ(スダチで)
イカ(生姜醤油 or わさび醤油)
とり貝(刺身とにぎり)
だし巻き(絶品)
赤貝(刺身)
こはだ
まだまだ食べましたが忘れてしまいました。本当にどれも絶品でした。
出し巻きといえば京都の八条口にある佳辰というお店のうまきも絶品ですが、それを超えるぐらいおいしかった。
大将もとてもいい人です。
ここで一つラッキーえびすビールと呼ばれるえびっさんが鯛を両手に抱えているビールが存在することを知りました。大将が7年やっていてはじめて見たとのことなのでお目にかかれる機会はほとんど無いかもしれません。
また是非行きたいお店です。
特異メソッドをalias_methodを使用して別名をつけようとするとエラーになる。
だが、同じブロック内でrespond_to?(:find)を実行するとtrueが返される。
undefined method `find' for class `ActiveRecord::Base' (NameError)
module EffectiveRails
module ActiveRecord
def self.included(klass)
klass.send ClassMethods
klass.class_eval do
p respond_to?(:find) # => true
alias_method_chain :find, :explain
end
end
module ClassMethods
def find_with_explain(*args)
# hogehoge
find_without_explain(*args)
end
end
end
end
ActiveRecord::Base.class_eval do
include EffectiveRails::ActiveRecord
end
module EffectiveRails
module ActiveRecord
def self.included(klass)
klass.send ClassMethods
klass.instance_eval do
alias :find_without_explain :find
alias :find :find_with_explain
end
end
module ClassMethods
def find_with_explain(*args)
# hogehoge
find_without_explain(*args)
end
end
end
end
ActiveRecord::Base.class_eval do
include EffectiveRails::ActiveRecord
end
2 April press conference
日本時間で言えば本日PM9時頃~かな。
ビートルズの配信契約の話ではなく、EMIがDRM撤廃を発表するとの事。
スペシャルライブも行われます。
追記
先ほど終了。
EMIアーティストのミュージックビデオもDRMフリーで提供されるほか、
2007年度はデジタルコンテンツの著作権が大きく変わりそうな年。年内にiTunes Storeの50%がDRMフリーかつ高音質で提供されると予測するスティーブジョブス。
ジョブズとEMI、DRMフリーダウンロードサービスを発表