.NET とか Node.js で KeyVault を触る

KeyValult の値をコードから触りたい場合。

.NET の場合

こうする。

var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(new AzureServiceTokenProvider().KeyVaultTokenCallback)

App Service からは MSI で認証しにいく*1。ローカルなら、Visual Studio が Azure で認証した内容が保存していて、クライアントを new するときに勝手にその情報を使いまわしてくれる。

.NET を使用した Azure Key Vault に対するサービス間認証 | Microsoft Docs

あとは client. で Tab ポチポチしたらだいたいわかる。 VS 最高。

Node.js の場合

npm から azure-keyvault をインストール。

npm i azure-keyvault

インポート。

import msRestAzure = require('ms-rest-azure');
import KeyVault = require('azure-keyvault');

App Service からは MSI で認証する。環境変数MSI_ENDPOINT とか MSI_SECRET とかが入ってるのでそれを参照できる。

const client = await msRestAzure.loginWithAppServiceMSI({ msiEndpoint: process.env.MSI_ENDPOINT, msiSecret: process.env.MSI_SECRET, resource: 'https://vault.azure.net' });

ローカルの場合。こちらは VS / .NET のときと違って、勝手に解決してくれない。

interactiveLogin を使って画面からインタラクティブにもやれるが、バックエンドを想定するとこう。 Azure のログインユーザー名とパスワードを生で環境変数にセットする、というのは良い気分ではないが((CLI から az login した認証情報を使いまわせたりするのかな))。。。

const client = await msRestAzure.loginWithUsernamePassword(process.env.KeyVaultLocalUsername, process.env.KeyVaultLocalPassword);

というわけで、合わせてこうなる。

const client = new KeyVault.KeyVaultClient(
  process.env.MSI_ENDPOINT 
    ? await msRestAzure.loginWithAppServiceMSI({ msiEndpoint: process.env.MSI_ENDPOINT, msiSecret: process.env.MSI_SECRET, resource: 'https://vault.azure.net' })
    : await msRestAzure.loginWithUsernamePassword(process.env.KeyVaultLocalUsername, process.env.KeyVaultLocalPassword));

Secret にセットするときはこんなかんじ。すでに存在したらバージョンが increment される。

const result = await client.setSecret('VAULT_URL', 'SECRET_NAME', 'SECRET');

result の中身はこんなかんじになる。

{ 
  value: 'SECRET',
  id: 'https:\\KEY_VAULT_NAME.vault.azure.net\secrets\SECRET_NAME\VERSION',
  attributes: 
  { 
    enabled: true,
    created: 2018-09-04T07:03:25.000Z,
    updated: 2018-09-04T07:03:25.000Z,
    recoveryLevel: 'Purgeable' 
  } 
}

*1:なので App Service で MSI を有効化し、 KeyVault の Access Policies からその MSI を許可しとく必要がある

膝上キーボード

ここ半年くらい、仕事中はキーボードを膝上に置いている。

f:id:tkrtkhsh:20180922155530j:image

 

板状のものはこれ。

 

 なぜかというと、机の上に手を置くのは疲れるから。何を言っているんだという人は一度ためしてみてほしい。明らかに肩が楽。膝の上に手を置くという、座ったときの正しい姿勢に近いのだから当然だ。

だが運用するまでわからないデメリットもある。

まず、数字/記号キー、Fnキーが全然あたらない。ディスプレイとキーボードの距離が広くなり、キーボードを見ようとすると首を動かす必要が生じるのだが、これまではこれらのキーを無意識のうちに目で確認していたようだ。全然ブラインドタッチできてない。これは結構ショックだ。

続いて、マウスが使いづらい。TrackPointに命を捧げている人なら問題ないのだが、ご覧の通りこの板ではマウスが乗らないのでマウスだけ机の上に置いている。普段はTrackPointで済むものの、図を描いたりするときはちょっと困る。

最後に、傍から見るとただ椅子に座ってるだけで仕事していないように見えるということだ。特に正面からだと手が見えないので大変だ。

ワイヤレスキーボードだったら膝上と机上を自由に行き来できるので、たまに切り替えるというのもでき良さそうだ。そのうち変えようかな。

Table Storage でバッチ処理

Azure の Table Storage を .NET から扱う場合は Microsoft.WindowsAzure.Storage 1 が利用できる。その中でバッチ処理についてメモ。

単一のテーブルにバッチ処理を行いたい場合は TableBatchOperation クラスを使う。

