Normal view

There are new articles available, click to refresh the page.
Today — 9 April 2025Curiosity

面试遇到怪题,大家有什么思路吗

By: tenserG
8 April 2025 at 22:04
tenserG:

分红包,上限是总奖金 30%,下线 1 元,输入奖金总数 m 和人数 n ,输出一个列表表示每个人红包

思路一 传统分红包办法,1 到 n-1 人领随机生成 range ( 1 ,0.3*m )的红包,最后一个人拿到剩余,但是这样最后一个人可能会超出上下限

思路二 下限当作保底,先每个人分 1 元保底,剩下奖金池是 m-n ,1 到 n-1 人领取随机生成 range ( 0 ,0.3*m-1 )的红包,最后一个人拿到剩余,这样保证了下限,但是上限还是会超,如果前面 n-1 个人没分完总奖金的( 1-30%)=70%,剩下一个人就会超过上限 30%

到这里基本时间就到了,感觉凉凉,复盘时候感觉无论怎么随机分,都没法保证刚好分完

思路三是搜索到的一种解法,先计算平均值 avg ,每个人两两一对,领取 avg+-random 的红包,如果人数是单数,则返回平均值。这样能保证分完,不过额真的随机么。

原来我今天才知道 Orbstack 正确的使用姿势

By: sinotw
9 April 2025 at 12:26
sinotw:

以前一直是先到 Docker 下载最新版安装,然后再安装 Orbstack ,运行没什么问题,但是每次使用,都需要启动 Docker ,连带着就启动了那个笨重的 Docker Desktop 。而且貌似这样使用 Docker Desktop 中的 Image 和 Orbstack 中的不完全一致。

今天看着这个 Docker Desktop 越发不顺眼,就卸载了,然后

brew install docker

然后

brew services start docker

但是失败了。

经过一番搜索,了解了原来

brew install docker

安装的只是 Docker 的 cli (不全面,但大致就是这个意思),还需要配合 Docker 引擎使用,Orbstack 根据 Docker 开放的技术标准实现了自己的引擎。 只需要

echo 'export DOCKER_HOST="unix:///Users/xxxxx/.orbstack/run/docker.sock"' >> ~/.zshrc
source ~/.zshrc

然后执行 Docker 的各种命令就和以前完全一样了,但是终于不用面对那个臃肿的 Docker Desktop 了。

一通折腾下来,终于清爽了。

[PDF 转 Markdown]做了一款免费的在线 PDF 转 Markdown 工具

By: mcutown
9 April 2025 at 12:14
mcutown:

Gemini 系列的大模型多模态能力在最近两个版本( 2.0flash/2.5pro )有了明显的提升;于是本着干中学的态度,写了一个 PDF 转 Markdown 的在线工具

  • 支持扫描件/公式/表格等多种文档内容格式
  • 支持多栏论文按阅读顺序解析
  • 支持文档内图像提取
  • 支持提取并翻译为目标语言

以下为在线地址,无需登录即可使用:

pdf2md.aitranspdf.com

为控制成本,使用时需填入授权码,下方分享一批授权码

455ae82d7e4a427b86fd19c733da01d4,
83411d78e2a54cce99a5a4d7394c884d,
f90f8ace02fc43079a44afac727cf39d,
ee509e4d307c4c64b48833e00cbae9fa,
35cdc2be66cb41138bf33b6c94c9a55a,
ad68df9f8fa64c84b1cab4463671d935,
59974330e6d346bca8638221d33da4ce

同时贴上提取相关的 python 核心代码,欢迎大佬指正优化

from google import generativeai as genai
import os
from pathlib import Path
from typing import List, Dict
import base64
import mimetypes
import time
from tqdm import tqdm
import tempfile
import logging
from concurrent.futures import ThreadPoolExecutor, as_completed
import fitz  # PyMuPDF
import uuid
import atexit
import json


