模拟电路 vs 数字电路

核心区别:信号形式不同

模拟电路 (Analog)数字电路 (Digital)
信号连续变化,电压/电流可以是任意值离散状态,只有 0 和 1 两种(或几种有限状态)
信息在哪在信号的大小、幅度、频率在 0 和 1 的组合与顺序
抗干扰差,噪声会直接叠加到信号上强,只要电压还在"高/低"区间内,就不会误判
例子音响功放、麦克风前置放大、收音机、电源电脑、手机芯片、单片机、LED 数码管驱动

下面给你一份3个月冲腰围 90 → 86 cm的「运动和训练清单」。
目标很明确:不追求花哨,只追求稳定执行、能坚持、能让腰围下降。

Step-by-step guides for exploring codebases, fixing bugs, refactoring, testing, and other everyday tasks with Claude Code.

先在 GitHub 上创建一个空的 Repository(仓库),创建时不要勾选“Initialize this repository with a README”等选项。保持仓库为空,可以避免和本地代码产生冲突。

如果你要考虑数据一致性或者线程安全的问题, 能承载 2 个线程就是解决了高并发的问题。

public class NioFileDemo {
    public static void main(String[] args) {
        NioFileDemo demo = new NioFileDemo();
        demo.writeFile();
        demo.readFile();
    }

    // 使用 NIO 写入文件
    public void writeFile() {
        Path path = Paths.get("logs/itwanger/paicoding.txt");
        try {
            FileChannel fileChannel = FileChannel.open(path, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE));

            ByteBuffer buffer = StandardCharsets.UTF_8.encode("学编程就上技术派");
            fileChannel.write(buffer);

            System.out.println("写入完成");
            fileChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 使用 NIO 读取文件
    public void readFile() {
        Path path = Paths.get("logs/itwanger/paicoding.txt");
        try {
            FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ);
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            int bytesRead = fileChannel.read(buffer);
            while (bytesRead != -1) {
                buffer.flip();
                System.out.println("读取的内容: " + StandardCharsets.UTF_8.decode(buffer));
                buffer.clear();
                bytesRead = fileChannel.read(buffer);
            }

            fileChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

package com.example.msdksample.utils

import android.util.Log

class Logger(private val tag: String) {
    fun info(message: String) {
        Log.i(tag, message)
    }

    fun error(message: String, throwable: Throwable? = null) {
        if (throwable != null) {
            Log.e(tag, message, throwable)
        } else {
            Log.e(tag, message)
        }
    }

    fun debug(message: String) {
        Log.d(tag, message)
    }

    fun warn(message: String) {
        Log.w(tag, message)
    }
}

package com.example.msdksample.activity

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.msdksample.MyApplication
import com.example.msdksample.R
import com.google.android.material.snackbar.Snackbar

class MainActivity : AppCompatActivity() {

    private lateinit var tvAppActivation: TextView
    private lateinit var btnFlightController: Button

    // Use enum for better type safety
    private enum class ActivationState {
        ACTIVATED,
        NOT_ACTIVATED
    }

    private var appActivationState: ActivationState = ActivationState.NOT_ACTIVATED

    // BroadcastReceiver to monitor application registration and product connection
    private val registerReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                MyApplication.REGISTER_SUCCESS -> {
                    appActivationState = ActivationState.ACTIVATED
                    updateActivationUI()
                    showMessage(getString(R.string.register_success))
                }
                MyApplication.REGISTER_FAILURE -> {
                    val errorMessage = intent.getStringExtra("error_message") ?: getString(R.string.unknown_error)
                    appActivationState = ActivationState.NOT_ACTIVATED
                    updateActivationUI()
                    showMessage(getString(R.string.register_failure, errorMessage))
                }
                MyApplication.PRODUCT_CONNECT -> {
                    showMessage(getString(R.string.product_connect))
                }
                MyApplication.PRODUCT_DISCONNECT -> {
                    showMessage(getString(R.string.product_disconnect))
                }
                MyApplication.PRODUCT_CHANGED -> {
                    showMessage(getString(R.string.product_changed))
                }
            }
        }
    }

