ソフトウェア工学

システム開発ライフサイクル内で働く専門家、学者、学生向けのQ&A

3
条件付きコンパイルのショートカットとしてC / C ++マクロを使用するのは良い習慣ですか?
コードにいくつかのタイプの出力メッセージが必要だとしましょう。それらの1つはDEBUG、コードがデバッグモードでコンパイルされたときにのみ出力されます。 通常私は #ifdef DEBUG std::cout << "Debug message" << std::endl; #endif これはかなり面倒で、多くの場所で使用するのは面倒です。 コードスニペットのマクロを定義することをお勧めします。このように使用しますか? MSG_DEBUG("Debug message") または、マクロなしでそれを処理する他のよりエレガントな方法はありますか?異なるプロジェクトで両方の言語を使用しているため、CとC ++の両方で可能なソリューションに興味があります。
13 c++  c  macros 

3
正式な方法の広範な採用を妨げる障壁は何ですか?[閉まっている]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 2年前に閉店。 正式な方法を使用して、アプリケーションのコードを指定、証明、生成できます。これはエラーが発生しにくいため、主に安全/クリティカルプログラムで使用されます。 日常のプログラミングやWebアプリケーションなどでもっと頻繁に使用しないのはなぜですか? 参考資料: 正式な方法 B法 ホアロジック

7
高頻度イベントを接続制限のあるデータベースに保存する
サーバーに大量のイベントが流入し、平均して1秒あたり約1000イベント(ピークは〜2000)に対処しなければならない状況があります。 問題 私たちのシステムはHerokuでホストされ、比較的高価なHeroku Postgres DBを使用します。これにより、最大500のDB接続が可能になります。接続プーリングを使用して、サーバーからDBに接続します。 DB接続プールが処理できるよりも速くイベントが入ります 私たちが抱えている問題は、イベントが接続プールが処理できるよりも速く来るということです。1つの接続がサーバーからDBへのネットワークラウンドトリップを終了するまでに、n追加のイベントが入るよりも多く、プールに解放されます。 最終的に、イベントは蓄積され、保存されるのを待機します。プールに使用可能な接続がないため、タイムアウトし、システム全体が動作不能になります。 クライアントから遅いペースで問題のある高周波イベントを発信することで緊急事態を解決しましたが、その高周波イベントを処理する必要がある場合にこのシナリオを処理する方法を知りたいです。 制約 他のクライアントがイベントを同時に読み取りたい場合があります 他のクライアントは、DBにまだ保存されていない場合でも、特定のキーを持つすべてのイベントの読み取りを継続的に要求します。 クライアントはGET api/v1/events?clientId=1、クライアント1によって送信されたすべてのイベントを照会して取得できます。それらのイベントがまだDBに保存されていない場合でもです。 これに対処する方法に関する「教室」の例はありますか? 可能な解決策 サーバーのイベントをキューに登録します サーバー上のイベントをキューに入れることができます(キューの最大同時実行数は400であるため、接続プールが不足することはありません)。 次の理由により、これは悪い考えです。 使用可能なサーバーメモリを使い果たします。スタックされたエンキューイベントは、大量のRAMを消費します。 サーバーは24時間ごとに1回再起動します。これはHerokuによって課される厳しい制限です。イベントがエンキューされている間にサーバーを再起動すると、エンキューされたイベントが失われます。 サーバーに状態が導入されるため、スケーラビリティが低下します。マルチサーバー設定があり、クライアントがキューに入れられたイベントと保存されたイベントをすべて読みたい場合、キューに入れられたイベントがどのサーバーに存在するかはわかりません。 別のメッセージキューを使用する メッセージキュー(RabbitMQなど)を使用して、メッセージをポンプで送り、もう一方の端にはDB上のイベントの保存のみを処理する別のサーバーがあると仮定します。 メッセージキューがエンキューされたイベント(まだ保存されていない)のクエリを許可するかどうかわからないので、別のクライアントが別のクライアントのメッセージを読みたい場合、DBから保存されたメッセージとキューから保留中のメッセージを取得できますそれらを連結して、読み取り要求クライアントに返送できるようにします。 複数のデータベースを使用し、それぞれが中央のDBコーディネーターサーバーでメッセージの一部を保存して、それらを管理します しかし、もう1つの解決策は、中央の「DBコーディネーター/ロードバランサー」で複数のデータベースを使用することです。イベントを受信すると、このコーディネーターはメッセージを書き込むデータベースの1つを選択します。これにより、複数のHerokuデータベースを使用できるようになり、接続の制限がデータベースの500倍になります。 読み取りクエリで、このコーディネーターはSELECT各データベースにクエリを発行し、すべての結果をマージして、読み取りを要求したクライアントにそれらを送り返すことができます。 次の理由により、これは悪い考えです。 この考えは...ええと..オーバーエンジニアリングのように聞こえますか?同様に管理するのは悪夢です(バックアップなど)。構築と保守は複雑で、絶対に必要でない限り、KISS違反のように聞こえます。 一貫性を犠牲にします。このアイデアを採用すれば、複数のDBでトランザクションを実行することはできません。