class PDFToMarkdownConverter:
    def __init__(self, api_key: str, api_endpoint: str = None, chunk_size: int = 20, max_retries: int = 3):
        """
        初始化转换器
        :param api_key: Gemini API 密钥
        :param api_endpoint: 代理服务器地址
        :param chunk_size: 每个分块的页数
        :param max_retries: 最大重试次数
        """
        # 设置日志
        logging.basicConfig(level=logging.INFO)
        self.logger = logging.getLogger(__name__)

        # 基础配置
        self.chunk_size = chunk_size
        self.max_retries = max_retries

        # 创建临时目录
        self.temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'temp')
        os.makedirs(self.temp_dir, exist_ok=True)
        self.logger.info(f"临时文件目录: {self.temp_dir}")

        # 设置 API 端点
        if api_endpoint:
            os.environ['GOOGLE_API_BASE_URL'] = api_endpoint

        # 配置 API
        genai.configure(
            api_key=api_key,
            transport="rest"
        )

        # 初始化模型
        self.model = genai.GenerativeModel('gemini-2.0-flash')

        # 注册退出时的清理函数
        atexit.register(self._cleanup_temp_dir)

    def _extract_images_from_pdf(self, pdf_path: str, task_id: str) -> Dict[int, List[Dict]]:
        """
        从 PDF 中提取图片
        :param pdf_path: PDF 文件路径
        :param task_id: 任务 ID ,用于生成唯一的图片名称
        :return: 按页码索引的图片信息字典 {页码: [图片信息列表]}
        """
        images_by_page = {}
        doc = fitz.open(pdf_path)

        for page_num, page in enumerate(doc):
            image_list = page.get_images(full=True)
            page_images = []

            for img_index, img_info in enumerate(image_list):
                xref = img_info[0]
                base_image = doc.extract_image(xref)
                image_bytes = base_image["image"]
                image_ext = base_image["ext"]

                # 生成唯一的图片名称
                image_filename = f"{task_id}_page{page_num + 1}_img{img_index + 1}.{image_ext}"

                # 获取图片在页面中的位置
                rect = page.get_image_bbox(img_info)

                page_images.append({
                    "filename": image_filename,
                    "data": image_bytes,
                    "ext": image_ext,
                    "rect": rect,
                    "xref": xref
                })

            if page_images:
                images_by_page[page_num] = page_images

        doc.close()
        return images_by_page

    def _upload_images_to_s3(self, images_by_page: Dict[int, List[Dict]], s3_service) -> Dict[int, List[Dict]]:
        """
        将提取的图片上传到 S3
        :param images_by_page: 按页码索引的图片信息字典
        :param s3_service: S3 服务实例
        :return: 更新后的图片信息字典,包含 S3 URL
        """
        for page_num, images in images_by_page.items():
            for img in images:
                try:
                    # 上传图片到 S3
                    file_key = f"images/{img['filename']}"
                    img_url = s3_service.upload_binary(
                        img['data'],
                        file_key,
                        f"image/{img['ext']}"
                    )
                    img['url'] = img_url
                except Exception as e:
                    self.logger.error(f"图片上传失败: {str(e)}")
                    img['url'] = None

        return images_by_page

    def _cleanup_temp_dir(self):
        """
        清理临时目录
        """
        try:
            if os.path.exists(self.temp_dir):
                for file in os.listdir(self.temp_dir):
                    try:
                        file_path = os.path.join(self.temp_dir, file)
                        if os.path.isfile(file_path):
                            os.remove(file_path)
                    except Exception as e:
                        self.logger.warning(f"清理临时文件失败: {str(e)}")
                os.rmdir(self.temp_dir)
        except Exception as e:
            self.logger.warning(f"清理临时目录失败: {str(e)}")

    def _split_pdf(self, pdf_path: str) -> List[str]:
        """
        将 PDF 分割成小块
        :param pdf_path: PDF 文件路径
        :return: 临时 PDF 文件路径列表
        """
        temp_files = []
        doc = fitz.open(pdf_path)
        total_pages = doc.page_count

        self.logger.info(f"PDF 总页数: {total_pages}")

        for start in range(0, total_pages, self.chunk_size):
            end = min(start + self.chunk_size, total_pages)

            # 创建新的 PDF 文档
            new_doc = fitz.open()
            new_doc.insert_pdf(doc, from_page=start, to_page=end - 1)

            # 使用 UUID 创建唯一的临时文件名
            temp_file_path = os.path.join(self.temp_dir, f'chunk_{uuid.uuid4().hex}.pdf')
            new_doc.save(temp_file_path)
            new_doc.close()

            temp_files.append(temp_file_path)

        doc.close()
        return temp_files

    def _read_pdf_file(self, pdf_path: str) -> dict:
        """
        读取 PDF 文件
        :param pdf_path: PDF 文件路径
        :return: 包含文件内容的字典
        """
        try:
            with open(pdf_path, 'rb') as file:
                content = file.read()
                base64_content = base64.b64encode(content).decode('utf-8')

            return {
                "mime_type": "application/pdf",
                "data": base64_content
            }
        except Exception as e:
            raise Exception(f"PDF 文件读取失败: {str(e)}")

    def _process_chunk(self, pdf_path: str, keywords: List[str], chunk_index: int,
                       translation_mode: str = "single", target_language: str = None) -> Dict:
        """
        处理单个 PDF 分块
        :param pdf_path: PDF 分块文件路径
        :param keywords: 关键词列表
        :param chunk_index: 分块索引
        :param translation_mode: 转换模式 ('single' 或 'bilingual')
        :param target_language: 目标语言
        :return: 包含处理结果的字典
        """
        for attempt in range(self.max_retries):
            try:
                pdf_data = self._read_pdf_file(pdf_path)

                # 获取当前分块的页数信息
                doc = fitz.open(pdf_path)
                page_info = f"(页码 {chunk_index * self.chunk_size + 1} - {chunk_index * self.chunk_size + doc.page_count})"
                doc.close()

                # 根据转换模式选择不同的提示词
                if translation_mode == "single":
                    prompt = f"""
                    请将这份 PDF 文档{page_info}转换为 Markdown 格式。

                    转换要求:
                    {', '.join(keywords)}

                    请确保:
                    1. 输出格式为标准 Markdown ,但不要用```markdown 包裹全部内容
                    2. 保持文档的结构和层级
                    3. 保持内容的完整性
                    4. 表格要转换为 Markdown 表格格式
                    5. 代码块要使用正确的格式
                    6. 正确使用 Markdown 换行语法(使用两个空格或空行实现换行)
                    """
                else:
                    prompt = f"""
                    请将这份 PDF 文档{page_info}转换为双语对照的 Markdown 格式,不要用```markdown 包裹全部内容。

                    转换要求:
                    1. 将内容翻译成{target_language}
                    2. 使用对照模式展示原文和译文
                    3. {', '.join(keywords)}

                    输出格式要求:
                    1. 对于每个章节标题:
       原文标题

       译文标题

                    2. 对于正文内容:
       原文段落

       译文段落

                    3. 对于表格,输出翻译前后的两个表格的独立:

                    4. 对于代码块:
       保持代码块原样,只翻译注释

                    请确保:
                    1. 保持文档的结构和层级
                    2. 翻译准确且符合目标语言的表达习惯
                    3. 保持格式的一致性
                    4. 专业术语的翻译准确
                    5. 正确使用 Markdown 换行语法(使用两个空格或空行实现换行)
                    6. 译文用引用的 Markdown 语法包裹以区分
                    """

                response = self.model.generate_content([prompt, pdf_data])

                return {
                    'index': chunk_index,
                    'content': response.text,
                    'success': True
                }

            except Exception as e:
                self.logger.error(f"处理分块{chunk_index}第{attempt + 1}次尝试失败: {str(e)}")
                if attempt == self.max_retries - 1:
                    return {
                        'index': chunk_index,
                        'content': f"<!-- 处理失败: {str(e)} -->",
                        'success': False
                    }

    def convert_to_markdown(self, pdf_path: str, keywords: List[str],
                            translation_mode: str = "single",
                            target_language: str = None,
                            parallel: bool = True,
                            progress_callback=None,
                            s3_service=None,
                            task_id: str = None) -> str:
        """
        将 PDF 转换为 Markdown ,包括图片
        :param pdf_path: PDF 文件路径
        :param keywords: 指导转换的关键词列表
        :param translation_mode: 转换模式 ('single' 或 'bilingual')
        :param target_language: 目标语言
        :param parallel: 是否并行处理
        :param progress_callback: 进度回调函数
        :param s3_service: S3 服务实例
        :param task_id: 任务 ID
        :return: Markdown 格式的文本
        """
        start_time = time.time()
        self.logger.info(f"开始转换... 模式: {translation_mode}" +
                         (f", 目标语言: {target_language}" if translation_mode == "bilingual" else ""))
        temp_files = []

        try:
            # 提取图片(如果提供了 S3 服务和任务 ID )
            images_by_page = {}
            if s3_service and task_id:
                self.logger.info("开始提取 PDF 中的图片...")
                images_by_page = self._extract_images_from_pdf(pdf_path, task_id)
                self.logger.info(f"共提取了 {sum(len(imgs) for imgs in images_by_page.values())} 张图片")

                # 上传图片到 S3
                self.logger.info("开始上传图片到 S3...")
                images_by_page = self._upload_images_to_s3(images_by_page, s3_service)

            # # 分割 PDF
            # temp_files = self._split_pdf(pdf_path)
            # chunks_count = len(temp_files)
            # self.logger.info(f"PDF 已分割为{chunks_count}个块")

            # 添加图片信息到关键词中
            if images_by_page:
                # 创建一个不包含二进制数据的图片信息字典
                image_info_for_json = {}
                for page_num, images in images_by_page.items():
                    image_info_for_json[page_num] = []
                    for img in images:
                        # 创建不包含二进制数据的图片信息副本
                        img_copy = {k: v for k, v in img.items() if k != 'data'}
                        # 将 Rect 对象转换为列表,以便 JSON 序列化
                        if 'rect' in img_copy and hasattr(img_copy['rect'], 'to_list'):
                            img_copy['rect'] = img_copy['rect'].to_list()
                        elif 'rect' in img_copy:
                            # 如果没有 to_list 方法,尝试直接转换为列表
                            img_copy['rect'] = [float(img_copy['rect'][0]), float(img_copy['rect'][1]),
                                                float(img_copy['rect'][2]), float(img_copy['rect'][3])]
                        image_info_for_json[page_num].append(img_copy)

                # 将处理后的图片信息转换为 JSON 字符串
                try:
                    image_info_json = json.dumps(image_info_for_json)
                    keywords.append(f"PDF 中包含图片,请在适当位置插入图片链接。图片信息: {image_info_json}")
                    keywords.append("对于每个图片,使用 Markdown 图片语法 ![图片描述](图片 URL) 插入")
                except TypeError as e:
                    self.logger.error(f"图片信息 JSON 序列化失败: {str(e)}")
                    # 如果序列化失败,添加简化的图片信息
                    simple_image_info = {}
                    for page_num, images in images_by_page.items():
                        simple_image_info[str(page_num)] = [
                            {"url": img.get('url', ''), "filename": img.get('filename', '')}
                            for img in images
                        ]
                    image_info_json = json.dumps(simple_image_info)
                    keywords.append(f"PDF 中包含图片,请在适当位置插入图片链接。简化图片信息: {image_info_json}")
                    keywords.append("对于每个图片,使用 Markdown 图片语法 ![图片描述](图片 URL) 插入")

            # 分割 PDF
            temp_files = self._split_pdf(pdf_path)
            chunks_count = len(temp_files)
            self.logger.info(f"PDF 已分割为{chunks_count}个块")

            results = []
            processed_count = 0

            if parallel:
                with ThreadPoolExecutor() as executor:
                    futures = [
                        executor.submit(self._process_chunk, temp_file, keywords, idx,
                                        translation_mode, target_language)
                        for idx, temp_file in enumerate(temp_files)
                    ]

                    for future in as_completed(futures):
                        processed_count += 1
                        if progress_callback:
                            progress_callback(processed_count, chunks_count)
                        results.append(future.result())
            else:
                for idx, temp_file in enumerate(temp_files):
                    result = self._process_chunk(temp_file, keywords, idx,
                                                 translation_mode, target_language)
                    processed_count += 1
                    if progress_callback:
                        progress_callback(processed_count, chunks_count)
                    results.append(result)

            # 按索引排序并合并结果
            results.sort(key=lambda x: x['index'])
            markdown_content = "\n\n".join(result['content'] for result in results)

            # 计算并显示耗时
            duration = time.time() - start_time
            if duration < 60:
                time_str = f"{duration:.2f}秒"
            elif duration < 3600:
                time_str = f"{duration / 60:.2f}分钟"
            else:
                time_str = f"{duration / 3600:.2f}小时"

            # 输出转换统计信息
            self.logger.info(f"转换完成!耗时: {time_str}")

            # 统计成功率
            success_count = sum(1 for r in results if r['success'])
            self.logger.info(f"处理成功率: {success_count}/{chunks_count} " +
                             f"({success_count / chunks_count * 100:.2f}%)")

            # 如果是双语模式,添加文档头部说明
            if translation_mode == "bilingual":
                #             header = f"""# 双语对照文档
                # 原文与{target_language}对照
                #
                # ---
                #
                # """
                markdown_content = markdown_content

            return markdown_content

        except Exception as e:
            error_msg = f"转换过程出错: {str(e)}"
            self.logger.error(error_msg)
            raise Exception(error_msg)
        finally:
            # 清理临时文件
            for temp_file in temp_files:
                try:
                    if os.path.exists(temp_file):
                        os.remove(temp_file)
                except Exception as e:
                    self.logger.warning(f"清理临时文件失败: {str(e)}")

    def save_markdown(self, markdown_text: str, output_path: str):
        """
        保存 Markdown 文件
        :param markdown_text: Markdown 文本
        :param output_path: 输出文件路径
        """
        try:
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(markdown_text)
            self.logger.info(f"Markdown 文件已保存至: {output_path}")
        except Exception as e:
            raise Exception(f"文件保存错误: {str(e)}")