var entities = GetEntities();
var operations = new TableBatchOperation();
foreach(var entity in entities)
{
    operations.Add(TableOperation.Add(entity));
}
await table.ExecuteBatchAsync(operations, cancellationToken);

Atomicity は担保されているらしい。なので 1 件でも失敗したらロールバックされるような動きになる。 参考

パフォーマンスもこの方がいいらしい。

また TableBatchOperationIList<T> の実装なので実行順序は保証されている。はず。よね?

注意しときたいのは、このとき entities が空だと ExecuteBatchAsync で空振り......ではなく StorageException を吐く。 TableBatchOperation にオペレーションを詰める前に分岐させてスキップしておくのが良さげ。

var entities = GetEntities();
if(entities.Length > 0)
{
    var operations = new TableBatchOperation();
    foreach(var entity in entities)
    {
        operations.Add(TableOperation.Add(entity));
    }
    await table.ExecuteBatchAsync(operations, cancellationToken);
}

また、 1 バッチオペレーションでは Insert / Delete 同時に実行できるが、同一エンティティを Insert / Delete しようとすると死ぬ。意図的にこんなことをしようとすることはないだろうけど、結果的にそうなっちゃったってことは起こり得るかも。

try
{
    var operation = new TableBatchOperation
    {
        TableOperation.Insert(new UserMappingSet {PartitionKey = "hoge", RowKey = "fuga"}), 
        TableOperation.Delete(new UserMappingSet {PartitionKey = "hoge", RowKey = "fuga", ETag = "*"})
    };  
    await table.ExecuteBatchAsync(operation, cancellationToken);
}
catch (StorageException ex)
{
    // "1:One of the request inputs is not valid. ..."
    log.Error(e.RequestInformation.ExtendedErrorInformation.ErrorMessage)
}

なお複数テーブルに対するトランザクション処理的なものは用意されていない。 Entity Group Transactions というのが使えそうな気配がするが、少なくとも SDK にそれっぽいものがなく、 REST API 専用なのかな?


  1. .NET を使用して Azure Table Storage と Azure Cosmos DB Table API を使用する | Microsoft Docs によると 「 Microsoft.Azure.Storage.Common を使え」らしいが、 NuGet で落とそうとすると preview しかなかったりして謎。

フロントエンドのビルド周りを触った

半年前になるが、年末から年始にかけて業務でフロントエンドのビルド周りを初めてがっつり触ったのでメモ。最新技術みたいな話は特に無いのであしからず。

(この「フロントエンドのビルド周り」を表す言葉って無いんだろうか)

今回書くこと

今回書いてないけどやったこと

  • vue component のビルド
  • svg を Web フォントにビルド
    • あと Cache Busting

簡単に用語の説明

Babel ?

Web ブラウザは ECMAScript という規格に準拠して JavaScript の動作環境を提供していますが、 ECMAScript にはバージョンがあり、ブラウザによってどのバージョンまで対応しているかが異なります。代表的なところでは、ES6 は Chrome / Firefox / Edge / Safari などメジャーなブラウザでは動作しますが Internet Explorer 11 では動作しません。当然新しいバージョンに従って記述できたほうが開発者としてメリットがあるわけですが、できれば多くのブラウザをカバーしたい。そういう場合に、新しいバージョンで記述された JavaScript を古いバージョンでも解釈できるように変換 (transpile) してあげるツールが Babel です。

運用としては、開発時は新しいバージョンで記述された JavaScript をソース管理し、デプロイ時に何かしら自動化ツールによって Babel をかけたものを public なディレクトリに配置する、という流れになります。

SCSS ?

CSS は辛い。その辛さを軽減させた言語です。具体的には変数が使えたり関数っぽいものを書けたり子孫セレクタをネストさせて書けたり等。Babel を使用する場合のように .scss ファイルをバージョン管理してデプロイ時に .css に変換します。似た言語として LESS や Stylus などがありますが、いまのところは Sass 一強 のようです。

Cache Busting ?

JavaScriptCSS などの静的ファイルは、無駄なリクエストを減らすためにクライアントのブラウザにキャッシュさせる戦略をとることが多いです (Web サーバーやブラウザーの設定に依存します) 。このとき、サーバー側でファイルの中身を変更したのにクライアント側にキャシュが残っており、表示が崩れたり JavaScript でエラーが発生する、ということが発生します。これを防ぐため、ファイルが変更されたときにキャッシュを破棄することを Cache Busting と呼びます。よくやる手段 (というか他の手段を知らないのですが) は、ファイル名やクエリ文字列に日付や revision などを付与して URI を変えることで、クライアントに新しいファイルであると認識させてあげる、というものです。