5
すべての開発者にコードレビューを行わせる
私は7-8人の開発者チームのソフトウェア開発者です。私たちは現在かなり長い間コードレビューを行っており、コードの品質は時間の経過とともに向上しています。 しかし、最近、一部の開発者が他の開発者よりも多くのコードレビューを求められていることに気付きました。私は彼らの柔軟な態度のためだと思います。 私の見解では、これはコードレビューの実施方法ではありません。すべてのチームがそれを説明し、コードレビュー担当者が変更を簡単に受け入れる意思があるために選ばれるべきではありません。 チームでこの問題にどのように対処しますか? コードレビュー担当者を選択するためのルールを確立しましたか? コードレビュー担当者は、(良い)コードレビューを行った時間に対して報われるべきだと思いますか?そして、彼らはどのように報われるべきですか? あなたの答え/アイデアをありがとう。

2
リポジトリにソフトウェアライセンスをコミットするのが遅れた場合、以前のコミットはすべてライセンスからバインド解除されますか?
100件のコミットがあるプライベートプロジェクトがあるとします。101回目のコミットまでソフトウェアライセンスを追加しません。プロジェクトをオープンソースにした場合、最初の100件のコミットはすべて、101回目のコミットのソフトウェアライセンスに拘束されないということですか? ライセンスが追加されたときにプロジェクトをリベースする必要がありますか?

3
静的タイプチェックを使用してビジネスエラーから保護する
私は静的型チェックの大ファンです。これは、次のような愚かな間違いを犯さないようにします。 // java code Adult a = new Adult(); a.setAge("Roger"); //static type checker would complain a.setName(42); //and here too しかし、それはあなたがこのような愚かな間違いを犯すことを妨げません: Adult a = new Adult(); // obviously you've mixed up these fields, but type checker won't complain a.setAge(150); // nobody's ever lived this old a.setWeight(42); // a 42lb adult would …

4
修正された後にのみテストできるバグをTDDするにはどうすればよいですか?
次に例を示します。私のWebアプリケーションには、ドラッグ可能な要素が含まれています。要素をドラッグすると、ブラウザは「ゴーストイメージ」を生成します。ドラッグするときに「ゴーストイメージ」を削除したいので、この動作のテストを作成します。 私の問題は、最初にこのバグを修正する方法がわからないことであり、テストを書く唯一の方法は修正した後です。 などの単純な関数ではlet sum = (a, b) => a - b、コードを記述する前に、なぜsum(1, 2)等しくないかに関するテストを書くことができ3ます。 私が説明しているケースでは、検証が何であるかわからないので、テストできません(アサーションがどうあるべきかわかりません)。 説明されている問題の解決策は次のとおりです。 let dataTransfer = e.dataTransfer let canvas = document.createElement('canvas'); canvas.style.opacity = '0'; canvas.style.position = 'absolute'; canvas.style.top = '-1000px'; dataTransfer.effectAllowed = 'none'; document.body.appendChild(canvas); dataTransfer.setDragImage(canvas, 0, 0); これが解決策だとは知らなかった。ソリューションをオンラインで見つけた後、テストを作成することさえできませんでした。実際に機能するかどうかを知ることができる唯一の方法は、このコードをコードベースに追加し、目的の効果があったかどうかをブラウザで確認することでした テストは、TDDに反するコードの後に​​記述する必要がありました。 この問題に対するTDDアプローチはどうなりますか?コードの前にテストを書くことは必須ですか、それともオプションですか?