def main():
    # 配置信息
    api_key = "xxxxxxxxxxxxxxx"
    api_endpoint = "https://xxxx.xxxxxxxxxxxxxx.com"  # 你的代理服务器地址

    # 文件路径
    pdf_path = "origin.pdf"  # 替换为你的 PDF 文件路径
    output_path = ("output-doc.md")

    # 转换指导关键词
    # keywords = [
    #     "保持文档的标题层级结构",
    #     "将表格转换为 Markdown 表格格式",
    #     "如果文档中有公式,注意公式的识别和转换",
    #     "如果文档中有多栏格式时,注意多栏模式下的阅读顺序保持",
    #     "保持列表的缩进和格式",
    #     "突出显示重要内容",
    #     "保持代码块格式",
    #     "添加适当的分隔符",
    #     "注意只需要输出 Markdown 内容,不要做多余的解释",
    #     "如果发现文档内有图例,可以在需要插入图例的位置插入图片占位符"
    #     "注意提取的完整性,不要错漏文档的内容"
    # ]
    keywords = [
        "You are an expert OCR assistant. Your job is to extract all text from the provided image and convert it into a well-structured, easy-to-read Markdown document that mirrors the intended structure of the original. Follow these precise guidelines:",
        "Use Markdown headings, paragraphs, lists, and tables to match the document's hierarchy and flow.",
        "For tables, use standard Markdown table syntax and merge cells if needed. If a table has a title, include it as plain text above the table.",
        "Render mathematical formulas with LaTeX syntax: use $...$ for inline and $$...$$ for display equations.",
        "For images, use the syntax ![descriptive alt text](link) with a clear, descriptive alt text.",
        "Remove unnecessary line breaks so that the text flows naturally without awkward breaks.",
        "Your final Markdown output must be direct text (do not wrap it in code blocks).",
        "Ensure your output is clear, accurate, and faithfully reflects the original image's content and structure."
    ]

    # 转换模式配置
    translation_mode = "single"  # 可选 "single" 或 "bilingual"
    target_language = "Chinese"  # 目标语言,如 "英语"、"日语" 等

    try:
        # 根据转换模式设置输出文件名
        base_name, ext = os.path.splitext(output_path)
        if translation_mode == "bilingual":
            output_path = f"{base_name}_{target_language}{ext}"

        # 初始化转换器
        converter = PDFToMarkdownConverter(
            api_key=api_key,
            api_endpoint=api_endpoint,
            chunk_size=3,
            max_retries=3
        )

        # 转换 PDF 到 Markdown
        print(f"开始转换... 模式: {translation_mode}" +
              (f", 目标语言: {target_language}" if translation_mode == "bilingual" else ""))

        markdown_content = converter.convert_to_markdown(
            pdf_path=pdf_path,
            keywords=keywords,
            translation_mode=translation_mode,
            target_language=target_language,
            parallel=True
        )

        # 保存结果
        converter.save_markdown(markdown_content, output_path)
        print(f"转换完成!文件已保存至: {output_path}")

    except Exception as e:
        print(f"转换过程中出现错误: {str(e)}")