Build System / Task Runner

上述のように、これらを実行するためには開発したものを変換してからデプロイしてあげる必要があります。これを実現するためのツールは Gulp や Grunt などがあり、ビルドシステムやタスクランナーなどと呼ばれています (この呼び名の差異がよくわかってない、、) 。 Grunt の方は開発が止まっており (なぜか 2018/02/07 に約2年ぶりに小さな update がありましたが) 、これから始めるのであれば Gulp の方がよさそうです。ただし、近年は「そもそもタスクランナーいらなくね? npm scripts で十分じゃね?」という動きもあり、要注意です。

あらかじめ変換のためのスクリプトを記述しておき、コマンドから gulp などで実行します。あるいは gulp --watch としておくと都度コマンドを実行せずともファイルを保存したときにスクリプトが走るので、開発時はこちらを使用したりします。

JavaScript でやったこと

gulpfile.js で以下のようにします。 gulp-babelgulp-rev を通しています。これにより、 script にいた .js ファイルが変換されて public/scripts に配置されます。各種プラグインnpm -i --save-dev で入れときます。

const gulp = require('gulp');
const plumber = require('gulp-plumber');
const babel = require('gulp-babel');
const rev = require('gulp-rev');

gulp.task('babel', function () {
    return gulp.src('./scripts/*.js')
        .pipe(plumber({ errorHandler: makeErrorHandler(err => err.toString()) }))
        .pipe(babel())
        .pipe(rev())
        .pipe(gulp.dest('public/scripts'))
        .pipe(rev.manifest())
        .pipe(gulp.dest('public/scripts'));
});

Babel の設定はルートの .babelrc に書いておくと勝手に読み込まれます。

{
  "presets": ["es2015"]
}

gulp-rev は何をしてくれているのかというと、 [元のファイル名]-[ハッシュ値].js といった名前に変換し、そしてその対応表を rev-manifest.json として生成してくれます。ハッシュ値は実行の度に変わります。json の中身はこんなかんじ。

{
    "js/unicorn.js": "js/unicorn-273c2c123f.js"
}

これをサーバー側で読み込んで、変換後のファイルを拾います。たとえば Node.js であれば

let revision;
app.all('/*', function(req, res, next) {
    if(!revision) revision = JSON.parse(fs.readFileSync('rev-manifest.json', 'utf-8'));
    
    res.locals.revision = revision;
    
    next();
});

としておいて、view (ejs) で

<script src="/scripts/<%= revision['index.js'] %>"></script>

のようにします。

CSS でやったこと

CSS は Gulp -> Webpack -> SCSS トランスパイル という感じにしました。

......なんでこうしたか覚えてないんですけどね。。たしか js も Webpack にしたかったけどエントリーポイントを複数に指定しようとしてうまくいかなかったとか、そんな感じだったと思います。

Webpack

Webpack はいろんな機能があるので他のツールと並べて説明しづらいのですが、たとえば複数の css ファイルを一つにまとめる (bundle) 、スペースや改行などを削除してファイルサイズを小さくする (minify) 、さらにプラグインを入れて Babel や SCSS トランスパイルをかける、といったことも可能です。設定は JSON で記述します。コマンドから実行もできますし Gulp から呼ぶこともできます。

gulpfile.js で以下のようにします。やはり gulp-rev で Cache Busting を図ります。

const webpackConfig = require('./webpack.config');
const webpackStream = require('webpack-stream');
const rev = require('gulp-rev');

gulp.task('ws', function () {
    return webpackStream(webpackConfig, webpack)
        .on('error', makeErrorHandler(err => undefined))
        .pipe(rev())
        .pipe(gulp.dest('public/bundles'))
        .pipe(rev.manifest())
        .pipe(gulp.dest('public/bundles'));
});

webpack.config.js で以下のようにします。 gulpfile.js の中に直接 JSON を書いても構いませんがファイルの肥大化は避けたいところ。 style-loader css-loader sass-loadernpm i --save-dev で入れておきます。

var glob = require('glob');

