無理しなくても、こんなに上手になれるなんて - Little Goose 学習記録 大規模キュー同期 実戦ログ
序文
ほとんどの人はプログラマーが使用するプログラミング言語や技術的な詳細を理解しておらず、プログラマーがコードを書くときに直面するさまざまな困難や問題を理解できないため、プログラマー以外の人にとっては、プログラマーのコードは神秘的に感じることがあります。また、プログラマが書いたコードがコンピュータ上でどのように実行されるかは比較的謎に満ちており、ほとんどの人はコードの実行中に生成される中間プロセスや結果を見ることができません。これらの要因により、神秘的な感覚が生まれることがあります。
しかし、プログラマーにとって、コードは神秘的なものではありません。彼らにとって、コードを書くことは日常的な仕事であり、問題を絶えず分析し、解決策を考え、それをコード実装に変換する必要があります。彼らはプログラミング言語と技術的な詳細を理解しており、コードに含まれるさまざまな変数、データ型、論理関係を理解できます。コードを記述するとき、プログラマーは古いコードと新しいコードの間でデバッグと最適化も行い、コードの謎をさらに減らします。
プログラマーにとってコードは神秘的なものではなく、日常的な作業の産物ですが、継続的な進歩と成長の過程には、確かに毎回収穫と達成感があります。
1. プログラミング言語の概要
1. PHP は世界で最高の言語です
「PHP は世界で最高の言語です。」PHP は Web 開発で広く使用されており、安定性と開発効率が高く、開発ツールやコミュニティ サポートも比較的充実しています。ただし、PHP にはパフォーマンスが比較的低いなど、大規模で複雑なプロジェクトの開発には適さない可能性があるなど、いくつかの欠点もあります。
しかし、Web開発に関しては、プロジェクト要件、技術的特性、リソース条件などを考慮し、低コスト・高効率の現実主義を追求しており、すでに船に乗り込んでおり、降りることはできません。
2. サードパーティ API ドッキングの悩み
php開発で一番面倒なのはサードパーティAPIとの連携ですが、開発時間の経過にほぼ反比例して毛量の密度は大きくなります。サードパーティ API インターフェイスに接続する場合、次のような一般的な問題が発生します。
-
認証の問題: サードパーティ API は使用する前に認証を必要とするため、プログラマは対応する認証情報を提供し、認証操作を実行する必要があります。認証中は、提供された認証情報が正しく、API インターフェースの要件を満たしているかどうかに注意する必要があります。そうでないと、認証が失敗する可能性があります。
-
パラメータの問題: API インターフェイスを呼び出すとき、リクエスト パラメータ、リクエスト ヘッダーなどを設定する必要があります。設定するときは、パラメータの形式と値が API インターフェイスの要件を満たしているかどうかに注意する必要があります。そうでない場合、リクエストが失敗する可能性があります。失敗。
-
インターフェイスの戻り形式の問題: 一部のサードパーティ API は、XML、JSON などのさまざまな形式でデータを返す場合があり、使用する前にプログラマーが対応するデータの解析と処理を実行する必要があります。処理する際には、データ形式が一致しているか、変換が必要かどうかに注意する必要があります。
-
タイムアウトの問題: API インターフェースを呼び出すときに、リクエストのタイムアウトまたは戻りデータのタイムアウトが発生する場合があります。タイムアウトの問題によるプログラムの中断を避けるために、対応するタイムアウト期間を設定するか、エラー処理を実行する必要があります。
-
セキュリティの問題: サードパーティ API を使用する場合は、データ セキュリティに注意する必要があります。データ セキュリティを保護するために、API インターフェイスの要件に従って、パスワードなどの機密情報を暗号化または非表示にする必要があります。
3. 適切なプロジェクトのスケジュールが絵に描かれている理由
「プロジェクトのスケジュール通りに開発したことがなく、毎日が締め切りのような気分です。」
まず、プログラミング作業が複雑なため、必然的にスケジュールが不確実になります。プログラマーはさまざまな技術的問題や複雑なビジネス ロジックに直面する必要があり、それぞれの問題を解決するにはある程度の時間がかかります。同時に、プログラミング作業では、コードの競合やコードの品質の問題など、さまざまな問題が発生する可能性があります。これらの問題の解決には時間がかかり、スケジュールが不確実になります。
第二に、ソフトウェア開発プロセスの変化とリスクも、スケジュールが定期的に調整される理由の 1 つです。ソフトウェア開発の過程では、要件の変更や機能のリファクタリングなど、当初のスケジュールに影響を与える事態に遭遇することがよくあります。また、ソフトウェア開発の過程には、技術的な実現の困難さやパートナーの変更など、さまざまなリスクが存在します。これらのリスクは、プロジェクトのスケジュールの安定性にも影響を与えます。
要約すると、プログラマーのプロジェクト スケジュールの不確実性は、プログラミング作業の複雑さと、ソフトウェア開発プロセスの変化とリスクによって引き起こされます。プロジェクトのスケジュールと開発品質への影響を避けるために、プログラマーは、プロジェクトが予定どおりに納品され、プロジェクトの品質の安定性が維持されるようにスケジュールを調整する必要があります。
2. コード共有を誇示する
上級プログラマーであればあるほど、ctrl+c および ctrl+v の使用に習熟します。
個人的には、基本的には同意しますが、少し否定します。ctrl+c と ctrl+v が必要なわけではないので、ctrl+c と ctrl+v を使用できます。
プログラマの開発はすべてコピペだというのは誤解です。プログラマーは開発プロセス中に既存のコードを使用することがよくありますが (コピー アンド ペーストとも呼ばれます)、これは開発プロセスのほんの一部にすぎません。
実際、プログラマーはアルゴリズムを設計し、コードを記述し、開発プロセスの複数の段階をテストする必要があります。アルゴリズムを設計するには、複雑な問題を理解し解決するために、数学とコンピューター サイエンスの確かな知識を持つプログラマーが必要です。コードを記述するには、プログラマーがプログラミング言語と開発ツールを習得し、アルゴリズムを実際のコード実装に変換できる必要があり、またコードの品質、読みやすさ、保守性も考慮する必要があります。テストでは、プログラマーはさまざまなテスト ツールとテクニックを使用して、プログラムの正確さと安定性を確認する必要があります。
プログラマーは効率を向上させるためにインターネットまたは他のコード ベースから既存のコードを検索しますが、これはプログラマーがコピー アンド ペーストだけを行うという意味ではありません。既存のコードを使用する場合、プログラマーはそのロジックと実装方法を理解し、個々のニーズを満たすために実際のニーズに応じて適切な変更と最適化を行う必要があります。さらに、コピーして貼り付けたコードは、コードの正確さと安定性を確認するためにテストやデバッグなどの複数の手順を実行する必要があります。
つまり、プログラマーの仕事は単にコードをコピー&ペーストするだけではなく、質の高い開発作業を行うためには、厳密な思考と確かな知識、そして優れた技術が必要となります。
3. 事例の共有
5 月中旬、Gooselink に接続されたサードパーティ プラットフォームが予定より早く開始されました。
- テスト、コードの調整、基本的には継続的な改訂のプロセス中...
- 当事者 A の電話、WeChat、その他の爆撃手段は圧力をもたらしました...
- 夜更かししたり、食事の順番を間違えたり…。
- …
まあ、乗り越えました。DEADLINE に、Xiaogetong 学習レコードの大規模なキュー同期がついに完了し、その効果は次のとおりです。
1. プロジェクトの要件
- 単一の申請者の数は30,000を超えており、Xiaogetongのトークンの取得頻度と学習記録の更新頻度は制限されているため、バッチで直接処理することはできません。
- PHP スクリプト言語の制限により、マルチスレッドは実行できません。つまり、クリック イベントが実現された後、バックグラウンドで自動的に処理されます。
- トレーニングが終了し、コースが完了すると、スーパー管理者はコースの進行状況と学習時間を一度に完了します。各メンバーは自分のバックグラウンドでログインし、自分の学習の進行状況を個別に更新します。
PHP にはスリープ機能がありますが、Python の実行とは大きく異なり、PHP はフロントエンドで出力する前に必ず処理全体を実行しますが、これは PHP の特性によって決まります。管理者に同期記録をリアルタイムで知らせるにはどうすればよいですか?
JavaScriptには関数がないのでしょうかsetTimeout
?タイムシェアリングとバッチ実行は、この要件を解決できるはずです。
2. 開発実践
(1) 外部jsライブラリの導入
<!--layui核心框架-->
<script src="static/layui/layui.js"></script>
<link rel="stylesheet" href="static/layui/css/layui.css" media="all">
(2) HTMLコンテナの作成
<div class="layui-fluid">
<!--提示说明-->
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-card">
<div class="layui-card-body" style="padding: 15px;text-align: center;">
<button class="layui-btn" id="sync"><i class="layui-icon layui-icon-time"></i> 队列同步</button>
<button class="layui-btn layui-btn-danger" id="cancelSync"><i
class="layui-icon layui-icon-logout"></i>停止同步
</button>
</div>
</div>
<div class="layui-card">
<div class="layui-card-header"><strong>提示说明:</strong></div>
<div class="layui-card-body">
<div class="layui-form-item">
<p>1.基于小鹅通token和学习记录API接口的限制,采用队列同步大数据量;</p>
<p class="x-red">2.同步前,请先同步用户小鹅通user_eid;</p>
<p>3.为减少小鹅通接口的使用频率,建议课程结束后,进展同步;</p>
<p>4.同步时,不能关闭窗口,请最小化后进行其他事件操作;</p>
</div>
</div>
</div>
</div>
</div>
<!--同步信息记录-->
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-card">
<div class="layui-card-header"><strong><span class="x-red" id="total"></span></strong></div>
<div class="layui-card-body">
<div class="layui-form-item" id="content"></div>
</div>
</div>
</div>
</div>
</div>
(3) キュー同期遅延実行
//同步队列
$("#sync").click(function () {
$.getJSON('./api/api.php?act=getStudyUser&token=3cab7ce4142608c0f40c785b5ab5ca24', {
course_id: course_id}, function (res) {
//console.log(res.data);
if (res.data.length == 0) {
$("#total").html("学习记录全部同步,无需重复操作。")
} else {
//禁止操作
$("#sync").attr("disabled", true).addClass("layui-btn layui-btn-primary");
//同步数据
outputArrayInBatch(res.data, 0, 90);
}
})
})
//停止执行
$("#cancelSync").click(function () {
location.reload();
})
//封装函数;
function outputArrayInBatch(arr, batchNum, interval) {
var startIndex = batchNum * interval; // 当前批次的起始索引
var endIndex = (batchNum + 1) * interval; // 当前批次的结束索引
if (startIndex > arr.length - 1) {
return;
}
if (endIndex > arr.length) {
endIndex = arr.length;
}
var batchArr = arr.slice(startIndex, endIndex);
//console.log(batchArr);
//计算剩余数量
var total = arr.length - startIndex;
//当结余数量不足完整批次时,自动清零
if (total <= interval) {
total = 0;
}
$("#total").html("总数量:" + total + "条记录,预计批次:" + Math.ceil(total / interval) + ",预计执行时间:" + parseFloat(total * 1 / interval / 60).toFixed(2) + "分钟");
$("#content").append("<p>第" + (batchNum + 1) + "批次,完成同步...<p>");
//同步记录并入库
$.ajax({
type: "post",
url: "./api/api.php?act=updateStudyRecord&token=3cab7ce4142608c0f40c785b5ab5ca24",
async: true,
data: {
course_id: course_id,
resource_id: resource_id,
batch_user_list: batchArr
},
dataType: "json",
success: function (res) {
console.log(res);
if (res.code.code == 2054) {
layer.msg('小鹅通API的请求短时间突增,稍等片刻重新同步', {
icon: 2, timeout: 2000}, function () {
location.reload();
})
return false;
}
},
error: function (err) {
console.log(err);
}
});
//延迟执行
setTimeout(function () {
outputArrayInBatch(arr, batchNum + 1, interval);
}, 1000); // 每隔1秒输出一批次
}
(4) 大量のデータを取得する
public function getStudyUser()
{
checkAdminAuth($_COOKIE['admin_roles'], '0', 1);//超管权限
global $db, $res;
dbc();
@$course_id = get_param('course_id');
$sql = "select sign_id,user_eid FROM " . $db->table('sign_2023') . " WHERE sync_mark = 0 AND user_eid <> ''";
$sql .= " AND course_id = " . $course_id;//必须指定课程ID
$sql .= " ORDER BY sign_id ASC";//升序执行
$row = $db->queryall($sql);
$res["data"] = $row;
die(json_encode_lockdata($res));
}
(5) PHP一括更新
- 学習記録を取得し、学習期間と学習の進捗状況を更新します。
- 学習記録がない場合は、更新の繰り返しを避けるために、更新されたかどうかのロゴを直接更新します。
//学习记录-同步至数据表
public function updateStudyRecord()
{
checkAdminAuth($_COOKIE['admin_roles'], '0', 1);//超管权限
global $db, $res;
dbc();
//1.获取参数
@$course_id = $_POST['course_id'];
@$resource_id = $_POST['resource_id'];
@$batch_user_list = $_POST['batch_user_list'];
/*2.同步获取小鹅通学习记录
* $res['xiaoE']['code'] 状态码
* $res['xiaoE']['data']['list'],返回小鹅通学习记录数组
* $res['xiaoE']['data']['list'][0]['learn_progress'],学习进度
* $res['xiaoE']['data']['list'][0]['stay_time'],学习时间,单位为秒
* $res['xiaoE']['data']['list'][0]['user_id'],小鹅通user_id
*/
$user_list = array();
for ($i = 0; $i < count($batch_user_list); $i++) {
$user_list[] = $batch_user_list[$i]['user_eid'];
}
require_once '../libs/Client.php';
$client = new Client();
$url = "https://api.xiaoe-tech.com/xe.user.leaning_record_by_resource.get/1.0.0";
$method = "post";
$data = array("search_max_learn_progress" => 0,
"stay_time" => 0,
"list" => $user_list);
$params = ["resource_id" => $resource_id, 'data' => $data];
$result = $client->request($method, $url, $params);
$dataList = $result['data']['list'];
//3.同步数据
$xiaoData_user = array();
if ($dataList) {
$xiaoData = array();
$len = count($dataList);
for ($j = 0; $j < $len; $j++) {
$xiaoData_user[] = $dataList[$j]['user_id'];
$xiaoData[] = array('user_eid' => $dataList[$j]['user_id'], 'learn_progress' => $dataList[$j]['learn_progress'], 'stay_time' => $dataList[$j]['stay_time'], 'sync_mark' => 1);
}
//4-1.有学习记录-同步数据
if (!empty($xiaoData)) {
$sql = batchUpdate($db->table('sign_2023'), $xiaoData, "user_eid", ["course_id" => $course_id, "sync_mark" => 0]);
$db->query($sql);
}
}
//4.无学习记录的-更改状态码
$noXiaoData = array();
$diffXiaoData = array_diff($user_list, $xiaoData_user);
for ($n = 0; $n < count($diffXiaoData); $n++) {
$noXiaoData[$n]['user_eid'] = $diffXiaoData[$n];
$noXiaoData[$n]['sync_mark'] = 1;
}
if (!empty($noXiaoData)) {
$sql = batchUpdate($db->table('sign_2023'), $noXiaoData, "user_eid", ["course_id" => $course_id, "sync_mark" => 0]);
$db->query($sql);
}
//输出状态
$res['code'] = $result;
$res["data"] = "课程同步学习记录,Status:OK";
die(json_encode_lockdata($res));
}
(6) Little Goose Cloud APIはリアルタイムでステータスを監視します
(7) フロントエンドコンソールの印刷テスト
4. 先端技術の学び方
世の中の物事は難しいのでしょうか、それとも簡単なのでしょうか?難しいこともやれば簡単、簡単なこともやらないと難しい。人にとって学ぶことは難しいですか、それとも簡単ですか? 学べば難しいことも簡単になり、学ばなければ簡単なことも難しくなります。
-
必要な基礎知識を習得する:高度な技術を学ぶためには、数学、コンピュータの基礎、プログラミング言語、アルゴリズムなど、必要な基礎知識を習得する必要があります。これらの基礎知識を習得することによってのみ、高度な技術をより深く理解し、学ぶことができます。
-
優れたプログラミングの本を読む: プログラミングの本を読むことは、高度なテクニックを学ぶのに非常に効果的な方法です。いくつかの古典的なプログラミング本を選択し、その本の概念やアイデアを理解することに集中することができます。
-
オープンソース プロジェクトに参加する: オープンソース プロジェクトに参加すると、多くの高度なテクノロジーを学ぶことができ、また、他の開発者とのコミュニケーションや協力を通じて貴重な経験を積むこともできます。いくつかのオープンソース プロジェクトを選択し、独自のコードやアイデアを貢献することができます。
-
高度なトレーニング コースへの参加: 高度なトレーニング コースへの参加は、高度な技術を学ぶための重要な方法であり、有名なオンライン コース プラットフォームまたはオフラインのトレーニング機関を選択して学習することができます。トレーニング プロセスでは、より専門的なガイダンスと学習教材が利用可能です。
-
自分でやる: 高度なテクニックを学ぶには、継続的な練習と応用が必要です。既存のソフトウェアを模倣したり、独自にプロジェクトを設計したりするなど、自分のレベルに適したプロジェクトを選択して開発および実践し、経験を積んで技術力を向上させることができます。
つまり、高度な技術を習得するには、より高度な技術力を習得するために、深い理解と思考を重視しながら、たゆまぬ学習と実践が必要です。
@リークタイムも時々あります