if __name__ == "__main__":
    main()

微信小游戏,大家平时真的会自己去玩吗?

By: ttivan
9 April 2025 at 11:59
ttivan:

微信小游戏市场越来越大,但实际生活中能见到玩的人太少了,真的有那么多人玩 + 当主游戏来冲钱吗?

看微信小游戏数据 top10 每个产品都有 5000 万 用户量。

我身边是没有一个人在玩,故发出此疑问。。。

例如:top10 榜的《向僵尸开炮》、《无尽冬日》

避免踩坑,请给我帮忙看下安卓机。

By: jaleo
9 April 2025 at 11:56
jaleo:

目前在用 xr 6.5 年,想换安卓机。

主要需求: 支持 Google 服务 系统流畅好用 屏幕舒服 通透 不泪眼 拍照较好 偶尔玩游戏

小米据说系统不好就不考虑了。

目前只选了三个 vivo x200 pro mini ( 6.3 寸)、oppo Find X8 ( 6.59 寸)、 一加 13 ( 6.78 寸),有其他好的型号也可以建议。 请大家指点下各款的优缺点,另外天机高通处理器差距大不大。

CN 域名不是都实名制吗,为啥还有诈骗网站用 CN 域名?

By: renfei
9 April 2025 at 11:52
renfei:

今天收到了一个诈骗邮件,邮件内容如下:

各 单位 /部 门 :
关于 2 0 2 5 年个人绩效补贴通知;
根据国家人力资源部要求关于落实正常 发 放《 2025 年 度综 合工 薪补 贴》 申 领办 理 通知 , 依 据《 国 家劳 动法管理》
条例针对在职岗位薪资补贴、 医保补贴、住房补贴、交通补贴 等综合补贴申领认证通知 ;
一、该补贴联合单位下发 ,不得以工资形式发放 ,不纳入工资和奖金, 自助申请通过 7-10 个工作日发放三千元以上相应补贴金

二 、收到通知,请点击下方链接登录人力资源部官方服务办理大厅 自 助 申请领取

三 、请在 2025 年 4 月 8 日之前认证, 逾期申请视为放弃不再受理

点击 https://www.abjabjgja.cn 进入官方网站

其中诈骗网址: https://www.abjabjgja.cn

需要模拟手机打开,我填写了错误的信息,正确的手机号,然后,竟然真的收到了银联的短信:

[中国银联] 付款验证码 275018 ,任何人索取均为诈骗!尾号 3482 的银行卡向 SAMSUNG 付款 53490.00HKD ,请勿泄露!

whois 信息:

whois.cnnic.cn