5
voidメソッドの単体テスト
アプリケーションのバグを修正するために、postLoginという名前の既存のメソッドに呼び出しを追加することにより、という名前のメソッドを変更しましたgetShoppingCart。 コード protected void postLogin() { getShoppingCart(); } ただし、単体テストを作成する最適な方法が何であるかはわかりませんpostLogin。 アプローチ1 Mockitoのverifyを使用して、メソッドが呼び出されたことを確認します。 verify(mock).getShoppingCart(); アプローチ2 ユーザーのショッピングカートの値を取得して、メソッド呼び出しの副作用をテストします。 AssertNotNull(user.getShoppingCart()); 1つのアプローチは他のアプローチよりも優れていますか?

3
イベントストアではなく「スナップショット」プロジェクションから集計を再水和する
そのため、実際のプロジェクトにパターンを適用する機会は一度もありませんでしたが、しばらくの間、イベントソーシングとCQRSをいじっていました。 読み取りと書き込みの懸念を分離することの利点を理解しています。また、イベントソースとは異なり、イベントストアとは異なる「読み取りモデル」データベースに状態の変更を簡単に投影できます。 私があまりはっきりしていないのは、イベントストア自体から集計を再水和する理由です。 「読み取り」データベースへの変更の投影が非常に簡単な場合、スキーマがドメインモデルと完全に一致する「書き込み」データベースへの変更を常に投影しないのはなぜですか。これは、事実上スナップショットデータベースになります。 これは、ES + CQRSアプリケーションでかなり一般的だと思います。 この場合、イベントストアは、スキーマの変更の結果として「書き込み」データベースを再構築するときにのみ役立ちますか?それとも、もっと大きなものが欠けていますか?

2
LinkedListを拡張するスタック。Liskov Substitution Principleの違反?
クラスLinkedListは、add_first()、add_last()、add_after()、remove_first()、remove_last()、remove()などの関数とともに存在します 現在、push()、pop()、peek()、またはtop()などの機能を提供するクラスStackがあり、これらのメソッドを実装するためにLinkedListクラスメソッドを拡張しています。これは、リスコフ代替原理の違反ですか? たとえば、リンクリストのn番目の位置にノードを追加する場合のadd_after()の場合を考えます。これは基本クラスで実行できますが、Stackクラスでは実行できません。ここで事後条件が弱くなっていますか、それともadd_after()メソッドを変更してスタックの一番上に追加しますか? また、違反ではない場合、これは悪い設計ですか?そして、LinkedListクラスを使用してStack機能をどのように実装しますか?