module.exports = {
    entry: {
        css: glob.sync('./scss/*.scss')
    },
    output: {
        path: `${__dirname}/bundles/`,
        filename: '[name].bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.scss$/,
                loaders: [
                    'style-loader',
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    }
}

gulp ws を実行すると、 /scss.scss ファイルが CSS にトランスパイルされ、更にバンドルされて css-[ハッシュ値].bundle.js として 1 ファイルにまとまります。

ざざっと書いてきましたが、時間が無い中ゴリ押しで進めたプロジェクトだったので、技術選定にあまり時間を割けなかったのが正直なところ。かつ、このへんの情報を Web で調べようとすると、個別の技術については見つかるのですが横断的にまとまってる記事が少なく、いろいろ案件こなしてアンチパターン踏んでいかないと感覚が身につかないだろうなぁと思っています。

シベリウス 交響曲第2番 第2楽章 の無慈悲さ

まず、このシンフォニーは第1楽章冒頭で奏でられる、上昇する3つの音がモチーフとして全体を支配している。第2楽章も例外でなく、ファゴットの第1主題もこのモチーフから始まる。

 

たぶん、この楽章で上昇形は希望、下降形は絶望を描いている。冒頭は無感情に始まるが、次第に上昇 vs 下降の図式になり、混沌としてくる。希望と絶望どちらが正しいのか?金管のコラールはこれが一体化し非常に狭い幅で上昇と下降を繰り返す。頂点にたどり着いたと思ったら、ホルンによるフレーズの終わりは半音下降というなんとも後味の悪いものだ。

しかし、続く第2主題は一転、救いの音楽になる。美しい旋律に、木管楽器による天使のような上昇音形。そしてなんと、下降形のモチーフが明るく長調で奏でられる!もしかしたら絶望なんてなかったんじゃないだろうか?

 

それでもやはり、希望を信じきれない。第1主題がより感情的に再現される。疑いは続く。絶望感を帯びたままの第2主題。先ほど長調だった下降形も、今回は短調になってしまう。木管楽器の上昇音形も顔を出さない。

しかし、もうこれぞシベリウスといった調子で低音厚めの弦楽合奏が上昇下降を繰り返し、ひたすら祈る。そしてやっと、再び下降形が明るく、トゥッティで登場する。よかった......!!

という安心も束の間。チェロやヴァイオリンによる不吉なフレーズ。木管楽器が、そんなはずはない!と僅かに上昇。しかしこれも弦楽器に激しく否定される。木管も下降。そして最後は、上昇音形すら、悲しく、短調で奏でられてしまう。信じてたのに。嘘だったのか。

 

というわけで、第2楽章は何の慈悲も無い。

しかし、それを踏まえて第4楽章を聴くともう余計嬉しい。フィナーレは上昇する3音のモチーフをひたすら信じる。死ぬほど長い第2主題はモチーフと全く切離されたものだが、それでも信じて、モチーフに頼らずに、絶望に勝利する。それを、コーダでモチーフが称えてくれる。しかもここで、なんとずっと3音で奏でられていたモチーフは第4の音に到達する。このカタルシス!!

いやー、いい曲だ。

 

www.youtube.com

 

なお、シベ4になると全曲を通して無慈悲である。。

ホルンのウォームアップ

週末ホルニストは(ホルンに限らないだろうが)、合奏前の短いウォームアップでいかにベストコンディションに近づけられるかが重要です。

ウォームアップで重要なのは、音を出すことで体を暖めること。そして、自分のコンディションを確認すること。

集中力を欠いてダラダラと「いつものメニュー」をこなしてしまうと、合奏中もなかなかコンディションが上がらず、その日の合奏をムダにしてしまいかねません。

というわけで自分がふだんコンディションのどのポイントを確認しながらどんなメニューに取り組んでいるのか振り返ってみます。これは自分への戒め、再確認でもあります。


ロングトーン

内容

真ん中の C からスタート。音量はmfくらい。F管で、4拍伸ばしたらスラーで半音下がる。下がって4拍伸ばしたらブレス。次は下がった音からまた4拍伸ばし、スラーで半音下がる......これを繰り返す。下の音がFに達したら終了。

確認すること

  • 息を適切に吸えているか?
    • 量は十分か?
    • 横隔膜、およびその周りの筋肉がスムーズに動くか?無理してないか?
  • タンギングがスムーズか?
    • 音の出だし、空気が唇を抜けはじめる感覚はどうか?
    • 唇が心地よく振動しているか?
  • 息を適切に吐けているか?
    • 音程、音量が揺れていないか?
    • 腹筋はどうか?同じ息の量を保てているか?
    • アパチュアは一定か?
    • 唇の振動は一定か?
  • スラーはスムーズか?
    • 息の向きを無理やり変えていないか?
    • 唇の振動がスムーズに切り替わっているか?
    • 指の動きと息のコントロールがシンクロしているか?
  • 腕の筋肉の使い方が適切か?
    • 右手の角度はどうか?上腕二頭筋が無理していないか?
    • 左胸が無理していないか?

リップスラー

内容

F C A C (ブレス) F C A F を1セットとして、半音ずつ上げていく。音量は f 。フルブレスで。

確認すること

  • 息を適切に吸えているか?
    • ロングトーン後なのでより吸えるようになっているはず。無理なくフルブレスできるか?
  • 息を適切に吐けているか?
    • f に唇、腹筋が耐えられるか?
  • スラーはスムーズか?
    • 音が途切れるよりは間に音が入ったほうがいいが、思いどおりに切り替わるか?
  • アンブッシュアは一定か?
    • 唇、息の向きが無理していないか?
  • 音量は適切か?
    • 音によって音量が変わったりしないか?

ロングトーン再び

内容

真ん中の C を ff で伸ばす。

確認すること

  • 息を適切に吸えているか?
    • まだ油断しない。
  • 息を適切に吐けているか?
    • 横隔膜が一定のスピードで動くか?
  • 唇が適切に振動しているか?
    • アパチュアが広くなり、ここまで振動しなかったところが振動するようになっているはず。その振動が無理していないか?

ハイトーン

内容

五線の中の F からスタート。8拍くらい伸ばし、半音ずつ上げていく。上のFに達したら終了。

確認すること

  • 息を適切に吸えているか?
    • 細くなっていないか?
  • 唇の周りの筋肉はどうか?
    • 無理していないか?しっかり引き締まっているか?
  • アパチュアが適切か?
    • 狭いアパチュアに心地よく息が通っているか?
  • 顔全体の筋肉はどうか?
    • 眉毛を上げたりして、こめかみあたりの筋肉がほぐれているか?

ざっと挙げてみましたが、まだまだある気がする。。

あと、タンギングのメニューを取り込んでもいいかも、と思った。

思いついたらまた書いてみよう。

ドラッカーによるイノベーションの7つの機会

年末年始にドラッカーイノベーションと企業家精神を読んだ。面白かったがが頭の中で整理しきれなかったので、その中から「イノベーションの7つの機会」をまとめてみる。

あるイノベーションは、いずれかの機会のみによって生まれるとは限らず、複数の機会の組み合わせによって生まれることもある。

1. 予期せぬことの生起

予期せぬ成功

  • リスクが小さいはずだが、見逃されることが多い(否定されることすらある)機会。
  • 「弊社のこの事業がなぜか成長しているが、本当に取り組みたい事業ではない」
  • 予期していないため、観測・分析されないこともある。目にとまる仕組みを体系化する必要がある。

予期せぬ失敗

  • 成功すると思っていたビジネスの失敗。予期せぬ成功と違って見逃されることは少ないが、機会であると捉えられることは少ない。
  • 慎重に行われたビジネスであったら、想定と現実に差異があったことになる。差異こそが機会。
  • 自身だけでなく他者の予期せぬ失敗からも学ぶことができる。
  • 企業家たる者にとって、現実が変化した原因を知る必要はない。何が起こったかはわかっても、なぜ起こったかはわからないほうが多い。だが、なぜ起こったかはわからなくともイノベーションに成功することはできる。

2. ギャップ

  • 現実にあるものと、あるべきものとの乖離。
  • 定量的でなく定性的であることが多い。

業績ギャップ

  • 需要が伸びているのに業績が伸びていない状態。
  • 産業全体で生じていることが多い。
  • 行動する前に、解決すべき問題を明確にし、既存の技術・資源を利用して解決策を考える。

認識ギャップ

  • 産業内部の者が現実を誤って認識している状態。
  • 「この問題を解決するためにこの分野に力を入れるべき」
  • 問題を複雑に認識してしまっている状態に対し、より単純な方法を提供することでイノベーションとなることが多い。

価値観ギャップ

  • 消費者が持つ価値観を生産者が誤って認識している状態。
  • 「貧しい人たちが何を変えるかを知っているのは、彼ら貧しい人たちではなく私である」
  • 生産者が提供していると思っているものを購入する消費者はほとんどいない。このとき、生産者は消費者が不合理であるとみなすが、ここにこそ機会がある。

プロセスギャップ

  • ある業務プロセスに課題がある状態。
  • 特定の産業に対して丁寧にヒアリングすることで明らかになることが多い。消費者は多くの場合、すでにそのギャップを感じている。

3. ニーズ

  • ニーズによるイノベーションが成功するには5つの前提がある。
    • 完結したプロセスについてのものである
    • 欠落した部分や欠陥が1箇所だけである
    • 目的が明確である
    • 目的達成に必要なものが明確である
    • 「もっとよい方法があるはず」という認識が浸透している
  • また3つの条件がある
    • 何がニーズであるかが明確に理解されている
    • 必要な知識が手に入る
    • 解決策が、それを使う者の仕事の方法や価値観に一致している

プロセス上のニーズ

  • 状況ではなく課題からスタートする。誰もがそのニーズが存在していることを知っているが、手を付けられていない状態。
  • ひとたび解決すると、そのイノベーションは標準となる。

労働力上のニーズ

  • 機械/ロボットによる自動化など。

知識上のニーズ

  • 研究開発によって満たされるニーズ。課題はすでに明らかになっている。
  • プロセス上のニーズや労働力上のニーズよりも困難でリスクが大きい。

4. 産業構造の変化

  • 産業・市場の構造は、内部の人間が感じるよりも脆弱である。
  • 小さな企業が機会としてとらえ、大企業が損失を被ることが多い。
  • 産業の外部からは機会、内部からは脅威とみえる。
  • ここでのイノベーションは単純でなければならない。
  • 以下の場合、ほぼ確実に起こる。
    • 急速な成長
    • 急速な成長に伴い、その市場のとらえ方、対応の変化
    • いくつかの技術の合
    • 仕事の仕方の急速な変化

5. 人口構造の変化

  • 人口の増減、年齢構成、雇用、教育水準、所得などの変化。
  • 可能性・リードタイムの予測が容易。
  • 急速に、原因もわからず起こる場合もある。このケースを認めようとしない場合は敗者となる。
  • 統計ではなく、街の観察によって変化の可能性に気づく場合もある(ただし統計がベースであるべき)。

6. 認識の変化

  • コップの半分に水が入っているとき、「半分は満たされている」なのか「半分は満たされていない」とするのか。
  • 1960年代から20年後、アメリカでは健康度が著しく上昇したが、多くのアメリカ人の不健康への恐怖は増大していた。健康に対する認識が変わっていた。
  • やはり、原因はわからないことが多い。また定量的でない。定量化できたとしても、そのときにはイノベーションの機会には遅すぎる。
  • 一時的なものか永続的なものか見分けがつきづらいため、小規模に始める必要がある。

7. 新しい知識の出現

  • 技術的・社会的知識によるイノベーション
  • 実用化までのリードタイムが長い。市場で受け入れられるようになるには25年から35年を要する。リードタイムの長さは短くなっているとされているが、錯覚にすぎない。
    • (所感: これはさすがに多少は短くなっているのではないだろうか??)
  • 科学や技術以外の知識を含め、複数の知識が結合して起こる。
  • 必要な知識の全てが用意されなければ必ず失敗する。
  • 3つの条件がある。
    • 社会、経済、認識の変化などあらゆる要因の分析。分析しなければ、何の知識が足りないのかがわからない。
      • 科学者や技術者は自分がすべてを知っていると思い込んでいるが、多くの場合誤っている。
    • 戦略。戦略には3つしかない。
      • システム全体を自ら開発し、それを手に入れる
      • システム全体ではなく、特定の市場を確保する(自ら創造する)。
      • 重要な能力に力を集中し、重点を占拠する。産業が変化しても超然としていられる場所を探す。
    • マネジメント。リスクの大きさをマネジメントで補う必要がある。
      • 新しい知識のイノベーションが失敗する原因の多くはマネジメントの不足である。
  • ほかのイノベーションはすでに起こった変化を利用するが、ここではイノベーションが変化を起こす。それによりニーズが生まれる。世に受け入れられるかどうかはわからない。
  • 誰もがニーズがあると知っていても、実際に現れると抵抗されることもある。
  • リスクが大きいが、それを予期せぬ出来事やギャップの存在、ニーズの存在といった機会とみなし、リスクを減らすことができる。