Domain Name: abjabjgja.cn
ROID: 20250409s10001s65430332-cn
Domain Status: ok
Registrant: 曹浩然
Registrant Contact Email: 13386318346@189.cn
Sponsoring Registrar: 浙江贰贰网络有限公司
Name Server: ns2.22.cn
Name Server: ns1.22.cn
Registration Time: 2025-04-09 01:20:54
Expiration Time: 2026-04-09 01:20:54
DNSSEC: unsigned

用实名制的域名搞诈骗?他们是怎么做到的

疑似做完这些事就被墙

By: crc8
9 April 2025 at 11:51
crc8:

想在 openwrt 上用 ss 客户端,折腾了两件事:

  1. 安装 shadowsocks-libev luci-app-shadowsocks ,设置账号,因为没看到有支持 2022-blake3-aes-128-gcm ,选了 xchacha20-ietf-poly1305 ,便把服务器的也改为 xchacha20-ietf-poly1305 ;

  2. 因为做 1 后,发现根本连不上,接着安装 sing-box,配置文件忘记改回 2022-blake3-aes-128-gcm ,也是用 xchacha20-ietf-poly1305 ,也是没连接上,然后也没结束进程,就一直挂着,挂了一夜。

然后第二天早上起来 7 点左右,VPS 整个 IP 就被墙啦。