1
マイクロサービスはユーザーである必要がありますか?
マイクロサービスのアクセス権を制限しながら、マイクロサービスアーキテクチャでユーザーを承認する最適な方法を決定しようとしています。このアーキテクチャでは、中央認証サービスを使用して、JWTトークンの発行を処理します。 次の要件があります。 ユーザーは特定の役割を実行するように制限する必要があります。たとえば、ユーザーは自分が所有するコンテンツのみを作成、変更、または読み取りできる必要があります。 マイクロサービスは、必要な権限のみに制限する必要があります。たとえば、別のサービスからデータを読み取るだけでよいマイクロサービスは、そのサービスへのデータの書き込みを明示的に禁止する必要があります。 例として、ユーザーが画像ストアサービスに写真をアップロードできるシステムがあるとします。写真に位置を自動的にタグ付けするタグ付けサービスがあります。ユーザーは自分の写真のみをCRUDできます。タグ付けサービスは、イメージストアサービスから任意のイメージを読み取ることができますが、変更/削除はできません。 JWTトークンを使用して上記を達成する良い方法は何ですか?私たちが議論したいくつかのソリューションは次のとおりです。 画像ストアサービスは2つのAPIを公開します。1つは外部で利用可能(ユーザーCRUDアクセスを提供)、もう1つは内部で利用可能(内部読み取り専用アクセスを提供)です。柔軟性がないようです-別の内部サービスがすべての画像(たとえば、明示的な画像を自動的に削除するもの)への読み取り/書き込みアクセスを必要とする場合はどうなりますか? ユーザーのJWTに2つの許可を設定します。1つはCRUD_OwnImagesで、もう1つはREAD_ForAnalysisです。タグ付けサービスは、ユーザーがREAD_ForAnalysis権限を持っているかどうかを確認し、もしそうであれば、適切な要求を行います。ユーザー自身の画像でのCRUD操作のためにユーザーがCRUD_OwnImagesを持っているかどうかを確認する別のマイクロサービスがあります。これにより、各マイクロサービスに責任が課され、ユーザーは必要なアクションに制限されます。画像ストアには、このアプローチで各マイクロサービスを制限する方法がないため、潜在的に不安定でエラーが発生しやすくなります。 READ_ForAnalysisを許可として、タグ付けマイクロサービスに独自のユーザーを与えます。次に、タグ付けサービスが画像ストアから画像を要求すると、それらへのアクセスが許可されますが、それらの変更は禁止されます。ユーザーのユーザーはCRUD_OwnImages権限のみを持っているため、フロントエンドから自分の画像のみを取得してアクセスすることができます。別のサービスがすべてのデータに対してCRUDを必要とする場合、CRUD_AllDataまたは同様のサービスを提供できます。各サービスが独自のデータを担当するようになったため(このロジックは複数のサービスに複製されるのではなく)このアプローチが好きですが、サービスにユーザー権限とマイクロサービス権限の両方が必要な場合はどうでしょうか?2つのJWTトークン(ユーザーとマイクロサービスの両方)を安全に送信できますか?許可を安全に組み合わせて送信する方法はありますか?例えば ユーザー情報がさらに下流に必要な場合(2または3マイクロサービス離れている)、問題は悪化します。私たちは、必要なアクションに自分自身を制限するのは個々のマイクロサービス次第であり、それを明確にしないと仮定するだけですか?

3
自動化されたテストを人気にする方法は?[閉まっている]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 2年前に閉店。 私たちのコードベースは現在20年間成長しています。私たちは500klocで作業する約10人の開発者+ sqaです。少し前に、私たちの小さなチーム(2人の開発者、1人はsqaから)が自動化されたテストプログラムに取り組み始めました。現在、1回の実行には11時間かかり、どういうわけか統合テストです。この問題を解決し、誤検知を減らすために取り組んでおり、その点で大きな進歩を遂げています。しかし、詳細は重要ではありません。 問題なく機能しており、改善を続けています。私たち(小さなチーム)はとても気に入っています。何かを壊すと、2か月後ではなく1日後にsqaが表示されます。また、私たちのマネージャー(dev + sqa)はこのアイデアを気に入っています。しかし、チームの他の人々はテスト結果を無視します。彼らの心では、チェックイン後にテストが失敗する場合、それはテストの問題であり、コードの変更の問題ではなく、単なるおもちゃのプロジェクトです。テストの失敗が本当のエラーである場合、私たちは何度か議論しました。ほとんどの場合です。 私たちは何かを強制することはできませんし、したくありません。自動テストが重要であることをどのように示すことができますか?