    private var isReceiverRegistered = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initViews()
        checkAndRequestPermissions()
    }

    private fun initViews() {
        tvAppActivation = findViewById(R.id.tv_status_application)
        btnFlightController = findViewById(R.id.btn_flight_controller)

        btnFlightController.setOnClickListener {
            if (appActivationState == ActivationState.ACTIVATED) {
                val intent = Intent(this, FlightActivity::class.java)
                startActivity(intent)
            } else {
                showMessage(getString(R.string.app_not_activated))
            }
        }

        updateActivationUI()
    }

    private fun updateActivationUI() {
        val statusText = when (appActivationState) {
            ActivationState.ACTIVATED -> getString(R.string.activation_status_activated)
            ActivationState.NOT_ACTIVATED -> getString(R.string.activation_status_not_activated)
        }
        tvAppActivation.text = getString(R.string.activation_status_label, statusText)
    }

    override fun onStart() {
        super.onStart()
        registerBroadcastReceiver()
    }

    override fun onStop() {
        unregisterBroadcastReceiver()
        super.onStop()
    }

    private fun registerBroadcastReceiver() {
        if (!isReceiverRegistered) {
            val filter = IntentFilter().apply {
                addAction(MyApplication.REGISTER_SUCCESS)
                addAction(MyApplication.REGISTER_FAILURE)
                addAction(MyApplication.PRODUCT_CONNECT)
                addAction(MyApplication.PRODUCT_DISCONNECT)
                addAction(MyApplication.PRODUCT_CHANGED)
            }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                registerReceiver(registerReceiver, filter, Context.RECEIVER_NOT_EXPORTED)
            } else {
                registerReceiver(registerReceiver, filter)
            }

            isReceiverRegistered = true
        }
    }

    private fun unregisterBroadcastReceiver() {
        if (isReceiverRegistered) {
            try {
                unregisterReceiver(registerReceiver)
                isReceiverRegistered = false
            } catch (e: IllegalArgumentException) {
                // Receiver was already unregistered
            }
        }
    }

    /* Permission Handling */

    private fun getRequiredPermissions(): Array<String> {
        val basePermissions = mutableListOf(
            android.Manifest.permission.RECORD_AUDIO,
            android.Manifest.permission.INTERNET,
            android.Manifest.permission.CHANGE_WIFI_STATE,
            android.Manifest.permission.ACCESS_WIFI_STATE,
            android.Manifest.permission.ACCESS_NETWORK_STATE,
            android.Manifest.permission.CAMERA,
            android.Manifest.permission.ACCESS_COARSE_LOCATION,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        )

        // Only add storage permissions for older Android versions
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
            basePermissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
            basePermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE)
        }

        return basePermissions.toTypedArray()
    }

    private fun checkAndRequestPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!hasAllPermissions()) {
                requestAllPermissions()
            } else {
                proceedWithAppFunctionality()
            }
        } else {
            proceedWithAppFunctionality()
        }
    }

    private fun hasAllPermissions(): Boolean {
        return getRequiredPermissions().all {
            ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun requestAllPermissions() {
        ActivityCompat.requestPermissions(this, getRequiredPermissions(), PERMISSIONS_REQUEST_CODE)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        if (requestCode == PERMISSIONS_REQUEST_CODE) {
            if (grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
                proceedWithAppFunctionality()
            } else {
                showMessage(getString(R.string.permissions_required))
            }
        }
    }

    private fun proceedWithAppFunctionality() {
        showMessage(getString(R.string.permissions_granted))
    }

    private fun showMessage(message: String) {
        // Use Snackbar instead of Toast for better UX
        Snackbar.make(
            findViewById(android.R.id.content),
            message,
            Snackbar.LENGTH_SHORT
        ).show()
    }

    companion object {
        private const val PERMISSIONS_REQUEST_CODE = 102
    }
}

在我们开始之前,先要弄清楚我们在搭建一个用于做什么的 C/C++ 环境。一个 C/C++ 环境最基础的要求是舒适的代码编写体验(包括智能提示、代码高亮等)以及便利的编译调试功能(包括源码编译、链接、生成可执行文件等)。我们既可以分别配置代码编辑器和编译器来完成环境的搭建,也可以直接选用集成开发环境(IDE,Integrated Development Environment) 来进行程序开发。

当你学习怎样去建立一个电路时,面包板是最基本、最简单的元件之一。由于板子上有很多小插孔,各种电子元器件可根据需要任意插入或拔出,免去了焊接的工序,节省了电路的组装时间,且元件可以重复使用,非常适合电子电路的组装、调试和训练。