然而在此之前,我用的是 SSH 翻,或者是其他工具用 ss 或 ssr 一直十几年都没事,奇怪了。。。

最近经常刷到一些通过打字背单词的软件和网站, 自己也实现了一下.

9 April 2025 at 11:50
rookiemaster:

最近经常刷到一些通过打字背单词的软件和网站, 碰巧在学习 ts, 所以想自己实现一个, 感觉还挺有意思. 涉及 dom 操作, 播放音频, 重载快捷键, localStorage 等知识. 所有代码都在 App.vue 里, 不算 css 的话也就 200 行.

GitHub 地址

也可以通过GitHub Page访问, 记得打开声音.

kindle scribe 后台自动升级了

By: shyrock
9 April 2025 at 11:50
shyrock: 坏消息是 KOReader 失效了。
好消息是更新了直接在文档上写笔记的功能,之前看介绍还以为只有新款 KS 才支持。
居然软件升级支持,ama 良心了。

而且突然发现我不越狱,直接 send to kindle 也能很好地支持 epub ,
似乎没有特别的越狱必要性了,何况这越狱还一升级就掉。

噩耗!安装 15.4 到外置硬盘时报用户数据迁移出错,无法启动!

By: mandex
9 April 2025 at 11:43
mandex:

我是首先升级了内置硬盘里的系统到 15.4 ,一切正常。 然后升级外置硬盘系统的时候,重启失败,跳到了恢复模式,说迁移用户数据时出错,让我重新安装系统解决问题。 然鹅,重新安装的时候提示权限不足。真的醉了。 所以正确的升级步骤是什么???

还好我之前把外置硬盘单独分了一个卷宗出来存放数据,现在准备把系统卷宗抹掉。 感觉还是用内置硬盘安装系统吧,我内置硬盘有 512G ,不是太够。很多软件,像 xcode 这种只能安装在系统盘,不能移动出去使用,很惆怅。就算软件可以安装到外置硬盘,它产生的数据也一般放在系统盘的资源库里,这很难崩。

请教:地下仓储用电量统计的问题。

By: Mryang
9 April 2025 at 11:42
Mryang:

在小区地下购买了一个仓储,大概也就 5 、6 平米吧,然后接入电力的时候,物业说只能通过物业购电,且没有独立电表。问题是按照日常使用的话无法获知使用了多少电,也有邻居用了一段时间后,已购电量用完导致断电,因为仓储有冰箱之类的电器,断电后东西都坏了。物业说如果接入市政电网,那就是商用电,要不就只能用物业统一用电才是民用电价。然后只能时不常的问物业还剩多少电字,比较麻烦。有没有什么办法自己统计用电量以及剩余电量的方案?

安卓有没有类似解码器 dll 的东西?

