From ff844de60774a078de153d0fc590b333cc8f393f Mon Sep 17 00:00:00 2001 From: rayc Date: Mon, 22 Apr 2024 11:49:47 +0800 Subject: [PATCH] =?UTF-8?q?=20=E6=95=B4=E7=90=86=E7=8E=B0=E6=9C=89?= =?UTF-8?q?=E7=9A=84=E4=B8=A4=E4=B8=AAObsidian=E5=BA=93=E5=BE=97=E5=88=B0?= =?UTF-8?q?=E7=9A=84=E6=96=B0=E5=BA=93=EF=BC=8C=E5=90=8E=E7=BB=AD=E7=9A=84?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E9=83=BD=E5=9F=BA=E4=BA=8E=E8=BF=99=E4=B8=AA?= =?UTF-8?q?=E5=BA=93=E8=BF=9B=E8=A1=8C=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .obsidian/workspace.json | 71 ++-- Bug日志/Android - Bug记录.md | 3 + Bug日志/后端 -- Bug记录.md | 9 + README.md | 3 +- web/{ => css}/现代WEB布局.md | 0 web/js/`JS` `setTimeout` 和 `clearTimeout`.md | 9 + .../相机/Android Camera2 在预览时,录制视频.md | 355 ++++++++++++++++++ 博客/docker 安装 wordpress.md | 55 +++ 博文计划/待写博客.md | 1 + 各类IDE操作问题/Android Studio 相关.md | 28 ++ 各类IDE操作问题/VSCode 相关.md | 18 + 工作日志/X6 修改.md | 17 + 工作日志/服务器程序更新.md | 8 + 工具相关文档/Obsidian 使用笔记.md | 4 + 工具相关文档/VSCode/VSCode 文件嵌套.md | 17 + .../VSCode/VSCode 连接 云服务器.md | 0 工具相关文档/git/Git 笔记.md | 28 ++ 开发中/RayC后台开发日志.md | 19 + 开发中/Vue3 + 腾讯COS文件上传.md | 4 + 开发中/本地版本的cos图床.md | 4 + 开发愿望清单.md | 16 + 开发资源/SpotifyMusic.md | 3 + 文档编写/PRD/PRD 学习.md | 104 +++++ 日志检索.md | 49 ++- .../Java 实战训练营}/Netty/Netty 与 网络通信.md | 0 .../Java 实战训练营}/Netty/Netty 实现IM系统.md | 0 .../Java 实战训练营}/分布式服务/Dubbo.md | 0 .../分布式服务/Dubbo提供的各种服务引用机制.md | 0 .../分布式服务/Dubbo服务端与客户端通信原理.md | 0 .../Java 实战训练营}/分布式服务/RPC.md | 0 .../Java 实战训练营}/分布式服务/Zookeeper.md | 0 .../Java 实战训练营/分布式服务/分布式服务.md | 49 +++ .../Java 实战训练营}/分布式服务/分布式服务容错.md | 0 极客时间学习/Mini-Tomcat/2023-12-14.md | 0 极客时间学习/Nginx_geek/核心基础.md | 65 ++++ .../Vite + VUE3 + TS 配置ESLint + Prettier.md | 26 ++ 每日日志/vue3 + vite 不能使用 import.meta.md | 1 + 每日日志/vue3 + vite 中import path.md | 1 + 每日日志/腾讯 COS + CDN实现图床.md | 5 + 每日日志/腾讯 COS + Spring Boot 上传下载.md | 10 + 语言/Kotlin/2023-11-16.md | 8 + 语言/Rust/Rust学习笔记一.md | 22 ++ 43 files changed, 981 insertions(+), 32 deletions(-) create mode 100644 .gitignore create mode 100644 Bug日志/Android - Bug记录.md create mode 100644 Bug日志/后端 -- Bug记录.md rename web/{ => css}/现代WEB布局.md (100%) create mode 100644 web/js/`JS` `setTimeout` 和 `clearTimeout`.md create mode 100644 博客/Android/相机/Android Camera2 在预览时,录制视频.md create mode 100644 博客/docker 安装 wordpress.md create mode 100644 博文计划/待写博客.md create mode 100644 各类IDE操作问题/Android Studio 相关.md create mode 100644 各类IDE操作问题/VSCode 相关.md create mode 100644 工作日志/X6 修改.md create mode 100644 工作日志/服务器程序更新.md create mode 100644 工具相关文档/Obsidian 使用笔记.md create mode 100644 工具相关文档/VSCode/VSCode 文件嵌套.md rename VSCode 连接 云服务器.md => 工具相关文档/VSCode/VSCode 连接 云服务器.md (100%) create mode 100644 工具相关文档/git/Git 笔记.md create mode 100644 开发中/RayC后台开发日志.md create mode 100644 开发中/Vue3 + 腾讯COS文件上传.md create mode 100644 开发中/本地版本的cos图床.md create mode 100644 开发愿望清单.md create mode 100644 开发资源/SpotifyMusic.md create mode 100644 文档编写/PRD/PRD 学习.md rename {后端/极客时间Java实战 => 极客时间学习/Java 实战训练营}/Netty/Netty 与 网络通信.md (100%) rename {后端/极客时间Java实战 => 极客时间学习/Java 实战训练营}/Netty/Netty 实现IM系统.md (100%) rename {后端/极客时间Java实战 => 极客时间学习/Java 实战训练营}/分布式服务/Dubbo.md (100%) rename {后端/极客时间Java实战 => 极客时间学习/Java 实战训练营}/分布式服务/Dubbo提供的各种服务引用机制.md (100%) rename {后端/极客时间Java实战 => 极客时间学习/Java 实战训练营}/分布式服务/Dubbo服务端与客户端通信原理.md (100%) rename {后端/极客时间Java实战 => 极客时间学习/Java 实战训练营}/分布式服务/RPC.md (100%) rename {后端/极客时间Java实战 => 极客时间学习/Java 实战训练营}/分布式服务/Zookeeper.md (100%) create mode 100644 极客时间学习/Java 实战训练营/分布式服务/分布式服务.md rename {后端/极客时间Java实战 => 极客时间学习/Java 实战训练营}/分布式服务/分布式服务容错.md (100%) create mode 100644 极客时间学习/Mini-Tomcat/2023-12-14.md create mode 100644 极客时间学习/Nginx_geek/核心基础.md create mode 100644 每日日志/Vite + VUE3 + TS 配置ESLint + Prettier.md create mode 100644 每日日志/vue3 + vite 不能使用 import.meta.md create mode 100644 每日日志/vue3 + vite 中import path.md create mode 100644 每日日志/腾讯 COS + CDN实现图床.md create mode 100644 每日日志/腾讯 COS + Spring Boot 上传下载.md create mode 100644 语言/Kotlin/2023-11-16.md create mode 100644 语言/Rust/Rust学习笔记一.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..451c79a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +密码记录/ \ No newline at end of file diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 51d01a4..e84f0fe 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -37,7 +37,7 @@ "state": { "type": "markdown", "state": { - "file": "后端/极客时间Java实战/分布式服务/分布式服务容错.md", + "file": "README.md", "mode": "source", "source": false } @@ -49,14 +49,14 @@ "state": { "type": "markdown", "state": { - "file": "后端/极客时间Java实战/Netty/Netty 实现IM系统.md", + "file": "开发中/本地版本的cos图床.md", "mode": "source", "source": false } } } ], - "currentTab": 3 + "currentTab": 2 } ], "direction": "vertical" @@ -122,7 +122,7 @@ "state": { "type": "backlink", "state": { - "file": "后端/极客时间Java实战/Netty/Netty 实现IM系统.md", + "file": "README.md", "collapseAll": false, "extraContext": false, "sortOrder": "alphabetical", @@ -139,7 +139,7 @@ "state": { "type": "outgoing-link", "state": { - "file": "后端/极客时间Java实战/Netty/Netty 实现IM系统.md", + "file": "README.md", "linksCollapsed": false, "unlinkedCollapsed": true } @@ -162,7 +162,7 @@ "state": { "type": "outline", "state": { - "file": "后端/极客时间Java实战/Netty/Netty 实现IM系统.md" + "file": "README.md" } } } @@ -183,30 +183,43 @@ "command-palette:打开命令面板": false } }, - "active": "b0885c2694804173", + "active": "fcca90a4313bff23", "lastOpenFiles": [ - "后端/极客时间Java实战/Netty/Netty 与 网络通信.md", - "后端/极客时间Java实战/Netty/Netty 实现IM系统.md", - "后端/极客时间Java实战/分布式服务/Zookeeper.md", - "后端/极客时间Java实战/Netty", - "后端/极客时间Java实战/分布式服务", - "后端/极客时间Java实战/分布式服务/Dubbo服务端与客户端通信原理.md", - "后端/极客时间Java实战/分布式服务/分布式服务容错.md", - "后端/极客时间Java实战/分布式服务/Dubbo提供的各种服务引用机制.md", - "未分类日志.md", + "开发中/Vue3 + 腾讯COS文件上传.md", + "工具相关文档/git/Git 笔记.md", + "工具相关文档/git", + "工具相关文档/未命名.md", + "开发愿望清单.md", "日志检索.md", - "后端/极客时间Java实战/分布式服务/Dubbo.md", - "后端/极客时间Java实战/分布式服务/RPC.md", - "后端/极客时间Java实战", - "VSCode 连接 云服务器.md", - "README.md", - "web/现代WEB布局.md", - "运维", - "基础", - "后端", - "rust", - "android", - "web", - "Welcome.md" + "开发中/本地版本的cos图床.md", + "工具相关文档/VSCode/VSCode 连接 云服务器.md", + "工具相关文档/VSCode/VSCode 文件嵌套.md", + "工具相关文档/VSCode", + "未命名", + "工具相关文档/Obsidian 使用笔记.md", + "开发中/RayC后台开发日志.md", + "gitea.md", + "开发中", + "未分类日志.md", + "语言/Rust/Rust学习笔记一.md", + "博客/Android/相机/Android Camera2 在预览时,录制视频.md", + "博客/docker 安装 wordpress.md", + "Bug日志/后端 -- Bug记录.md", + "极客时间学习/Nginx_geek/核心基础.md", + "语言/Kotlin/2023-11-16.md", + "语言/未命名.md", + "语言/Kotlin", + "语言", + "极客时间学习/Java 实战训练营/分布式服务/分布式服务.md", + "极客时间学习/Java 实战训练营/分布式服务/分布式服务容错.md", + "文档编写/PRD", + "文档编写/PRD.md", + "文档编写", + "工具相关文档", + "UI学习/PS 学习/日志.md", + "web/js/`JS` `setTimeout` 和 `clearTimeout`.md", + "web/css", + "开发资源/SpotifyMusic.md", + "文档编写/PRD/PRD 学习.md" ] } \ No newline at end of file diff --git a/Bug日志/Android - Bug记录.md b/Bug日志/Android - Bug记录.md new file mode 100644 index 0000000..7c2e040 --- /dev/null +++ b/Bug日志/Android - Bug记录.md @@ -0,0 +1,3 @@ +```log + +``` \ No newline at end of file diff --git a/Bug日志/后端 -- Bug记录.md b/Bug日志/后端 -- Bug记录.md new file mode 100644 index 0000000..07a978e --- /dev/null +++ b/Bug日志/后端 -- Bug记录.md @@ -0,0 +1,9 @@ +## nginx 在https的server中访问http 的链接会失败 +当我们有一个申请了 `https` 证书的 `server` 时,如果这个 `server` 中的服务使用到了一个 `http` 的链接,会访问失败,例如: 我在一个 `vue` 的项目中室友了 `http` 的链接时,访问会失败 + +- 解决办法 + - 网上的解决方案好像都是对于nginx做代理的后端资源的解决方案,是在server当中添加一个响应头的配置,但我的是访问的同一个nginx下不同服务的资源,目前这种方案没有尝试过 + - 对使用 `http` 的 `server` 申请一个 `https` 的证书, 我使用的是 `certbot` 为 `nginx` 中指定的server 的域名申请证书 +``` +sudo certbot --nginx --nginx-server=/nginx_config_path -d the_domain_which_need_https +``` \ No newline at end of file diff --git a/README.md b/README.md index eb8e592..c82cbe9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ -Obsidian git 备份 - +个人知识库 \ No newline at end of file diff --git a/web/现代WEB布局.md b/web/css/现代WEB布局.md similarity index 100% rename from web/现代WEB布局.md rename to web/css/现代WEB布局.md diff --git a/web/js/`JS` `setTimeout` 和 `clearTimeout`.md b/web/js/`JS` `setTimeout` 和 `clearTimeout`.md new file mode 100644 index 0000000..94235f5 --- /dev/null +++ b/web/js/`JS` `setTimeout` 和 `clearTimeout`.md @@ -0,0 +1,9 @@ +最近学习vbenjs 发现的一个内存缓存中使用到的,具体的要参考vben的cache代码,这里只简单记录一下两个的使用办法, +`setTimeout` 其实是用来设置延时任务的函数,主要作用是在一段时间之后执行任务,会返回一个id,用来区分不同的任务 +```ts +const timeoutId = setTimeout(() => {}, expire) +``` +`clearTimeout` 用来清除使用setTimeout创建的延时任务, +```typescript +clearTimeout(timeoutId) +``` \ No newline at end of file diff --git a/博客/Android/相机/Android Camera2 在预览时,录制视频.md b/博客/Android/相机/Android Camera2 在预览时,录制视频.md new file mode 100644 index 0000000..6c456c6 --- /dev/null +++ b/博客/Android/相机/Android Camera2 在预览时,录制视频.md @@ -0,0 +1,355 @@ + +>写在前面: +> 1. 本文中的方法只是实现在 `Android` 中使用 `Camera2` 的情况下,实现一个在预览时,实现时评录制。本文中的代码只是一个demo,相机相关的流程需要再细化, +> 2. 另外,本文中的代码会存在一个问题,预览过程中会出现拉伸,原因是,本例中使用的是全局预览,需要再做适配,后面再补上. +> 3. 本文中的代码,并不规范,只是实现效果,许多地方的异常可能发生的地方,被直接忽略了 + +### 因为代码比较简单,所以直接给出代码: +```kotlin +class RecordVideoWhilePreviewClient( + val context: Context, + val mTextureView: AutoFitTextureView, + val filePath: String, + val stateListener: CameraStateListener +) { + companion object { + const val TAG = "RecordVideoWhilePreviewClient" + } + private var state: State = State.NEW + + val SENSOR_ORIENTATION_DEFAULT_DEGREES = 90 + private val SENSOR_ORIENTATION_INVERSE_DEGREES = 270 + private val DEAULT_ORIENTATIONS = SparseIntArray().apply { + append(Surface.ROTATION_0, 90) + append(Surface.ROTATION_90, 0) + append(Surface.ROTATION_180, 270) + append(Surface.ROTATION_270, 180) + } + private val INVERSE_ORIENTATIONS = SparseIntArray().apply { + append(Surface.ROTATION_0, 270) + append(Surface.ROTATION_90, 180) + append(Surface.ROTATION_180, 90) + append(Surface.ROTATION_270, 0) + } + + private var mBackgroundThread: HandlerThread = HandlerThread(TAG) + private lateinit var mBackHandler: Handler + @Volatile + private var mCameraDevice: CameraDevice? = null + @Volatile + private var mCameraCaptureSession: CameraCaptureSession? = null + @Volatile + private var mCaptureRequest: CaptureRequest.Builder? = null + @Volatile + private var mPreviewSurface: Surface? = null + @Volatile + private var mRecordSurface: Surface? = null + @Volatile + private var mMediaRecorder: MediaRecorder? = null + + @Volatile + private var mSensorOrientation: Int = 0 + @Volatile + private var mCameraOpenCloseLock = Semaphore(1) + private lateinit var mPreviewSize: Size + private lateinit var mVideoSize: Size + + private val mSurfaceTextureListener = object : TextureView.SurfaceTextureListener { + override fun onSurfaceTextureAvailable(texture: SurfaceTexture, width: Int, height: Int) { + openCamera(width, height) + } + + override fun onSurfaceTextureSizeChanged(texture: SurfaceTexture, width: Int, height: Int) { + configureTransform(width, height) + } + + override fun onSurfaceTextureDestroyed(texture: SurfaceTexture) = true + + override fun onSurfaceTextureUpdated(texture: SurfaceTexture) { + } } + + private val mCameraStateCallback = object : CameraDevice.StateCallback() { + override fun onOpened(device: CameraDevice) { + mCameraOpenCloseLock.release() + mCameraDevice = device + + if (!mTextureView.isAvailable) return + + try { + val texture = mTextureView.surfaceTexture!! +// texture.setDefaultBufferSize(, 720) + val previewSurface = Surface(texture) + mPreviewSurface = previewSurface + + setupMediaRecorder(1280, 720) + val recordSurface = mRecordSurface!! + + mCaptureRequest = device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW).apply { + addTarget(previewSurface) + addTarget(recordSurface) + } + + mCameraDevice?.createCaptureSession( + listOf(previewSurface, recordSurface), + mCaptureSessionStateCallback, + mBackHandler + ) + } catch (e: CameraAccessException) { + Log.e(TAG, "onOpened: ") + } + + } + + override fun onDisconnected(device: CameraDevice) { + mCameraOpenCloseLock.release() + device.close() + mCameraDevice = null + } + + override fun onError(device: CameraDevice, error: Int) { + mCameraOpenCloseLock.release() + device.close() + mCameraDevice = null + } + } + + private val mCaptureSessionStateCallback = object : CameraCaptureSession.StateCallback() { + override fun onConfigured(session: CameraCaptureSession) { + mCameraCaptureSession = session + + val camera = mCameraDevice ?: return + val previewSurface = mPreviewSurface ?: return + val recordSurface = mRecordSurface ?: return + + val captureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW).apply { + addTarget(previewSurface) + addTarget(recordSurface) + } + mCaptureRequest = captureRequest + session.setRepeatingRequest(captureRequest.build(), mCaptureCallback, mBackHandler) + } + + override fun onConfigureFailed(session: CameraCaptureSession) { + Log.e(TAG, "CameraCaptureSession.StateCallback -- onConfigureFailed: ") + } + } + + private val mCaptureCallback = object : CameraCaptureSession.CaptureCallback() { + override fun onCaptureCompleted( + session: CameraCaptureSession, + request: CaptureRequest, + result: TotalCaptureResult + ) { + super.onCaptureCompleted(session, request, result) + if (state == State.INITIALIZING) { + onStateChange(State.READY) + } + } + } + + init { + mBackgroundThread.start() + mBackHandler = Handler(mBackgroundThread.looper) + } + + @SuppressLint("MissingPermission") + fun openCamera(width: Int, height: Int) { + val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager + try { + if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { + throw RuntimeException("Time out waiting to lock camera opening") + } + val cameraId = manager.cameraIdList[0] + val characteristics = manager.getCameraCharacteristics(cameraId) + + val range21 = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); + + val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) + ?: throw RuntimeException("Cannot get available preview/video sizes") + + mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)!! + + + mVideoSize = Size(1280, 720) + mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture::class.java), width, height, Size(2400, 1080)); + + mTextureView.setAspectRatio(mPreviewSize.width, mPreviewSize.height) + configureTransform(width, height) + mMediaRecorder = MediaRecorder() + manager.openCamera(cameraId, mCameraStateCallback, null) + } catch (e: CameraAccessException) { + Log.e(RecordVideoWhilePreview.TAG, "openCamera: Cannot access the camera. \n$e") + } catch (e: NullPointerException) { + Log.e(RecordVideoWhilePreview.TAG, "onRequestPermissionsResult: 没得相机硬件") + } catch (e: InterruptedException) { + throw RuntimeException("Interrupted while trying to lock camera opening.") + } + } + + private fun setupMediaRecorder(width: Int, height: Int) { + var mediaRecorder = mMediaRecorder + if (mMediaRecorder == null) { + mediaRecorder = MediaRecorder() + } else { + mediaRecorder?.reset() + } + + val rotation = (context as Activity).windowManager.defaultDisplay.rotation + when (mSensorOrientation) { + SENSOR_ORIENTATION_DEFAULT_DEGREES -> { + mediaRecorder?.setOrientationHint(DEAULT_ORIENTATIONS.get(rotation)) + } + SENSOR_ORIENTATION_INVERSE_DEGREES -> { + mediaRecorder?.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation)) + } + } + + var recordSurface = mRecordSurface + if (recordSurface == null) { + recordSurface = MediaCodec.createPersistentInputSurface() + mRecordSurface = recordSurface + } + + mediaRecorder?.apply { + setInputSurface(recordSurface!!) + + setVideoSource(MediaRecorder.VideoSource.SURFACE) + setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) + + setOutputFile(filePath) + + setVideoEncodingBitRate(1280*720) + setVideoSize(width, height) + setVideoEncoder(MediaRecorder.VideoEncoder.H264) + + setCaptureRate(30.0) + setVideoFrameRate(30) + + prepare() + } + + mMediaRecorder = mediaRecorder + } + + private fun chooseOptimalSize( + choices: Array, + width: Int, + height: Int, + aspectRatio: Size + ): Size { + val w = aspectRatio.width + val h = aspectRatio.height + val bigEnough = choices.filter { + it.height == it.width * h / w && it.width >= width && it.height >= height + } + return if (bigEnough.isNotEmpty()) { + Collections.min(bigEnough, CompareSizeByArea()) + } else { + choices[0] + } + } + + private fun configureTransform(viewWidth: Int, viewHeight: Int) { + val rotation = (context as Activity).windowManager.defaultDisplay.rotation + val matrix = Matrix() + val viewRect = RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat()) + val bufferRect = RectF(0f, 0f, mPreviewSize.height.toFloat(), mPreviewSize.width.toFloat()) + val centerY = viewRect.centerY() + val centerX = viewRect.centerX() + + if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) { + bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()) + matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL) + val scale = Math.max( + viewHeight.toFloat() / mPreviewSize.height, + viewWidth.toFloat() / mPreviewSize.width + ) + with(matrix) { + postScale(scale, scale, centerX, centerY) + postRotate((90 * (rotation - 2)).toFloat(), centerX, centerY) + } + } + mTextureView.setTransform(matrix) + } + + private fun onStateChange(newState: State) { + state = newState + stateListener.onStateChange(state) + val state = when (state) { + State.NEW -> "STATE.NEW" + State.INITIALIZING -> "STATE.INITIALIZING" + State.READY -> "STATE.READY" + State.RECORDING -> "STATE.RECORDING" + State.COMPETE -> "STATE.COMPLETE" + } + context.showToast(state, Toast.LENGTH_SHORT) + } + + fun initialize() { + if (mTextureView.isAvailable) { + openCamera(mTextureView.width, mTextureView.height) + } else { + mTextureView.surfaceTextureListener = mSurfaceTextureListener + } + onStateChange(State.INITIALIZING) + } + + fun close() { + mBackgroundThread?.quitSafely() + try { + mBackgroundThread?.join() + } catch (e: InterruptedException) { + Log.e(TAG, "close: ") + } + mPreviewSurface?.release() + mRecordSurface?.release() + mMediaRecorder?.release() + mMediaRecorder = null + } + + fun startRecord() { + if (state != State.READY && state != State.COMPETE) return + + context.showToast("开始录像", Toast.LENGTH_SHORT) + setupMediaRecorder(1280, 720) + mMediaRecorder?.let { + it.start() + } + onStateChange(State.RECORDING) + } + + fun stopRecord() { + if (state != State.RECORDING) return + + context.showToast("结束录像", Toast.LENGTH_SHORT) + mMediaRecorder?.let { + it.stop() + it.reset() + } + onStateChange(State.COMPETE) + } + + interface CameraStateListener { + fun onStateChange(newState: State) + } + + enum class State { + NEW, + INITIALIZING, + READY, + RECORDING, + COMPETE, + } + + +} +``` + +### 需要注意的问题: +- 在创建 `MediaRecorder` 的时候,需要设置文件路径,这个时候,会在文件系统中生成一个空文件,等到录制的视频数据写入。 + - 但是我们上面的代码中,在 `CameraDevice.StateCallback` 的 `onOpened()` 中床创建 `CameraCaptureSession.StateCallback` 后面的过程中需要使用到 用来在 `MediaRecorder` 的 `Surface`, 需要提前 `设置好MediaRecorder` 并调用 `prepare` 不然预览会失败 + - 所以在第一次会创建一个文件,建议处理好文件的路径,本例目前只有一个文件路径 + +### 直接总结: +- 本文主要参考的是 [google官方的demo](https://github.com/android/camera-samples/tree/main/Camera2Basic), 官方的预览和录制视频是分开的,导致我一开始以为需要重新创建 `CameraCaptureSession`, 所以一开始,是在 *预览* 和 *视频录制* 之间进行切换,但是这个方法在 **切换** 的时候,会有明显的卡顿。 +- 最后选择了在预览的 `CameraCaptureSession` 中添加 `MediaRecorder` 用来录制的 `Surface`. 最后实现的效果还是相对理想的,但是会有一个瑕疵,预览的显示和最后录制得到的视频不一致,但是我需要的是最后的结果,屏幕预览的效果,后面再适配一下,是我可以接受的效果 diff --git a/博客/docker 安装 wordpress.md b/博客/docker 安装 wordpress.md new file mode 100644 index 0000000..05e181f --- /dev/null +++ b/博客/docker 安装 wordpress.md @@ -0,0 +1,55 @@ +- 使用 docker 运行一个 mysql, 可以自己再创建一个用户,授权之后,再提供给wordpress使用 +``` shell +sudo docker pull mysql +sudo docker run --name=mysql-wp -p 3306:3306 \ + -v /local/data/path:/var/lib/mysql \ + -e MYSQL_ROOT_PASSWORD=password \ + -d mysql +``` +- 安装运行wordpress +``` shell +sudo docker pull wordpress +sudo docker run --name wp -p 1080:80 \ + -e WORDPRESS_DB_HOST=mysql_tcp_link + -e WORDPRESS_DB_USER=root + -e WORDPRESS_DB_PASSWORD=password + -d wordpress +``` +- 访问服务器ip:1080端口,初始化wordpress。因为指定了数据库,成功的话会跳过数据的配置部分,后面的很简单,跟着提示完成即可 +- 安装主题,如果需要上传主题,需要修改wordpress的容器中的php的上传文件大小的配置 +```shell +# 默认情况下的上传文件大小是 2M, 可以在 WordPress 的 `媒体->上传文件` 的最下方会显示文件上传限制 +sudo docker exec -it `wp_container_id` bash # 进入wordpress容器 +cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini # +vim /usr/local/etc/php/php.ini +# 修改一下几个配置 +# memory_limit 500M +# upload_max_filesize=500M +# post_max_size=500M +``` +- 安装的主题是 [Sakurairo](https://github.com/mirai-mamori/Sakurairo) + 上传成功后可以自动安装,安装的时间不长,后面跟着[官方文档](https://docs.fuukei.org/first-step/theme-install/) 进行配置就可以了 +- `Nginx` 配置代理,配置之后,云服务器防火墙关闭1080端口使用域名进行访问,需要现在wordpress中吧域名相关的配置做修改 +```nginx +server { + server_name 域名; + listen 80; + + access_log logs/wp.access.log; + error_log logs/wp.error.log; + + location / { + proxy_pass http://127.0.0.1:1080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` +- https 配置 使用 certbot 引用let's encrypt 为网站申请证书,记得过期后再次申请 +``` +sudo certbot --nginx --nginx-server-root=`conf_path` -d 域名 +``` \ No newline at end of file diff --git a/博文计划/待写博客.md b/博文计划/待写博客.md new file mode 100644 index 0000000..f6dd747 --- /dev/null +++ b/博文计划/待写博客.md @@ -0,0 +1 @@ +- Socket通信系列 \ No newline at end of file diff --git a/各类IDE操作问题/Android Studio 相关.md b/各类IDE操作问题/Android Studio 相关.md new file mode 100644 index 0000000..2a7159d --- /dev/null +++ b/各类IDE操作问题/Android Studio 相关.md @@ -0,0 +1,28 @@ +### kotlin 下载慢 +- 2023-11-27 -- 国内下载kotlin的速度巨慢 + - 解决办法:修改settings.gradle.kts , 添加aliyun的依赖源,下载时间还是不短,但比原本的快 +```kotlin +pluginManagement { + repositories { + maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") } + maven { url = uri("https://maven.aliyun.com/repository/spring-plugin") } + maven { url = uri("https://maven.aliyun.com/repository/public") } + maven { url = uri("https://maven.aliyun.com/repository/google") } + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") } + maven { url = uri("https://maven.aliyun.com/repository/spring-plugin") } + maven { url = uri("https://maven.aliyun.com/repository/public") } + maven { url = uri("https://maven.aliyun.com/repository/google") } + google() + mavenCentral() + } +} +``` + diff --git a/各类IDE操作问题/VSCode 相关.md b/各类IDE操作问题/VSCode 相关.md new file mode 100644 index 0000000..074c225 --- /dev/null +++ b/各类IDE操作问题/VSCode 相关.md @@ -0,0 +1,18 @@ +### Java 运行的问题 +1. 在运行时,发现不能识别 主类的加载, + 解决办法: + - 方法一: 清除掉,`.vscode` 文件夹下的 `settings.json` 和 `lauch.json`, 退出重新加载,系统编译之后, 选择 `Fix and clean`, 之后再重新加载,问题就消失了,展示没找到其他的解决办法 + - 方法二: 在文件查看的侧边栏中,的Java Project菜单左侧,`...` 选择clean workspace,再重载一次项目,即可 + +### Vue + TS +1. 无法找到包: + - 问题描述:在Vue3 + TS 的环境中,`can not find modules` , 但是包是已经下载好依赖的 + - 解决办法:在`tsconfig.json` 中关闭js的strict + ``` + { + "compilerOptions": { + "strict": false, + "noImplicitThis": false + } + } + ``` \ No newline at end of file diff --git a/工作日志/X6 修改.md b/工作日志/X6 修改.md new file mode 100644 index 0000000..dd8ee85 --- /dev/null +++ b/工作日志/X6 修改.md @@ -0,0 +1,17 @@ +- 界面上方`title_bar` 移动到底部 + - 需要修改 activity_main.xml,在layout和layout-land + - 主题显示区域的 marginTop 修改为 marginBottom + - Menu也将 marginTop 修改为 marginBottom + - titleBar 修改 marginBottom + - 调整之后menu中唤起的 note_menu_popupwindow 和 measure_menu_popupwindow 需要把 `paddingTop` 修改为 `paddingBottom` +- titlebar小工具只显示 相机和电量 + - 需要修改 `fragment_main_titlebar` 和 `fragment_main_titlebar_820` `820` 是用于横屏模式 + - 把 `` 的 `other_param_h` 的根节点,设置为`visibility="gone"` + - 设置了上面的之后,相机图标会消失 + - 需要把相机显示的两个控件的设置为 `layout_width="40.0.dip"` +- Menu + TitleBar 背景颜色修改 + - 背景颜色直接修改,Menu和TitleBar的背景颜色是分开的 +- TGC 只留下TGC一个选项 + - 在 `activity_auxiliaire_setting.xml` 的 `rg_shortcut_button` 中除了 `tgc` 之外全部都 `visibility="gone"` +- Menu图标修改 + - 后期替换图片和xml文件 \ No newline at end of file diff --git a/工作日志/服务器程序更新.md b/工作日志/服务器程序更新.md new file mode 100644 index 0000000..54defc4 --- /dev/null +++ b/工作日志/服务器程序更新.md @@ -0,0 +1,8 @@ +## 12/31/2023 + +1. 安装Docker +2. 使用docker 安装mysql + mysql: 配置启动 +```shell +sudo docker run --name eacenic-mysql-v2 -e MYSQL_ROOT_PASSWORD=Eci85370978 -v /home/ecs-user/docker/mysql/data:/var/lib/mysql -p 3308:3306 -d mysql +``` \ No newline at end of file diff --git a/工具相关文档/Obsidian 使用笔记.md b/工具相关文档/Obsidian 使用笔记.md new file mode 100644 index 0000000..143a5ce --- /dev/null +++ b/工具相关文档/Obsidian 使用笔记.md @@ -0,0 +1,4 @@ + +### 使用Git作为同步工具 + +- [使用教程]([Obsidian通过github实现同步(Obsidian Git) - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/657924375)) \ No newline at end of file diff --git a/工具相关文档/VSCode/VSCode 文件嵌套.md b/工具相关文档/VSCode/VSCode 文件嵌套.md new file mode 100644 index 0000000..d018e11 --- /dev/null +++ b/工具相关文档/VSCode/VSCode 文件嵌套.md @@ -0,0 +1,17 @@ +在VSCode 的 vscode/settings.json 文件中添加如下规则: +```JSON +{ + // 控制相关文件嵌套展示 +  "explorer.fileNesting.enabled": true, +  // 默认不展开 +  "explorer.fileNesting.expand": false, +  // 嵌套的具体规则 +  "explorer.fileNesting.patterns": { +    "*.ts": "$(capture).test.ts, $(capture).test.tsx", +    "*.tsx": "$(capture).test.ts, $(capture).test.tsx", +    "*.env": "$(capture).env.*", +    "CHANGELOG.md": "CHANGELOG*", +    "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,README*,.npmrc,.browserslistrc", +    ".eslintrc.cjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,.stylelintrc.*" +} +``` \ No newline at end of file diff --git a/VSCode 连接 云服务器.md b/工具相关文档/VSCode/VSCode 连接 云服务器.md similarity index 100% rename from VSCode 连接 云服务器.md rename to 工具相关文档/VSCode/VSCode 连接 云服务器.md diff --git a/工具相关文档/git/Git 笔记.md b/工具相关文档/git/Git 笔记.md new file mode 100644 index 0000000..3368fef --- /dev/null +++ b/工具相关文档/git/Git 笔记.md @@ -0,0 +1,28 @@ +- `git fetch` + - `git fetch` 用来同步远程仓库和本地仓库中的git 信息,查看远程仓库的完整分支结构 + - `git fetch` 同步远程仓库的全部log信息 + - `git log origin` + `git fetch` 只会同步完整分支结构,不会直接将分支内容进行合并, + 所以不推荐 `git pull` +- `git push` + - `git push origin` 将当前分支push到远程仓库 + - `git push origin dev:dev` 可用于提交本地的新分支到远程分支 + +### commit 规范 +- 基本格式 + `(): subject` +- 说明 + - type (必填) + - feat -- 新功能 + - fix/to -- 修复bug + - docs -- 文档 + - style -- 格式 (不影响代码) + - refactor -- 重构(代码变动,没有修改功能,也不是修复bug) + - perf -- (优化, 替身性能,提升交互体验) + - test -- 增加测试 + - chore -- 构建过程或辅助工具的变动 + - revert -- 版本回退 + - merge -- 代码合并 + - sync 同步主线或分支的bug + - scope(可选) : 说明commit影响的范围 + - subject (必填):commit 目的的简短描述 \ No newline at end of file diff --git a/开发中/RayC后台开发日志.md b/开发中/RayC后台开发日志.md new file mode 100644 index 0000000..ad742c4 --- /dev/null +++ b/开发中/RayC后台开发日志.md @@ -0,0 +1,19 @@ +- 初始化项目 (2024--0-20) + > Spring Boot: `spring-boot-dependencies:3.1.8` + > druid: `druid-spring-boot-3-starter:1.2.21` + > mysql-connector-java: `mysql-connector-java:8.0.33` + > mybatis-plus: `mybatis-plus-boot-starter:3.5.5` + > hutool: `hutool-all:5.8.25` + > mapstruct: `mapstruct:1.5.5.Final mapstruct-jdk8:1.5.5.Final mapstruct-processor:1.5.5.Final` + + +- 开发用户管理模块 (目标暂时没有完成) + - 目标 + - 用户管理 + - 用户的创建和修改 + - 角色的增加和删除 + - 角色管理 + - 角色的创建和修改 + - 权限的增加和删除 + - 权限初始化时,写在数据库中 不可修改和变更,只允许被角色引用 + - \ No newline at end of file diff --git a/开发中/Vue3 + 腾讯COS文件上传.md b/开发中/Vue3 + 腾讯COS文件上传.md new file mode 100644 index 0000000..5298969 --- /dev/null +++ b/开发中/Vue3 + 腾讯COS文件上传.md @@ -0,0 +1,4 @@ +- 使用用户的永久密钥在用户管理中申请 +- ==开放cos的CORS==,设置CORS 操作范围,CORS 来源需要设置 +- 按照官方文档中即可上传成功 +- ==后面需要改进的地方==,创建SpringBoot COS 后台,用来生成临时密钥,通过临时密钥,事项文件上传 \ No newline at end of file diff --git a/开发中/本地版本的cos图床.md b/开发中/本地版本的cos图床.md new file mode 100644 index 0000000..0257a47 --- /dev/null +++ b/开发中/本地版本的cos图床.md @@ -0,0 +1,4 @@ +- 开通腾讯的COS服务 +- 创建Bucket +- 为Bucket设置CORS配置 +- 根据官网的 `Javascript SDK` 完成文件的增删改查 \ No newline at end of file diff --git a/开发愿望清单.md b/开发愿望清单.md new file mode 100644 index 0000000..6adc873 --- /dev/null +++ b/开发愿望清单.md @@ -0,0 +1,16 @@ +- 个人网站搭建 (先使用WordPress) -- 后面再开发 + - 先实现用户管理和腾讯COS文件上传 图床设置到cos中 +- 结合 cos 实现图床 -- 桌面端可用(或者web端也可以)先实现web端 +- 记账app +- 音乐app -- spotify-web-api-java 玩起来 +- python 做一个爬虫工具 +- python 用来处理表格,做自动化办公 +- 以下内容每天学习一点(知道其中三样) + - rust + - kotlin 协程 + - python + - nodejs (vue/react/koa) + - Java (Spring boot) + - 数据库(Mysql/MongoDB/Redis)(后面根据进度学习PostgreSQL) + - Android/SpringBoot/等周边框架 + - Electron \ No newline at end of file diff --git a/开发资源/SpotifyMusic.md b/开发资源/SpotifyMusic.md new file mode 100644 index 0000000..6cedb4f --- /dev/null +++ b/开发资源/SpotifyMusic.md @@ -0,0 +1,3 @@ +- clientID: `9c027f3e063a41949ae76e69f54bf6a8` +- ClientSecret: `f43c5aad266d4acfbe3805738c117a2c` +- \ No newline at end of file diff --git a/文档编写/PRD/PRD 学习.md b/文档编写/PRD/PRD 学习.md new file mode 100644 index 0000000..593afc5 --- /dev/null +++ b/文档编写/PRD/PRD 学习.md @@ -0,0 +1,104 @@ +## PRD 要素 +- 命名编码 +- 版本历史 +- 引言 +- 需求概述 +- 功能性说明 +- 非功能性说明 + +--- +### 文档标识 + +- 文档命名形式和编码 + XX 产品V1.0PRD_V1 + V1.0 是产品编号, PRD_V1 的V1 是PRD版本号 +- 版本历史 + - 版本号: V1 + - 文档编号:V1.0 + - 文档密级: + - 产品名: + - 编写人: + - 编写日期 +- 修订记录 + - 版本号: + - 修订人 + - 修订日期 + - 修订描述 +- 目录 -- 使用软件生成 +--- +### 引言 +- 引言 + - 产品背景 + - 说明该产品的研发的背景、市场趋势、发展前景(搜集并陈述事实,解释信息和活动、预测功能) + - 说明该铲平研发的目的、意义、里程碑式的建设(说明研发的优势) + - 预期读者 + - 该文档的阅读对象: 开发、测试、UI、产品 + - 产品规划 + - 说明该产品每一阶段的迭代目标, 开发及UI初期要达到的效果 + - 名词解释 + - 对文档中会出现的比较新的名称进行解释 + - 该文档的参考资料 + +--- +### 实现PRD文档的几种工具 + +- word +- 原型工具 + - xiaopiu + - Axure + - 墨刀 + - figma + - 慕客 + +--- +### 需求描述 + +- 业务流程 + - 组织架构图 -- 包含的模块、和子功能 + - 流程图 -- 泳道图(着重关注有判断逻辑和复杂业务逻辑的程序) +- 用户角色 + - 用户角色 + - 用户描述 +- 功能清单 + - 功能模块 + - 主要功能点 + - 优先级 决定开发的顺序 +- 运行环境 + - 软件运行环境 (浏览器、 操作系统) +- 产品规划 + - 对PRD中要开发的内容,给出关键里程碑,例如:需求评审通过的时间、开发完成的时间、上线时间 + - 描述产品可能存在的风险、比如性能瓶颈、没有解决的问题,用户不当使用的风险等等 + + +--- + +### 功能性需求说明 +- 简要说明:介绍此功能的用途,包括其来源或背景,能解决哪些问题 +- 场景描述,产品 在哪种情况下会被用户使用,就是用户场景模拟 + - 用户场景 + - 用户描述 +- 业务规则: + - 产品在开发时都有相应的业务规则,需要将跪着清晰的描述出来,让开发、测试人员明白,避免产生歧义 + - 业务规则必须是完整的、准确的,易懂的。 +- 原型图 (涉及到页面交互的部分) +- 前置条件:该需求实现依赖的前提条件。比如上传照片是,需要存有图像文件 +- 后置条件:操作引发的后续处理 + +--- + +### 非功能性需求 + +- 性能需求 + - 产品使用的并发性能、响应性能、安全性能、预期效果描述 + - 需求变更的计划 +- 运营需求 + - 产品上线后如何运营、目标受众是什么,建议的推广策略、问题反馈途径、风险监控、亮点宣传等等。以及与运营人员的协作方式 +- 风险分析: 针对可能出现的问题进行预判和预设解决方案 + +--- + +### 铲平设计原则 +- 不做高保真 +- 不写废话 +- 不重复 +- 把时间花在产品得核心驱动力上,减少对无用功的投入,降低单调重复的操作频次,才能保证高效产出有价值的牵引力 \ No newline at end of file diff --git a/日志检索.md b/日志检索.md index be67e6e..24dd3d7 100644 --- a/日志检索.md +++ b/日志检索.md @@ -1,2 +1,49 @@ ## 2024-03-08 -[[VSCode 连接 云服务器]] \ No newline at end of file +[[VSCode 连接 云服务器]] + +## 2024-01-08 +- 学习PS +- 修改X6(eci 工作,逆向,未完成) + +## 2024-01-11 +- [[腾讯 COS + CDN实现图床]] +- [[腾讯 COS + Spring Boot 上传下载]] + +## 2024-01-14 +- [[Vite + VUE3 + TS 配置ESLint + Prettier]] +- [[vue3 + vite 中import path]] +- [[vue3 + vite 不能使用 import.meta]] +- [[box-sizing border-box 失效]] + +## 2024-01-15 +- [[docker 安装 wordpress]] + +## 2024-01-17 +- [[Rust学习笔记一]] + +## 2024-01-19 +- [[Vue3 + 腾讯COS文件上传]] + +## 2024-01-20 +- [[本地版本的cos图床]] + +## 2024-02-20 +- [[`JS` `setTimeout` 和 `clearTimeout`]] +- JS 的 Reflect(反射) +- [[VSCode 文件嵌套]] + +## 2024-04-01 +[ViewModel 深度分析](https://juejin.cn/post/7344571269555126335?utm_source=gold_browser_extension) + +## 2024-04-01 +#### Git 出现错误 +> git bash报错fatal: detected dubious ownership in repository at的解决方法 +> 在Android Studio中使用commit时,遇到的错误 +> 原因:网上说,文件夹的所有者和当前用户不一致 +> 解决办法:git bash中执行 +> `git config --global --add safe.directory` + + +## 2024-04-12 +> Android 中的Service是在app的主线程中进行执行的,如果在主线程中执行了耗时操作,可能导致ANR + diff --git a/后端/极客时间Java实战/Netty/Netty 与 网络通信.md b/极客时间学习/Java 实战训练营/Netty/Netty 与 网络通信.md similarity index 100% rename from 后端/极客时间Java实战/Netty/Netty 与 网络通信.md rename to 极客时间学习/Java 实战训练营/Netty/Netty 与 网络通信.md diff --git a/后端/极客时间Java实战/Netty/Netty 实现IM系统.md b/极客时间学习/Java 实战训练营/Netty/Netty 实现IM系统.md similarity index 100% rename from 后端/极客时间Java实战/Netty/Netty 实现IM系统.md rename to 极客时间学习/Java 实战训练营/Netty/Netty 实现IM系统.md diff --git a/后端/极客时间Java实战/分布式服务/Dubbo.md b/极客时间学习/Java 实战训练营/分布式服务/Dubbo.md similarity index 100% rename from 后端/极客时间Java实战/分布式服务/Dubbo.md rename to 极客时间学习/Java 实战训练营/分布式服务/Dubbo.md diff --git a/后端/极客时间Java实战/分布式服务/Dubbo提供的各种服务引用机制.md b/极客时间学习/Java 实战训练营/分布式服务/Dubbo提供的各种服务引用机制.md similarity index 100% rename from 后端/极客时间Java实战/分布式服务/Dubbo提供的各种服务引用机制.md rename to 极客时间学习/Java 实战训练营/分布式服务/Dubbo提供的各种服务引用机制.md diff --git a/后端/极客时间Java实战/分布式服务/Dubbo服务端与客户端通信原理.md b/极客时间学习/Java 实战训练营/分布式服务/Dubbo服务端与客户端通信原理.md similarity index 100% rename from 后端/极客时间Java实战/分布式服务/Dubbo服务端与客户端通信原理.md rename to 极客时间学习/Java 实战训练营/分布式服务/Dubbo服务端与客户端通信原理.md diff --git a/后端/极客时间Java实战/分布式服务/RPC.md b/极客时间学习/Java 实战训练营/分布式服务/RPC.md similarity index 100% rename from 后端/极客时间Java实战/分布式服务/RPC.md rename to 极客时间学习/Java 实战训练营/分布式服务/RPC.md diff --git a/后端/极客时间Java实战/分布式服务/Zookeeper.md b/极客时间学习/Java 实战训练营/分布式服务/Zookeeper.md similarity index 100% rename from 后端/极客时间Java实战/分布式服务/Zookeeper.md rename to 极客时间学习/Java 实战训练营/分布式服务/Zookeeper.md diff --git a/极客时间学习/Java 实战训练营/分布式服务/分布式服务.md b/极客时间学习/Java 实战训练营/分布式服务/分布式服务.md new file mode 100644 index 0000000..75aea14 --- /dev/null +++ b/极客时间学习/Java 实战训练营/分布式服务/分布式服务.md @@ -0,0 +1,49 @@ +## 分布式服务体系 +#### 单体系统的问题 +1. 业务扩展性 -- 任何业务的调整都需要发布整个系统 +2. 性能伸缩性 -- 动态扩容对单体系统而言效率低下 +3. 代码复杂度 -- 修改一处代码容易引发连锁问题 + +- ##### 系统扩展性 + 当前系统的业务需求发生变化时,对现在的系统改动程度的一种控制能力。改动程度越大,扩展性越差 +- ##### 伸缩性 + 伸缩性,对系统性能的一种控制能力。如果通过简单扩容就能确保系统的性能得到等比例的提升,就认为系统具备较好的伸缩性。 +#### 分布式系统 +将整个系统拆分成多个能够独立运行的服务,这些服务再物理机上是隔离的,相互之间基于网络进行通信和协调 + +#### 单体系统的拆分策略 +- 纵向拆分:根据业务内容进行拆分,每一个服务都是单独的业务 +- 横向拆分:粒度更细,复用和组合业务能力 +#### 分布式系统的固有特性 +- 网络传输的三态性 -- 成功、失败、超时 +- 请求的容错性 -- 调用链路上的异常扩散,雪崩效应 +- 系统的异构性 -- 多种不同的技术体系 +- 数据的一致性 -- 传统的事务机制无法生效 (什么是传统的事务机制) +#### 分布式核心技术点 +- 可用 -- 降级、限流、集群和负载均衡 +- 扩展 -- SPI机制、异步消息 +- 性能 -- 异步化、资源重用 +- 治理 -- 服务注册与发现机制 +#### 分布式系统组成结构 +- 功能性组件 + - 网络通信 + - 序列化 + - 传输协议 + - 服务调用 +- 非功能性组件 + - 服务治理 + - 服务路由 + - 服务容错 + - 服务监控 + + + + + +## RPC架构 +`remote process call`, 远程过程调用,分布式的基础 +分布式系统基本功能组件: +- 网络通信 +- 序列化/反序列化 +- 传输协议 +- 服务调用 \ No newline at end of file diff --git a/后端/极客时间Java实战/分布式服务/分布式服务容错.md b/极客时间学习/Java 实战训练营/分布式服务/分布式服务容错.md similarity index 100% rename from 后端/极客时间Java实战/分布式服务/分布式服务容错.md rename to 极客时间学习/Java 实战训练营/分布式服务/分布式服务容错.md diff --git a/极客时间学习/Mini-Tomcat/2023-12-14.md b/极客时间学习/Mini-Tomcat/2023-12-14.md new file mode 100644 index 0000000..e69de29 diff --git a/极客时间学习/Nginx_geek/核心基础.md b/极客时间学习/Nginx_geek/核心基础.md new file mode 100644 index 0000000..ba64d89 --- /dev/null +++ b/极客时间学习/Nginx_geek/核心基础.md @@ -0,0 +1,65 @@ + + +### 进程结构 + +- 单进程结构 +- 多进程结构(默认配置-- 更适合工作环境):多线程情况下,一个线程(请求)引起的错误会影响整个进程,保证高可用性(一个请求失败后,不影响其他请求) + - woker 进程 + - cache 进程 +> 1. master 进程 +> 2. work 进程 +> 3. Cache Manager +> 4. Cache Loader +> Master 进程用来管理work进程, work进程用来处理实际的请求,Cache Loader 用来加载缓存,Cache Manager 用来管理缓存 +> work进程需要使用cache进程 +> 在 配置work 进程数时,需要把work进程数配置到和CPU核心数一样,还要为每个work进程绑定核心, 提高work进程的处理的能力和稳定性。 + +### 进程管理 -- 信号 +#### Master 进程 +1. 监控 Worker 进程 + - CHLD -- worker 进程结束的时候会向master 发送 `CHLD` 信号,用来监听worker进程,在必要的时候拉起worker进程 +2. 管理 Worker 进程 +3. 接收信号 + - TERM, INT -- 理解停止 + - QUIT -- 不影响用户的情况下,停止 + - HUP -- 重载配置文件 + - USR1 -- 重新打开日志文件, 做日志文件的切割 + - USR2 -- + - WINCH +> USR2 和 WINCH 只能通过进程号 直接向master进程发送,其他的可以使用nginx的命令行实现 + +#### Worker 进程 -- 通常不给worker进程发送信号 +1. 接收信号 + - TREM, INT + - QUIT + - USR1 + - WINCH + +#### Nginx 命令行 +- reload: HUP +- reopen: USR1 +- stop: TERM +- quit: QUIT + + +### reload 流程 +- 向master 发送 HUP 信号 +- master 检查配置文件语法正确性 +- master 打开新的监听端口 +- master 用 新的配置文件 启动新的worker进程 +- master 向老的worker子进程发送发动QUIT信号 +- 老的worker进程关闭监听句柄,处理完当前连接后结束进程(超时会被强制退出, 时间是由master进程决定的) + + +### 热升级流程 + + +### worker进程优雅的结束 +1. 设置定时器 -- worker_shutdown_timeout +2. 关闭监听句柄 -- 不再处理新的连接 +4. 关闭空闲连接 -- 从线程池中处理 +5. 在循环中等待全部连接关闭 (或者超时,被强制关闭) +6. 退出进程 + +### 网络收发 与 Nginx 事件间的关系 + diff --git a/每日日志/Vite + VUE3 + TS 配置ESLint + Prettier.md b/每日日志/Vite + VUE3 + TS 配置ESLint + Prettier.md new file mode 100644 index 0000000..c6f274b --- /dev/null +++ b/每日日志/Vite + VUE3 + TS 配置ESLint + Prettier.md @@ -0,0 +1,26 @@ +项目基本环境 +> `vite@5.0.8` +> `vue@3.3.11` +> `typescript@5.2.2` +> `eslint@8.56.0` +> `prettier@3.2.2` +- 创建项目 +```shell +pnpm create vite@latest project-name -- --template vue-ts +``` +- 配置 `ESLint` + - 安装ESLint + ```shell + pnpm add -D eslint + ``` + - 配置 ESLint + ``` + npx eslint --init + ``` + 选择的时候,直接选就可以了,最后默认安装推荐依赖即可 +- 配置 Prettier + - 安装 + ``` + pnpm add -D prettier + ``` + 然后添加 `.prettierc.json` 文件保存格式信息 diff --git a/每日日志/vue3 + vite 不能使用 import.meta.md b/每日日志/vue3 + vite 不能使用 import.meta.md new file mode 100644 index 0000000..3da22e0 --- /dev/null +++ b/每日日志/vue3 + vite 不能使用 import.meta.md @@ -0,0 +1 @@ +VSCode 的bug,关闭VSCode,然后重启就可以了 \ No newline at end of file diff --git a/每日日志/vue3 + vite 中import path.md b/每日日志/vue3 + vite 中import path.md new file mode 100644 index 0000000..2b698de --- /dev/null +++ b/每日日志/vue3 + vite 中import path.md @@ -0,0 +1 @@ +需要安装 `@types/node` 的依赖 \ No newline at end of file diff --git a/每日日志/腾讯 COS + CDN实现图床.md b/每日日志/腾讯 COS + CDN实现图床.md new file mode 100644 index 0000000..e1d67d2 --- /dev/null +++ b/每日日志/腾讯 COS + CDN实现图床.md @@ -0,0 +1,5 @@ +通过 `COS` 和 `CND` 实现一个基本的图床 +- 开通之后创建 `Bucket` +- 开通`CDN` 创建域名,这里用的自己服务器的域名的二级域名(在腾讯注册的,直接用就行,其他的域名不清楚),一路默认配置,就可以直接用, + - 设置了一个上线 + - 设置了智能压缩,但是没有生效 diff --git a/每日日志/腾讯 COS + Spring Boot 上传下载.md b/每日日志/腾讯 COS + Spring Boot 上传下载.md new file mode 100644 index 0000000..84f3c2b --- /dev/null +++ b/每日日志/腾讯 COS + Spring Boot 上传下载.md @@ -0,0 +1,10 @@ +- 需要引入 `cos` 的 `SDK` +```xml + + com.qcloud +    cos_api + 5.6.155 + +``` +- 需要使用 `api` 的 的 `accessKey` 和 `secretKey` ,使用临时密钥失败,不知道是不是没申请对,一直是 `InvalidAccessKey` + diff --git a/语言/Kotlin/2023-11-16.md b/语言/Kotlin/2023-11-16.md new file mode 100644 index 0000000..e17d5bd --- /dev/null +++ b/语言/Kotlin/2023-11-16.md @@ -0,0 +1,8 @@ +## Bug: +### Kotlin 在 做 val 声明的对象 作为参数传递时,对象内的属性的值如果被修改,则原有对象的值也会产生变化,反之亦然。 + ### 今天遇到的问题时, + - 我在`FragmentA` 中将 `ObjectA` 写入到 `FragmentA` 和 `FragmentB` 两个页面共享的 一个 `ViewModel` 中, + - 然后修改原来在 `ObjectA` 的属性值,之后进入到 `FragmentB` 中 (这么做的原因是因为每一次进入`FragmentA` 都需要 `ObjectA` 的属性值得到更新,但是放在启动 `FragmentB` 之前就直接清除了,这么做,导致了,后面的问题) + - 最后在 `FragmentB` 中获取到错误的值 + #### 解决办法: + - 把 `val` 改成 `var`, 或者修改 `Object` 清除属性值的时间点,把清除操作放到进入`FragmentA` 开始运行时的回调当中 diff --git a/语言/Rust/Rust学习笔记一.md b/语言/Rust/Rust学习笔记一.md new file mode 100644 index 0000000..2b0bdb0 --- /dev/null +++ b/语言/Rust/Rust学习笔记一.md @@ -0,0 +1,22 @@ +## 基础扫盲 +- 基本数据类型 +- 语法 +- 复合类型 +- 分支,流程控制(分支、循环) +- 函数 + 模块 +- 测试 + +## 所有权 -- Rust 的地基 +![所有权 1](https://static001.geekbang.org/resource/image/7f/37/7f78de64bb2756d7137124ce18886a37.jpg?wh=2178x1697) +主要需要把握几个点 +- 变量的可变与不可变的区别 +- 变量的作用域 +- 变量对应的资源的所有权 所有权相关的 `Copy` 和 `Move` 两个概念,函数传参,如果不使用引用,会发生所有权转移,需要再函数最后交回所有权(不绝对) + + +![引用2](https://static001.geekbang.org/resource/image/41/8d/41cf986d8da00cce53436aba30e89e8d.jpg?wh=1732x1398) +需要把握的几个点: +- 引用存在的意义 +- 可变引用和不可变引用 +- 可变借用和不可变借用的作用域冲突问题,借用的几个重要原则 +- 使用借用作为函数形参的 \ No newline at end of file