3
複数の言語で定数をどのように管理する必要がありますか?
機能的には複数の言語で同じライブラリをサポートしている状況があります。多くの場合、これらの間で共有する必要がある定数があります(たとえば、jsonフィールド名キーまたはエラーコード)。 私が現在これを行う方法は、各言語の定数を定義するコードを持つことです。 問題はメンテナンスにあります。新しいエラーコードを追加する場合、すべてのライブラリで手動で更新する必要があります。少数の人にとってはこれで問題ありませんが、更新するのに5つのSDKを使用しなければならないのは面倒です。これらについても単一の真実の情報源があると便利です。 ある種のconfig-likeファイルについて考えてきましたが、それはすべてのデプロイされたパッケージに含まれる必要があり、ビルド/リリースプロセスが複雑になります。 複数の言語間で共有される定数のメンテナンスを処理するより良い方法はありますか?
13 design  packages 

7
アプリケーションの一部の書き換えを回避する方法
会社で営業部門のプロジェクトに取り組んでいます。それは私の最初のプロのプログラミングの仕事ですが、私は自分でコーディングして何年も学習しています。プロジェクトの一部では、いくつかのデータを取得し、それを入力と組み合わせて生成およびグラフ化します。次に、データを保存します...など。そのため、私はこのためのコードを1日少しで書きました。翌日、私はプロジェクトスーパーバイザーを見せました。彼はそれを気に入っていましたが、「これがあったらどうだろう」と言って、グラフに何かを追加したかったのです。これはプログラムの外観や機能に対する大きな変更ではありませんでしたが、データの保存や処理などに必要な方法を大幅に変更しました。 この場合も、データベーステーブルを再構築し、この新しい要求をサポートするためにコードを基本的にゼロから書き直すのに約1日かかりました。私はそれを再び彼に持ち帰ったが、まったく同じことが起こった。彼は私がデータを処理するために必要な方法を劇的に変える何か他のものを要求しました。それで、私はそれを再び書き直さなければなりませんでした。最後に彼はそれにサインオフしました、そして願わくば、私は再びそれを書き直す必要がないでしょう。 ただはっきりさせてください、私はマネージャーやそのようなものをバッシングしていません。彼は偉大な人物であり、彼が要求していたことはこの世界からではなく、私が以前にやったことと相容れないものでした。 完全な書き直しを避けるために今後できることはないかと思っています。私は柔軟なコードを作成することを理解しており、それをしようとしていましたが、これを簡単にするために別の方法で行うことができたプラクティスまたは事柄を知りたいので、将来、私は何かに3日を費やしません取るべきでした1。

4
データベースの日付データ型の十字軍について:有効ですか?価値がある?他の誰かがそれを感じますか?
SOに関するSQLの質問に答えるのに多くの時間を費やしています。私はこのilkのクエリに頻繁に出くわします: SELECT * FROM person WHERE birthdate BETWEEN '01/01/2017' AND '01/03/2017' SELECT * FROM person WHERE birthdate BETWEEN '2017-01-01' AND '2017-03-01' SELECT * FROM person WHERE birthdate BETWEEN 'some string' AND 'other string' つまり、指定されたパラメータの文字列から日付への暗黙的な変換(不良)に依存するか、データベースがx、000,000個のデータベース行値を文字列に変換し、文字列比較を実行します(悪い) 私は時々コメントをします。特に、スマートな回答を書くのが高回答ユーザーである場合、私は本当に自分のデータ型でだらしない/文字列を入力するべきではないと思う人 コメントは通常、to_date(Oracle)、str_to_date(MySQL)、convert(SQLSERVER)、または同様のメカニズムを使用して、文字列を明示的に日付に変換した方が良いと思われる形式を取ります。 --oracle SELECT * FROM person WHERE birthdate BETWEEN TO_DATE('20170101', 'YYYYMMDD') AND TO_DATE('20170301', 'YYYYMMDD') --mysql …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.