By: uqf0663
9 April 2025 at 11:32
uqf0663: 家里局域网有多台不同品牌的安卓电视,由于某些儿童 tvapp 内容不可控(例如爱奇艺的儿童版-奇巴布 app ,很多弱智而且辣眼睛的内容)所以在家里 nas 存了不少自认为优质的儿童内容,但是发现由于不同电视的解码器问题,经常出现有声音没画面,放完上一个自动放下一个的时候画面比例不正确,音画不同步的问题,甚至无法播放(文件正常,但是在不同电视上的表现不一样)试过多款播放器(包括各电视自带的播放器、VLC 、MXPLAYER 、当贝等十几款市面上我都找到的播放器,各有各的问题,而且除了当贝的用户体验稍微正常,其它所有外国的播放器的交互体验简直是一言难尽),所以除了自行把 nas 的所有视频文件统一转换编码以外,有没有办法给各电视安装一个什么解码器让对视频编码的支持实现对齐?

vue3 我感觉挺好用呀

By: momowei
9 April 2025 at 11:30
momowei:

我看网络上不少人吐槽 vue3 ,不过我最近试了下 vue3 我感觉非常丝滑呀,尤其 Composition Api ,相比以前裹脚布似乎的 data,methods 声明,我觉得简化了很多,因为我也写过很多的 vue2 ,我觉得 vue3 从开发体验来说是比 vue2 好很多的,当然了,我不用 ts ,至于大家诟病的 ts 支持我感受不到。
因为也写 react ,我个人觉得在写 crud 方面,vue3 是吊打 react 的,双向绑定就是好使,当然了 slot 肯定没有 react 那么方便我也承认。 大家怎么看列

未和公司沟通去考研,在职场上是不是很严重的问题?

9 April 2025 at 11:29
LuckyPocketWatch:

RT

在职研究生,周末去上课的那种。然后今天和同事聊到这个话题,公司一个前辈(在公司任职超过 10 年)说,这种事情以前就有过,被公司知道了,然后那员工直接 被离职 了

我问他为啥这么严重,他说因为一般不是公司让你去考的,就默认你毕业即离职,所以基本直接让你管铺盖走人

我像问下,在职场里,对于公司来说,员工私自去考研是不是个非常严重的问题?

上海电信公网 ipv4 突然被取消

By: hackroad
9 April 2025 at 11:19
hackroad: 2025-04-06 04:12:41 秒突然收到告警,发现 WAN 口 ip 变成 100 段,发现的时候已经是中午。。。
[img][/img]

直接异地拨打 021-10000 投诉要求直接转后台测量室或装维,装维来电查了下说是之前就是私网 IP ,没有公网 ip ,直接开骂( FNMDGP ),让他去查查历史记录(公网 ipv4 都用了 2 年多,这条宽带用了快 16 年,早先一直都有公网 ip ,2 年前做公司和家里内网互联时发现被电信强加了云宽带变成了私网,于是去营业厅退掉了云宽带要求恢复公网 ip 。),要求立马给我恢复。

装维找了一堆接口说查下来就是之前没有公网 IP 的,已经帮我申请了,最快第二天就能恢复,这个恢复 2 个字你懂的,没怎么刁难一线人员只让他尽快给我恢复。


第二天中午 2 点多收到恢复消息,不知道上海电信这两天在操作什么。
[img][/img]

[股票交易大赛实习生]-请您帮忙找一下这个人

9 April 2025 at 10:56
genPeterTohetang: 请您帮忙找一下这个人哦,感谢~!

股票交易大赛实习生

我们正在寻找一位有激情、富有创意的实习生,来协助组织和执行我们的股票交易大赛。如果你对股票市场充满兴趣,并且有过类似的活动策划经验,欢迎加入我们的团队!

职位要求:
对股票交易和金融市场有浓厚兴趣
有过组织股票交易大赛或类似活动的经验(优先考虑)
具备良好的沟通能力和团队合作精神
细心、负责,能够独立执行任务
有创新思维,能提出并执行新的活动创意

职位职责:
协助策划和组织股票交易大赛的相关工作
协调活动流程,确保大赛顺利进行
参与宣传推广工作,提升大赛参与度
跟进大赛的实施,确保活动效果

-==--==--==--
WeChat 微信:johninception
Email 电邮: info@marv.ee
❌
❌