哈佛大学理论物理学家马修・施瓦茨借助 Claude 搭建的科研工具包 BootLoops 1.0 正式开源。施瓦茨提出「Claude 形状的问题」思路,即利用 AI 跨领域知识广、代码能力强、处理数据速度快的优势,解决不同学科中已有成熟跨领域解法但本领域学者未掌握的卡壳问题,基于该思路打造的 BootLoops 不绑定特定大模型,还设立了可核验的运算标准防范 AI 蒙混。过去三个月,施瓦茨联合 19 位合作者依托这套工具从 400 个候选问题中筛选推进,完成了覆盖 18 个领域的 36 篇学术手稿,在粒子物理、生态学、群体遗传学、经济学、语言学等多个领域取得了诸多跨界科研进展。这套科研架构通过多独立会话分工调度提升运行稳定性,但过程仍高度依赖人类学者把控学术方向、核验成果,当前 AI 仍存在缺乏时间概念、解题爱用蛮力、易夸大成果、无学术鉴别力等明显缺陷。施瓦茨认为当前 AI 最适合助力探索人类此前受限于精力未能涉足的学科交叉地带,同时 AI 深度介入科研也给传统学术评价、人才培养等现有学术生态带来了新的冲击与待解的问题。
衛福部健康幣10月1日正式上路,要把民眾健檢、癌篩、打疫苗等預防保健行為,轉換為可查詢、可兌換的數位獎勵。年滿18歲且持有臺灣健保卡的民眾,完成健保快易通App身分驗證並綁定國健署Health GO App後,就能透過健康存摺的健康幣專區,來查詢累積情形。今年12月1日起,累積滿1,000健康幣,民眾可依規定於合作通路兌換健康商品、電子票券或折抵部分自費醫療項目。 健康幣10月1日上路,健保快易通身兼點數查詢入口 做完健檢、癌篩或打疫苗後,能不能不用自己留單據、拍照上傳,也能自動拿到獎勵?
Dubai is a place where impressive vehicles are a familiar sight on the road. Wide highways, modern attractions, luxury hotels, stylish restaurants, and vibrant entertainment areas create an ideal setting for enjoying a premium car. Among the vehicles that attract attention, Brabus rental Dubai and Ferrari SF90 stand out for very different reasons. A Brabus offers a bold combination of power, luxury, and commanding road presence, while the Ferrari SF90 delivers an exciting sports car experience with remarkable performance. If you are considering renting either vehicle in Dubai, there are several important things to understand before making a booking. From choosing the right car for your plans to checking rental conditions, insurance, mileage, deposits, and driving requirements, careful preparation can make the entire experience more enjoyable. Understand What a Brabus Rental Offers Brabus is known for creating highly customized versions of premium Mercedes vehicles. Depending on the particular model available from a rental company, a Brabus can provide an impressive combination of luxury, performance, distinctive styling, and a carefully finished interior. A Brabus SUV can be particularly practical for Dubai because it combines a spacious cabin with a strong road presence. It can be used for business meetings, hotel transfers, shopping trips, sightseeing, and special occasions. Before booking, ask the rental company about the exact Brabus model. Different Brabus vehicles can have very different specifications, seating arrangements, engine performance, and equipment. Knowing the exact model helps you choose a vehicle that matches your plans. Explore the Ferrari SF90 Experience The Ferrari SF90 provides a completely different type of driving experience. It is a high performance Ferrari designed for drivers who want an exciting sports car with advanced technology and impressive acceleration. Its low profile and sports car design make it especially suited to travelers who want a memorable vehicle for special occasions or leisure drives. The Ferrari SF90 can be an attractive option for photography sessions, celebrations, luxury outings, and enjoying Dubai's modern roads. However, a sports car requires more consideration than a large SUV. Limited luggage space, low ground clearance, and a different seating arrangement can affect where and how you use the vehicle. Consider your itinerary carefully before choosing the SF90 for an entire trip. Think About Your Travel Plans Your schedule should play an important role in deciding between a Brabus and Ferrari SF90. If you need a vehicle for several passengers, luggage, business appointments, and longer journeys, a Brabus may provide greater practicality. If you are traveling alone or with one passenger and your main objective is to enjoy a high performance sports car, the Ferrari SF90 may better match your plans. Some visitors may even choose different vehicles for different occasions. A spacious Brabus can handle daily travel, while the Ferrari SF90 can be reserved for a special evening, celebration, or memorable drive. Check the Rental Price and Inclusions Never look only at the headline rental price. Before confirming your booking, ask exactly what the quoted amount includes. Important details can include insurance, mileage allowance, taxes, delivery and collection charges, additional driver fees, and other rental costs. Premium and high performance vehicles can have specific conditions that differ from standard car rentals. Ask whether the quoted rate is calculated by day, several days, or another rental period. If you intend to keep the car for an extended stay, ask about longer rental packages. A clear understanding of the total cost allows you to plan your budget properly. Understand the Security Deposit Luxury and performance cars may require a security deposit. Before collecting the vehicle, confirm the required amount and payment method. Ask how the deposit is handled and what circumstances can affect its return. Traffic fines, toll charges, fuel differences, or vehicle damage may be handled according to the terms of the rental agreement. Reading this section carefully can prevent misunderstandings later. If anything in the agreement is unclear, ask the rental company for an explanation before signing. Inspect the Vehicle Carefully A detailed inspection is especially important when renting an expensive vehicle. Before driving away, examine the exterior and interior carefully. Look for scratches, dents, wheel marks, paint damage, glass damage, and any other visible imperfections. Inside the vehicle, check the seats, dashboard, displays, controls, and other equipment. Make sure existing damage is documented by the rental company. Taking photographs or videos at the beginning of the rental can also provide a useful record of the vehicle's condition. For a Ferrari SF90 or a customized Brabus, careful inspection is particularly sensible because repairs and cosmetic components can be costly. Understand Mileage Restrictions Mileage conditions can have a major effect on your rental experience. Some rental agreements provide a daily mileage allowance, while additional distance may result in extra charges. Think about where you plan to drive before selecting a rental package. If you expect to visit different parts of Dubai or travel to another emirate, your mileage requirements may be higher. Ask the rental provider how additional mileage is calculated. Knowing this before booking can help you avoid unexpected expenses when returning the vehicle. Learn About Dubai Roads Dubai has an extensive network of modern roads, but traffic conditions can change considerably throughout the day. Drivers should pay attention to speed limits, road signs, lane markings, traffic signals, and other instructions. If you are driving a Ferrari SF90, extra attention is useful because its performance can make it tempting to focus on acceleration rather than normal road conditions. Always follow posted speed limits and local traffic regulations. A Brabus may feel larger than the vehicles you normally drive, particularly when parking or moving through tighter areas. Take time to become familiar with the vehicle before entering busy traffic. Consider Parking and Ground Clearance Parking should be part of your planning when renting a premium vehicle. Dubai has many large shopping centers, hotels, restaurants, and attractions with parking facilities, but individual spaces and entrances can vary. The Ferrari SF90 has a low sports car profile, so drivers should be cautious around ramps, raised surfaces, and other areas where ground clearance may become an issue. A larger Brabus can offer a more comfortable experience for general parking and passenger access, but its size should still be considered in compact parking areas. Follow the Fuel and Return Policy Ask about the fuel policy before beginning your rental. Find out whether the vehicle needs to be returned with the same fuel level as provided at collection. Also confirm the exact return location and time. If the vehicle is being delivered to your hotel or another location, make sure the collection arrangements are clearly understood. For premium cars, the return inspection can be detailed, so keeping the vehicle in good condition throughout the rental period is important. Choose the Vehicle That Fits Your Occasion A Brabus and Ferrari SF90 can both create an unforgettable driving experience, but they serve different purposes. A Brabus can be suitable for travelers who want luxury, strong performance, passenger space, and everyday usability. It can work well for business appointments, family travel, shopping, hotel visits, and longer drives. The Ferrari SF90 is more focused on the sports car experience. Its distinctive design and performance make it suitable for special occasions, leisure drives, celebrations, and travelers who want something truly different from an everyday vehicle. The right choice depends on your passengers, luggage, itinerary, driving preferences, and rental budget. Prepare Before You Collect the Car Before arriving at the rental location, make sure you have all required documents and understand the company's rental requirements. Confirm the accepted driving license, identification documents, payment arrangements, deposit, insurance terms, and rental duration. Take time to read the agreement instead of rushing through the collection process. Pay particular attention to mileage, traffic fines, toll charges, fuel requirements, insurance conditions, and vehicle return procedures. Once these details are clear, you can start your Dubai journey with fewer concerns. Enjoy Your Dubai Drive Renting a Brabus or Ferrari SF90 rental Dubai can turn ordinary transportation into a memorable part of your trip. The Brabus offers a spacious and commanding environment, while the Ferrari SF90 brings the character of a high performance sports car to the road. The most important step is choosing the vehicle according to your actual plans. Consider how many people will travel with you, where you will drive, how much luggage you have, and what type of experience you want. By checking rental terms, inspecting the vehicle, understanding mileage and deposit requirements, and following Dubai road regulations, you can make better use of your chosen vehicle. Whether you select the refined practicality of a Brabus or the thrilling character of a Ferrari SF90, proper preparation can make your time behind the wheel an enjoyable part of your Dubai visit.
P/E Ratio: The One Formula Every Stock Screener Runs (and Gets Wrong) By Marketcaplens. All figures below are illustrative hypotheticals, not data from any real company. If you've ever built a stock screener, a watchlist, or a ranking page, you've computed this number: price divided by earnings per share. The P/E ratio is the most quoted valuation shortcut in markets — and the easiest to misuse. This is the formula behind it, the traps baked into it, and how to use it without fooling yourself. The two formulas P/E asks one question: how many dollars does the market pay for one dollar of a company's earnings? P/E = share price ÷ EPS Implied share price = EPS × P/E multiple The first is what the market is paying . The second is what the stock would be worth if you chose the multiple. Same relationship, solved for a different unknown. Take an illustrative example: a company earns $5 a share and trades at $100 . Its P/E is 20 . Run it through the P/E and PEG calculator and you also get the earnings yield — EPS ÷ price — which is 5% here, plus PEG if you add a growth rate. Turn it around with the P/E valuation calculator : $5 of EPS at a 15× multiple implies $75 a share; at 20× it implies $100 ; at 25× it implies $125 . If the stock actually trades at $90 , those cases sit below, above, and further above the market price. That gap — implied versus actual — is where the real question lives. The denominator is a label, not a number Every screener bug I've seen in P/E logic comes from the denominator. "EPS" is not one number. It's a period you have to name: Trailing — the last reported twelve months (or the last fiscal year, if that's all you have). Fiscal year — the last completed fiscal year, even if a newer quarter exists. Forward — an estimate for a future year. A forecast, not a reported fact. A $100 price over $5 of trailing EPS is a trailing 20×. The same price over $6 of expected next-year EPS is a forward 16.7×. Those are different questions. If your screener mixes trailing prices with forward earnings without labeling the period, the "cheap" stocks it surfaces are unit errors, not bargains. PEG has the same trap: it only makes sense when the P/E period and the growth period match — trailing earnings with trailing growth, or forward with forward. The plain-English P/E guide works through exactly this. What P/E tells you, and what it leaves out P/E compresses price and earnings into one multiple so you can compare companies. A 12× stock is cheaper on earnings than a 30× stock, all else equal. All else is rarely equal. A high multiple often means the market is paying up for growth. It can also mean earnings have collapsed while the price hasn't caught up yet — the ratio looks expensive for the worst possible reason. Read it next to the business, never as a buy or sell signal. And remember P/E only sees equity and earnings, not debt or cash. Two companies can share a P/E and have nothing else in common. Zero and negative EPS: undefined, not zero You cannot divide by zero, so P/E is undefined when EPS is exactly zero. A loss-making company produces a negative mathematical quotient, but that figure is not meaningful (N/M) for the usual comparison. Taking the absolute value, or flipping the sign so a loss looks like a bargain multiple, is a trick — not a valuation. Any screener that displays a negative P/E as a sortable number is lying to its users; blank is the honest output. Until earnings turn positive, use another lens: sales, cash flow, or a DCF model if you have free cash flow. The takeaway for builders P/E is two inputs and one division. The work is everything around it: labeling the EPS period, refusing to compute on zero or negative earnings, and presenting the implied-price cases (low, base, high) instead of a single magic number. Get those right and the ratio does what it was built to do — compress price and earnings into one comparable multiple. Get them wrong and your screener manufactures bargains that don't exist. For general education only. Nothing here is investment advice. More calculators: all MarketCapLens tools .
이번주에는 면접관이 되었다. 이번 장의 주제는 무려 유튜브 설계 ... ! 문제 이해 및 설계 범위 확정 이번 장에서 다루고자하는 서비스 설계의 특징은 이러하다. • 빠른 비디오 업로드 • 원활한 비디오재생 • 재생 품질 선택 기능 • 낮은 인프라 비용(infrastructure cost) • 높은 가용성과 규모확장성, 그리고안정성 • 지원 클라이언트: 모바일 앱, 웹브라우저, 그리고 스마트 TV 개략적 규모 추정 CDN으로 비디오를 서비스하면 비용이 크다. 이 단계에서는 규모를 먼저 추정하고, 비용 절감 방법은 뒤에서 다룬다. 가정: DAU 500만 / 1인당 하루 5개 시청 / 사용자의 10%가 하루 1개 업로드 / 영상 평균 300MB 저장 용량: 500만 × 10% × 300MB = 하루 150TB 증가 CDN 비용: 500만 × 5개 × 0.3GB × $0.02 = 하루 $150,000 (CloudFront, 미국 트래픽 기준, 스트리밍 비용만 계산) 개략적 설계안 제시 및 동의 구하기 주어진 조건에 따라 기존 클라우드 서비스를 이용한다. 규모 확장이 쉬운 BLOB 저장소나 CDN을 직접 만드는 것은 매우 복잡하고 비용도 많이 들어 비효율적이기 때문이다. 넷플릭스나 페이스북 같은 큰 회사도 모든 것을 직접 구축하지는 않는다. 기존 클라우드를 이용할 때 서비스는 개략적으로 아래와 같이 구성되며, 이 구성을 바탕으로 비디오 업로드 절차와 비디오 스트리밍 절차 를 설계한다. ※ 단말(Client) : 컴퓨터, 모바일, 스마트 TV 등 YouTube를 시청할 수 있는 기기 ※ CDN : 비디오를 저장하고, 사용자가 재생 버튼을 누르면 CDN에서 비디오를 스트리밍하여 사용자 단말에서 이를 확인할 수 있게 함. ※ API 서버 : 비디오 스트리밍을 제외한 요청을 처리. (ex. 피드 추천, 비디오 업로드 URL 생성, 메타데이터 DB·캐시 갱신, 사용자 가입 등) 비디오 업로드 절차 해당 구조에서 비디오 업로드와 비디오 메타데이터 갱신 과정이 병렬적으로 수행된다. 비디오 업로드 원본 업로드 → 트랜스코딩 → 저장소 업로드 + 완료 이벤트 큐 → CDN 업로드 + DB/캐시 갱신 → 스트리밍 준비 완료 원본 업로드 단말이 비디오를 원본 저장소 에 업로드한다. 트랜스코딩 시작 트랜스코딩 서버가 원본 저장소에서 비디오를 가져와 여러 화질·형식으로 변환한다. 트랜스코딩 완료 후 병렬 처리 3a. 비디오 저장 : 트랜스코딩된 비디오를 트랜스코딩 비디오 저장소 에 업로드한다. 3b. 완료 이벤트 전달 : 트랜스코딩 완료 이벤트를 완료 큐 에 넣는다. 각 작업 진행 3a-1. CDN 업로드 : 트랜스코딩된 비디오를 CDN에 업로드 한다. 3b-1. 완료 이벤트 처리 : 완료 핸들러가 큐에서 이벤트를 꺼낸다. 3b-1-a/b. 메타데이터 갱신 : 완료 핸들러가 메타데이터 DB와 캐시를 갱신 한다. 스트리밍 준비 완료 알림 API 서버가 단말에 비디오 업로드 및 처리가 완료되어 스트리밍할 수 있음 을 알린다. ※ 트랜스코딩 : 압축된 디지털 파일(주로 오디오나 비디오)을 다른 형식이나 사양으로 변환하는 프로세스. 메타데이터 갱신 비디오 업로드 + 메타데이터 갱신 요청 → API 서버 → 메타데이터 캐시·DB 업데이트 메타데이터 갱신 요청 원본 저장소에 비디오를 업로드하는 동안, 단말이 API 서버에 메타데이터 갱신 요청 을 보낸다. 메타데이터 전달 요청에는 파일 이름, 파일 크기, 파일 포맷 등의 정보가 포함된다. 메타데이터 갱신 API 서버가 전달받은 정보를 이용해 메타데이터 캐시와 데이터베이스를 업데이트 한다. 비디오 스트리밍 절차 비디오는 다운로드 없이 바로 cdn에서 스트리밍된다. 이때, 비디오 스트리밍을 위해 스트리밍 프로토콜이 사용된다는 것을 알아두자. 스트리밍 프로토콜은 비디오 스트리밍을 위해 데이터를 전송할 때 쓰이는 표준화된 통신방법으로, 널리 쓰이는 것으로는 아래와 같은 것들이 있으니 훑어보자. • MPEG-DASH. MPEG • 애플(Apple) HLS. • 마이크로소프트 스무드 스트리밍 (Microsoft Smooth Streaming). • 어도비 HTTP 동적 스트리밍 (Adobe HTTP Dynamic Streaming, HDS) ※ 스트리밍 프로토콜은 각각 지원하는 비디오 인코딩이 다르고 플레이어도 다르다는 것이다. 따라서 비 디 오 스트리밍 서비스를 설계할 때는 서비스의 용례에 맞는 프로토콜을 잘 골라야 한다. 상세설계 비디오 업로드와 비디오 스트리밍을 최적화 하는 방법과, 발생할 수 있는 오류 처리에 대해서 알아본다. 비디오 트랜스코딩 비디오 트랜스코딩은 해상도, 코덱, 비트레이트(bitrate) 등의 매개변수를 조정해 비디오 파일을 다른 형식으로 변환하는 프로세스이다. 비디오를 녹화하면 단말(보통 전화나 카메라)은 해당 비디오를 특정 포맷으로 저장한다. 이 비디오가 저장 공간을 덜 차지하고, 다른 단말과 호환되며, 사용자의 대역폭에 맞는 화질로, 끊김 없이 재생되려면 변환이 필요하다. 트랜스코딩이 변환하는 대상인 비디오 포맷은 크게 두 부분으로 이루어진다. 컨테이너(container): 비디오, 오디오, 메타데이터를 담는 바구니 같은 것이다. 컨테이너 포맷은 .avi, .mov, .mp4 같은 파일 확장자를 보면 알 수 있다. 코덱(codec): 화질을 최대한 유지하면서 파일 크기를 줄이기 위해 고안된 압축 및 압축 해제 알고리즘이다. 가장 많이 쓰이는 비디오 코덱으로는 H.264, VP9, HEVC가 있다. 유향 비순환 그래프(DAG) 모델 비디오를 트랜스코딩하는 것은 컴퓨팅 자원을 많이 소모할 뿐 아니라 시간도 많이 드는 작업이다. 게다가 콘텐츠 창작자는 각자 자기만의 비디오 프로세싱 요구사항을 갖고 있다. 이런 다양한 요구를 지원하려면(=쟤들 말 들어주려면) 처리 과정을 적절히 추상화해서 작업을 직접 정의할 수 있게 해야 한다. 이때 쓸 수 있는 것이 DAG 모델이다. 원본 비디오는 비디오, 오디오, 메타데이터로 나뉘고, 정의된 작업들은 DAG 모델에 따라 단계별로 배열되어 순차적으로 또는 병렬적으로 실행된다. 비디오 트랜스코딩 아키텍처 본 설계안에서는 클라우드 서비스를 활용한 비디오 트랜스코딩 아키텍처를 다음과 같이 정의하였다. 전처리기 비디오 분할 : 비디오를 몇 초 단위의 GOP 로 나눈다. 구형 단말은 전처리기가 분할을 대신한다. DAG 생성 : 설정 파일을 바탕으로 비디오 처리 작업 순서(DAG) 를 생성한다. 데이터 캐시 : 분할된 비디오와 메타데이터를 임시 저장해 인코딩 실패 시 재개 할 수 있도록 한다. DAG 스케줄러 DAG 그래프를 몇 개 단계(stage)로 분할한 다음에 그 각각을 자원 관리자의 작업 큐(task queue)에 집어넣는다 자원 관리자 작업을 적절한 서버에 배분하고 실행 상태를 관리한다. 작업 큐 : 실행할 작업을 우선순위대로 보관 작업 서버 큐 : 사용 가능한 작업 서버 정보를 보관 실행 큐 : 현재 실행 중인 작업과 서버 정보를 보관 작업 스케줄러 : 작업과 서버를 매칭하고 실행을 지시 동작 과정: 우선순위 높은 작업 선택 → 적합한 서버 선택 → 작업 실행 지시 → 실행 큐에 등록 → 작업 완료 후 제거 작업 서버 작업 서버는 DAG에 정의된 작업을 수행한다. 이때, 작업종류에 따라 서버를 나누어 관리한다. 임시 저장소 어떤 시스템을 선택할 것이냐는 저장할 데이터의 유형, 크기, 이용 빈도, 데이터 유효기간 등에 따라 달라진다. 예시: 메타데이터 : 자주 참조하고 크기가 작으므로 메모리에 캐시 한다. 비디오·오디오 데이터 : 크기가 크므로 BLOB 저장소 에 보관한다. 임시 저장소 : 비디오 프로세싱이 완료되면 삭제한다 . 인코딩된 비디오 끝. 파이프라인 최종 결과물 생산완료. 시스템 최적화 속도, 안전성, 비용을 최적화하는 방법에 대해서 다룬다. 속도 최적화: 비디오 병렬 업로드 비디오 전체를 한 번에 업로드하는 것은 비효율적이다. 하나의 비디오를 GOP 단위로 분할해 병렬로 업로드하면 속도가 빨라지고, 일부가 실패해도 실패한 조각만 다시 올리면 되므로 빠르게 재개할 수 있다. 속도 최적화: 업로드 센터를 사용자 근거리에 지정 데이터가 이동해야 하는 네트워크 거리와 경로가 짧아지면 업로드 시간도 줄어든다. 업로드 센터를 여러 곳에 두어, 사용자가 거주지 근처의 업로드 센터를 이용하도록 하자. 속도 최적화: 모든 절차를 병렬화 메시지큐를 도입한다. 메시지 큐 도입 전: 각 모듈이 앞 단계의 작업이 끝나기를 기다려야 해서 속도가 느리다. 메시지 큐 도입 후: 모듈은 결과를 큐에 넣고 바로 다음 작업으로 넘어가고, 뒤 단계는 큐에 쌓인 작업을 여러 대가 병렬로 처리한다. 기다리는 시간이 없어지고 동시에 처리하는 양이 늘어나 속도가 빨라진다. 안전성 최적화: 미리 사인된 업로드 URL API 서버가 사용자의 업로드 권한을 확인한 뒤 미리 사인된 URL을 발급한다. 이 URL은 정해진 위치에만, 제한된 시간 동안만 쓸 수 있어서, 허가받은 사용자만 올바른 위치에 비디오를 업로드할 수 있다. 상세 절차: URL 요청: 클라이언트가 API 서버에 업로드 URL을 요청한다. URL 발급: API 서버가 업로드 권한이 포함된 미리 사인된 URL을 반환한다. 직접 업로드: 클라이언트가 해당 URL을 이용해 저장소에 비디오를 직접 업로드한다. 안전성 최적화: 비디오 보호 비디오 저작권 보호를 위해 움직여보자. 방식 핵심 내용 DRM 디지털 콘텐츠의 접근·복제 권한을 관리 AES 암호화 비디오를 암호화하고, 허가된 사용자만 재생 시 복호화 워터마크 영상에 회사 로고·소유자 정보 등을 표시 비용 최적화 CDN은 비싸다. 데이터 크기가 크면 클수록 더하다. 이 비용은 어떻게 낮출 수 있을까? 인기 영상만 CDN 사용 → 인기 없는 영상의 CDN 저장·전송 비용 을 줄인다. 인기 없는 영상은 필요할 때 인코딩 → 미리 인코딩하고 저장하는 인코딩·저장 비용 을 줄인다. 지역별 인기 영상만 해당 지역에 저장 → 다른 지역으로 영상을 복제하는 저장·전송 비용 을 줄인다. ISP와 제휴 → 사용자와 가까운 ISP를 통해 전송해 네트워크 전송 비용 을 줄인다. 사람들은 소수의 인기 영상을 본다. 인기 영상만 CDN으로 제공하고 나머지는 자체 서버에서 제공해 비용을 줄여보자. 오류 처리 시스템 오류에는 두 가지 종류가 있다. 회복 가능 오류(recoverable error) 재시도, 우회, 교체로 해결한다. 계속 실패하면 클라이언트에 오류 코드를 반환한다. 재시도로 해결 업로드 오류: 몇 회 재시도한다. 트랜스코딩 오류: 재시도한다. 전처리 오류: DAG 그래프를 재생성한다. DAG 스케줄러 오류: 작업을 다시 스케줄링한다. 작업 서버 장애: 다른 서버에서 해당 작업을 재시도한다. 다른 경로로 우회 비디오 분할 오류: 클라이언트가 GOP 단위로 분할하지 못하면 전체 비디오를 서버로 보내 서버가 분할한다. API 서버 장애: 무상태 서버이므로 신규 요청을 다른 API 서버로 보낸다. 사본과 교체로 해결 자원 관리자 큐 장애: 사본(replica)을 이용한다. 메타데이터 캐시 서버 장애: 다중화된 다른 노드에서 데이터를 가져오고, 장애 서버는 새것으로 교체한다. 메타데이터 데이터베이스 서버 장애 주 서버 장애: 부 서버 중 하나를 주 서버로 승격한다. 부 서버 장애: 다른 부 서버로 읽기를 처리하고, 장애 서버는 새것으로 교체한다. 회복 불가능 오류(non-recoverable error) 다시 시도해도 결과가 같은 오류. 해당 비디오의 작업을 중단하고 클라이언트에 오류 코드를 반환한다. 비디오 포맷이 잘못된 경우 이 주의 면접문제 14장은 260페이지를 기준으로 두 파트로 나뉘는데, 이 장의 꽃은 병렬화라고 생각해, 파트별로 병렬화와 관련된 문제를 내려고 한다. FASD92 트랜스코딩 절차에 DAG 모델을 도입하면 어떤 점이 좋은가? msms804 비디오 업로드부터 CDN 배포까지의 과정에서 속도를 최적화하는 방법으로는 업로드 센터를 사용자 가까이 두는 것이 있다. 이 외의 방법을 1가지 이상 서술하시오.
⚠️ Powerlevel10k/Powerlevel9k 사용자라면 반드시 읽어보세요! Powerlevel10k나 Powerlevel9k 테마를 사용하고 있다면, Cursor AI Assistant와 터미널 작업 시 명령어 완료 감지가 제대로 되지 않는 문제를 겪고 있을 가능성이 높습니다. Cursor 공식 문서에서 이 문제를 명시적으로 언급하고 있으며, CURSOR_AGENT 환경변수를 사용하는 것이 유일한 공식 해결책 입니다. 🐛 현상 및 원인 - Cursor 공식 문서 확인 Cursor – Terminal: Run terminal commands automatically as part of agent operations Cursor 공식 문서에서 이 문제의 원인을 명확히 설명하고 있습니다: "Some shell themes (for example, Powerlevel9k/Powerlevel10k) can interfere with the inline terminal output. If your command output looks truncated or misformatted, disable the theme or switch to a simpler prompt when Agent runs." 문제 현상: Cursor AI → run_terminal_cmd → 쉘 프로세스 → 명령어 실행 ↑ ↓ 수동 Skip ←←←← 여기서 멈춤 ←←←← 출력 결과 + 새 프롬프트 실제로 일어나는 상황: ✅ 명령어가 성공적으로 실행됨 ✅ 출력 결과가 표시됨 (하지만 잘리거나 형식이 깨질 수 있음) ✅ 새로운 쉘 프롬프트가 나타남 ❌ Cursor가 "터미널 명령어 실행 중..."에서 무한 대기 🖱️ 사용자가 매번 수동으로 "Skip" 버튼을 클릭해야 함 핵심 원인: Powerlevel9k/Powerlevel10k가 인라인 터미널 출력을 방해 복잡한 프롬프트 렌더링이 Cursor의 명령어 완료 감지 메커니즘과 충돌 터미널 출력이 잘리거나 형식이 깨져서 Agent가 완료 신호를 파싱하지 못함 ✅ 해결책 - Cursor 공식 권장 방법 Cursor에서 제공하는 유일한 공식 해결책 : "Disable heavy prompts for Agent sessions" "Use the CURSOR_AGENT environment variable in your shell config to detect when the Agent is running and skip initializing fancy prompts/themes." Cursor 측에서 제공한 공식 해결책은 CURSOR_AGENT 환경변수를 사용하는 것이 유일합니다. Powerlevel10k 사용자를 위한 설정 .zshrc 파일에 다음 코드를 추가하세요: # ~/.zshrc — disable Powerlevel10k when Cursor Agent runs if [[ -n "$CURSOR_AGENT" ]]; then # Skip theme initialization for better compatibility else [[ -r ~/.p10k.zsh ]] && source ~/.p10k.zsh fi # ~/.bashrc — fall back to a simple prompt in Agent sessions if [[ -n "$CURSOR_AGENT" ]]; then PS1='\u@\h \W \$ ' fi 🛠️ 내가 사용중인 해결책 - Oh-My-Zsh + Powerlevel10k 조합 문제 상황: 공식 해결책을 그대로 적용했을 때, oh-my-zsh와 Powerlevel10k를 함께 사용하는 환경에서는 일반 터미널에서도 테마가 제대로 로드되지 않는 문제가 발생했습니다. 모든 터미널이 기본 형태가 되어버리는 현상이었죠. 해결 방법: oh-my-zsh 초기화 라인을 추가해주니 완벽하게 작동했습니다. # Oh-My-Zsh + Powerlevel10k 사용자를 위한 개선된 설정 if [[ -n "$CURSOR_AGENT" ]]; then # Agent 세션: 테마 초기화 건너뛰기 (호환성 향상) else # 일반 세션: Oh-My-Zsh와 Powerlevel10k 정상 로드 source $ZSH/oh-my-zsh.sh [[ -r ~/.p10k.zsh ]] && source ~/.p10k.zsh fi 핵심 포인트: source $ZSH/oh-my-zsh.sh 라인이 추가되어 oh-my-zsh가 정상적으로 초기화됨 Agent 터미널에서는 여전히 모든 복잡한 테마가 비활성화됨 일반 터미널에서는 oh-my-zsh와 Powerlevel10k가 완벽하게 작동함 Oh-My-Zsh + Powerlevel10k 조합 사용자라면 이 방법을 권장합니다! 마무리 Cursor에서 제공하는 공식 해결책인 CURSOR_AGENT 환경변수를 활용하면 이 문제를 완벽하게 해결할 수 있습니다.** 이것이 Cursor에서 제공하는 유일하고 공식적인 해결책**입니다. (2025.09 기준) 참조 https://docs.cursor.com/en/agent/terminal https://github.com/cursor/cursor/issues/3165 https://github.com/cursor/cursor/issues/3215 원문: Sanghun Kang의 블로그
큐를 처음 배우면 먼저 들어온 데이터가 먼저 나오는 FIFO(First In, First Out) 자료구조라고 설명한다. const queue: string[] = []; queue.push("video-101"); queue.push("video-102"); const nextVideo = queue.shift(); // "video-101" video-101 이 먼저 들어왔으므로 먼저 꺼내진다. 줄을 먼저 선 사람이 먼저 서비스를 받는 모습으로 이해하면 큐의 기본 동작을 쉽게 기억할 수 있다. 입문 단계에서는 유용한 설명이지만, 실제 서비스의 처리 순서는 push() 와 shift() 만으로 결정되지 않는다. 크리스가 동영상 두 개를 차례로 업로드하더라도 첫 번째 영상의 변환 작업이 더 오래 걸리면 두 번째 영상이 먼저 완료될 수 있다. 작업이 실패해 재시도되거나 여러 서버가 동시에 처리하면 요청 순서와 시작 순서, 완료 순서가 서로 달라진다. 사용자는 업로드 요청이 끝날 때까지 영상 변환을 기다려야 할까? 작업 서버가 감당할 수 있는 양보다 요청이 빠르게 들어오면 어떻게 해야 할까? 실패한 작업은 언제 다시 처리하며, 같은 메시지가 두 번 전달되면 결과도 두 번 만들어야 할까? 실제 서비스에서 큐는 먼저 들어온 작업을 먼저 꺼내는 저장 공간이 아니라, 작업이 들어오는 속도와 처리되는 속도를 분리하고 어떤 작업을 언제 실행할지 통제하는 구조다. 오래 걸리는 작업을 요청 안에서 끝내야 할까? 크리스가 2GB짜리 영상을 업로드했다고 해보자. 서버는 원본 파일을 저장한 뒤 여러 해상도로 변환하고 썸네일을 생성해야 한다. 처음에는 하나의 API 요청에서 모든 작업을 처리할 수 있다. async function uploadVideo(input: UploadInput) { const video = await saveOriginalVideo(input.file); await transcodeVideo(video.id); await createThumbnail(video.id); return { videoId: video.id, status: "ready" }; } 코드는 단순하지만 변환에 10분이 걸리면 API 응답도 10분 동안 끝나지 않는다. 연결이 끊기거나 서버가 재시작되면 어디까지 처리했는지 확인하기도 어렵다. 동시에 여러 사용자가 영상을 올리면 업로드 요청이 변환 작업에 서버 자원을 빼앗길 수 있다. 영상 업로드와 영상 변환은 같은 시점에 시작할 수 있지만 생명주기가 다르다. 업로드 요청은 원본 파일이 안전하게 저장되고 작업이 등록되면 끝낼 수 있다. 영상 변환은 별도의 작업 서버가 이후에 처리해도 된다. async function uploadVideo( userId: string, input: UploadInput ) { const validatedFile = validateVideoFile(input.file); const video = await saveOriginalVideo(userId, validatedFile); const job = await videoJobRepository.create({ videoId: video.id, type: "transcode", status: "queued", attemptCount: 0 }); await videoQueue.enqueue({ jobId: job.id }); return { videoId: video.id, status: "processing" }; } 서버는 파일 형식과 크기, 사용자의 업로드 권한을 확인한 뒤 원본 영상을 저장한다. 그다음 변환 작업을 등록하고 큐에는 작업 ID를 넣는다. 클라이언트는 변환이 끝날 때까지 연결을 유지하는 대신 processing 상태를 받고 나중에 결과를 조회한다. 현실의 영상 처리 과정은 다음과 같이 코드로 변환된다. 입력 사용자 ID, 원본 영상, 변환 설정 상태 영상 ID, 원본 파일 위치, 작업 상태, 시도 횟수 출력 변환된 영상과 썸네일 또는 실패 상태 큐를 도입하면서 요청 처리와 작업 처리가 분리된다. 이제 API 서버는 작업을 안전하게 등록할 책임을 지고, 작업 서버는 큐에서 작업을 가져와 실행하고 결과를 기록할 책임을 진다. 먼저 꺼낸 작업이 먼저 완료된다는 보장은 없다 하나의 작업 서버가 모든 영상을 차례로 처리한다면 큐에 들어온 순서와 작업 시작 순서가 대부분 일치한다. 그러나 처리량을 높이기 위해 작업 서버를 세 개로 늘리면 결과가 달라진다. async function worker() { const message = await videoQueue.dequeue(); const job = await videoJobRepository.findById(message.jobId); await transcodeVideo(job.videoId); } 첫 번째 서버가 30분짜리 영상을 처리하는 동안 두 번째 서버는 1분짜리 영상을 처리할 수 있다. 먼저 등록된 영상이 늦게 끝나는 것은 오류가 아니라 동시 처리의 자연스러운 결과다. video-101: 30분 영상 ───────────────── 완료 video-102: 1분 영상 ── 완료 따라서 큐에서 말하는 순서는 구분해서 생각해야 한다. 큐에 등록된 순서 작업 서버가 가져간 순서 작업을 시작한 순서 결과가 완료된 순서 일반적인 영상 변환에서는 완료 순서가 바뀌어도 문제가 없다. 각 영상이 독립적이기 때문이다. 하지만 한 영상에 대해 원본 분석 → 변환 → 썸네일 생성 → 공개 순서가 반드시 지켜져야 한다면 각 작업의 선행 조건을 확인해야 한다. async function publishVideo(videoId: string) { const video = await videoRepository.findById(videoId); if (video.transcodeStatus !== "completed") { throw new Error("Video has not been transcoded"); } if (video.thumbnailStatus !== "completed") { throw new Error("Thumbnail has not been created"); } await videoRepository.updateStatus(videoId, "published"); } 큐에 먼저 넣었다는 사실만으로 작업 의존성이 보장되지는 않는다. 공개 작업은 필요한 결과가 준비되었는지 원본 상태를 확인해야 한다. 순서가 비즈니스 규칙이라면 큐의 FIFO 동작에만 기대지 말고 상태와 선행 조건으로 표현해야 한다. 큐의 메시지를 원본 데이터로 사용해도 될까? 변환에 필요한 모든 정보를 메시지에 넣을 수도 있다. await videoQueue.enqueue({ videoId: "video-101", ownerId: "user-20", sourceUrl: "https://storage.example.com/original.mp4", resolution: "1080p", status: "queued" }); 이 메시지가 오래 대기하는 동안 사용자가 영상을 삭제하거나 관리자가 공개를 제한할 수 있다. 저장 위치가 변경되거나 변환 설정이 수정될 수도 있다. 작업 서버가 메시지에 들어 있는 오래된 상태를 그대로 사용하면 삭제된 영상을 다시 처리하거나 현재 정책과 다른 결과를 만들 수 있다. 큐에는 가능한 한 작업을 식별할 수 있는 최소한의 정보만 넣고, 실행 직전에 신뢰할 수 있는 저장소에서 현재 상태를 조회하는 편이 안전하다. await videoQueue.enqueue({ jobId: job.id }); async function processVideoJob(jobId: string) { const job = await videoJobRepository.findById(jobId); if (!job || job.status === "completed") { return; } const video = await videoRepository.findById(job.videoId); if (!video || video.status === "deleted") { await videoJobRepository.markCancelled(job.id); return; } await transcodeVideo(video); await videoJobRepository.markCompleted(job.id); } 데이터베이스의 작업 레코드가 작업 상태의 Source of Truth가 되고, 큐 메시지는 해당 작업을 실행하라는 신호가 된다. 큐에 메시지가 남아 있더라도 데이터베이스에서 작업이 취소된 상태라면 실행하지 않는다. 외부에서 작업 ID를 받았다고 해서 바로 처리해서도 안 된다. 작업의 존재 여부, 영상의 소유자와 상태, 허용된 변환 설정을 확인해야 한다. 큐가 내부 시스템에 있더라도 메시지는 지연되거나 중복될 수 있으므로 검증 전까지 현재 상태라고 가정할 수 없다. 같은 작업이 두 번 전달되면 어떻게 해야 할까? 많은 작업 대기열은 메시지가 절대로 중복되지 않는다고 보장하지 않는다. 작업 서버가 변환을 완료한 직후 결과 확인 메시지를 보내기 전에 종료되면, 큐는 처리되지 않은 것으로 판단해 같은 작업을 다시 전달할 수 있다. async function processVideoJob(jobId: string) { const job = await videoJobRepository.findById(jobId); await transcodeVideo(job.videoId); await videoJobRepository.markCompleted(job.id); } 이 구현에서는 같은 메시지가 두 번 전달될 때 변환 파일이 중복 생성될 수 있다. 사용자에게 완료 알림을 보내는 작업이라면 같은 알림이 여러 번 전송될 수도 있다. 작업 서버는 이미 완료된 작업인지 확인하고, 실행 중 상태로 안전하게 변경한 서버만 실제 처리를 시작해야 한다. async function processVideoJob(jobId: string) { const claimed = await videoJobRepository.claimIfQueued(jobId); if (!claimed) { return; } try { await transcodeVideo(claimed.videoId); await videoJobRepository.markCompleted(jobId); } catch (error) { await videoJobRepository.markFailed(jobId); throw error; } } claimIfQueued() 는 작업 상태가 queued 일 때만 processing 으로 바꾸고, 동시에 여러 작업 서버가 요청하더라도 하나만 성공하도록 구현해야 한다. 데이터베이스의 조건부 업데이트나 트랜잭션이 이 책임을 맡을 수 있다. 이처럼 같은 작업이 여러 번 전달되어도 최종 결과가 한 번 처리된 것과 같도록 만드는 성질을 멱등성이라고 한다. 큐를 사용하는 서비스에서는 메시지가 정확히 한 번만 전달될 것이라고 기대하기보다, 중복 전달을 견딜 수 있도록 작업을 설계하는 편이 안전하다. 실패한 작업을 무조건 다시 넣어도 될까? 영상 변환이 실패했다고 해서 모두 같은 방식으로 재시도할 수 있는 것은 아니다. 작업 서버의 일시적인 메모리 부족은 잠시 뒤 성공할 수 있지만, 손상된 영상 파일은 몇 번을 반복해도 실패할 가능성이 높다. async function handleFailure( job: VideoJob, error: Error ) { if (job.attemptCount < 3 && isTemporary(error)) { await videoJobRepository.incrementAttempt(job.id); await videoQueue.retry(job.id); return; } await videoJobRepository.markPermanentlyFailed( job.id, error.message ); } 재시도 횟수와 간격을 제한하지 않으면 실패 작업이 계속 큐로 돌아와 정상 작업의 처리를 방해할 수 있다. 실패 원인을 구분하고, 일시적인 오류만 일정 시간 후 다시 처리하며, 반복해서 실패한 작업은 별도로 격리해야 한다. 요청이 작업 서버의 처리 속도보다 빠르게 들어오는 상황도 고려해야 한다. 한 시간에 1,000개의 영상이 등록되는데 500개만 처리할 수 있다면 큐는 계속 길어진다. 큐가 있다는 이유만으로 처리 능력이 증가하지는 않는다. 대기 작업 수와 가장 오래된 작업의 대기 시간, 실패율을 관찰하고 작업 서버를 늘리거나 업로드 속도를 제한해야 한다. 큐는 부하를 없애는 장치가 아니라 부하가 한꺼번에 작업 서버로 전달되지 않도록 완충하고, 운영자가 처리량을 조절할 시간을 제공하는 장치다. 영상 처리 큐를 설계하기 전에 확인할 질문 API 요청에서 즉시 끝내야 하는 일과 나중에 처리해도 되는 일은 무엇인가? 큐에 들어간 순서, 작업 시작 순서와 완료 순서 중 어떤 순서를 보장해야 하는가? 여러 작업 서버가 동시에 처리해도 각 작업은 서로 독립적인가? 선행 작업이 필요한 경우 그 조건을 큐 순서가 아니라 상태로 검증하고 있는가? 작업 상태의 Source of Truth는 큐 메시지인가, 데이터베이스의 작업 레코드인가? 오래된 메시지를 처리하기 전에 영상의 현재 상태와 접근 권한을 다시 확인하는가? 같은 메시지가 두 번 전달돼도 결과가 중복 생성되지 않는가? 일시적인 실패와 다시 시도해도 해결되지 않는 실패를 구분하는가? 재시도 횟수와 간격, 영구 실패 후의 처리 방법이 정해져 있는가? 작업 유입 속도가 처리 속도보다 빨라질 때 대기 시간과 서버 용량을 어떻게 통제할 것인가? 큐는 작업의 속도와 실행 순서를 통제하는 경계다 큐의 기본 동작은 먼저 들어온 항목을 먼저 꺼내는 것이다. 그러나 실제 영상 서비스에서는 작업을 꺼내는 순서만으로 전체 처리 순서를 설명할 수 없다. 여러 작업 서버가 동시에 실행되고, 오래 걸리는 작업과 실패한 작업이 섞이며, 같은 메시지가 다시 전달될 수 있기 때문이다. 영상 업로드 요청과 변환 작업을 분리하면 사용자는 긴 처리를 기다리지 않아도 되고, 서버는 감당할 수 있는 속도로 작업을 가져갈 수 있다. 대신 작업 상태를 저장하고, 중복 실행을 방지하고, 실패와 재시도를 통제하며, 순서가 필요한 작업의 선행 조건을 검증해야 한다. 큐를 선택한다는 것은 단순히 FIFO 자료구조를 사용하는 일이 아니다. 요청이 들어오는 시점과 실제 작업이 실행되는 시점 사이에 경계를 만들고, 그 경계에서 처리량·순서·실패를 관리하겠다는 설계 판단이다. 다음 글에서는 힙과 우선순위 큐가 모든 작업을 정렬하지 않고도 지금 처리해야 할 가장 중요한 작업을 선택하는 방법을 살펴본다.