2026/04/12

오늘의 이야기

Visual SVN에서 변경 이력 및 내역 확인하기


svn 동기화



CMD 창에서 변경 이력 확인


Visual SVN의 변경 이력을 CMD 창에서 확인하려면 svn log 명령어를 사용합니다. 예를 들어, 특정 파일의 변경 이력을 확인하려면 다음과 같이 입력합니다:



svn log path/to/your/file


특정 리비전의 변경 내용 확인


특정 리비전의 변경 내용을 확인하려면 svn diff 명령어를 사용합니다. 예를 들어, 리비전 1234의 변경 내용을 확인하려면:



svn diff -c 1234 path/to/your/file


특정 파일의 변경 이력과 내역 확인


특정 파일의 변경 이력과 내역을 확인하려면 다음 명령어를 사용합니다:



svn log path/to/your/file
svn diff -r N:M path/to/your/file


이 명령어를 통해 특정 파일의 변경 이력과 각 리비전에서의 변경 내용을 상세히 확인할 수 있습니다.




이 요약을 통해 블로그 게시물을 작성하시면 됩니다. 추가로 도움이 필요하시면 언제든지 말씀해 주세요! 😊





오늘의 이야기


#billcorea #운동동아리관리앱
🏸 Schneedle, aplikasi mesti ada untuk kelab badminton!
👉 Main Perlawanan – Rekod Markah & Cari Lawan 🎉
Sesuai untuk mana-mana sahaja, bersendirian, bersama rakan-rakan atau dalam kelab! 🤝
Jika anda suka badminton, pasti mencubanya

Pergi ke aplikasi 👉 https://play.google.com/store/apps/details?id=com.billcorea.matchplay




오늘의 이야기

Oracle 해시 조인의 이해와 활용


hash join



데이터베이스에서 대용량 데이터를 효율적으로 조인하는 방법 중 하나는 해시 조인(Hash Join)입니다. 이 글에서는 Oracle 데이터베이스에서 해시 조인의 작동 방식과 성능 특성, 그리고 사용 시기에 대해 알아보겠습니다.

해시 조인의 작동 방식
해시 조인은 두 단계로 이루어집니다:

Build 단계: 작은 집합(Build Input)을 읽어 해시 테이블을 생성합니다. 이 해시 테이블은 메모리에 저장되며, 조인 키를 기준으로 해시 버킷에 데이터를 분류합니다.
Probe 단계: 큰 집합(Probe Input)을 읽어 해시 테이블을 탐색하면서 조인합니다. 각 레코드는 해시 테이블의 해당 버킷을 탐색하여 일치하는 레코드를 찾습니다.
성능 특성
해시 조인은 다음과 같은 성능 특성을 가집니다:

랜덤 액세스 부하 없음: 조인 과정에서 랜덤 액세스 부하가 발생하지 않아 성능이 향상됩니다.
메모리 사용: 주로 PGA(Process Global Area) 메모리를 사용하여 디스크 I/O를 최소화합니다.
CPU 및 메모리 의존성: 해시 테이블 생성과 탐색에 많은 CPU와 메모리 자원이 필요합니다.
해시 조인의 사용 시기
해시 조인은 다음과 같은 상황에서 유용합니다:

인덱스가 없는 경우: 조인 컬럼에 적당한 인덱스가 없을 때 해시 조인이 효과적입니다.
대용량 데이터 조인: 많은 양의 데이터를 조인해야 할 때 해시 조인이 유리합니다.
성능 개선 방법
해시 조인의 성능을 최적화하기 위해 다음과 같은 방법을 사용할 수 있습니다:

효율적인 해시 테이블 생성: Build Input이 충분히 작고 중복 값이 적어야 합니다.
충분한 메모리 확보: Hash Area에 충분한 메모리를 할당하여 디스크 I/O를 줄입니다.
예제 코드
다음은 Oracle에서 해시 조인을 사용하는 예제 코드입니다:

SQL

SELECT /*+ USE_HASH(o l) */
    o.customer_id,
    l.unit_price * l.quantity AS total_price
FROM
    orders o,
    order_items l
WHERE
    o.order_id = l.order_id;

AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
이 쿼리는 orders 테이블의 order_id와 order_items 테이블의 order_id를 해시 조인하여 각 고객의 총 주문 금액을 계산합니다.

이 글이 해시 조인에 대한 이해를 돕는 데 도움이 되었기를 바랍니다. 추가로 궁금한 점이 있으면 언제든지 댓글로 남겨주세요! 😊





오늘의 이야기


#스하리1000명프로젝트,
Kadang-kadang susah nak bercakap dengan pekerja asing kan?
Saya membuat aplikasi mudah yang membantu! Anda menulis dalam bahasa anda, dan orang lain melihatnya dalam bahasa mereka.
Ia auto-terjemah berdasarkan tetapan.
Sangat berguna untuk sembang mudah. Lihatlah apabila anda mendapat peluang!
https://play.google.com/store/apps/details?id=com.billcoreatech.multichat416




오늘의 이야기

리눅스 셸 스크립트로 날짜 생성하기


화면 만들기



리눅스 셸 스크립트를 사용하여 향후 3개월 동안의 날짜 목록을 생성하는 방법에 대해 논의했습니다. 다음은 블로그 게시물에 사용할 수 있는 단계별 가이드와 최종 스크립트입니다.


단계별 가이드



  1. 시작 날짜와 종료 날짜 초기화:

    • 시작 날짜는 오늘 날짜로 설정합니다.

    • 종료 날짜는 오늘로부터 3개월 후로 계산합니다.



  2. 각 날짜를 반복:

    • while 루프를 사용하여 시작 날짜부터 종료 날짜까지 각 날짜를 반복합니다.

    • 원하는 형식(yyyymmdd)으로 각 날짜를 출력합니다.



  3. 날짜 비교:

    • 숫자 비교를 위해 -lt를 사용하여 올바른 날짜 비교를 보장합니다.




최종 스크립트


다음은 향후 3개월 동안의 날짜를 yyyymmdd 형식으로 생성하는 최종 스크립트입니다:



#!/bin/bash

# 시작 날짜 (오늘)
start_date=$(date +%Y%m%d)

# 종료 날짜 (오늘로부터 3개월 후)
end_date=$(date -d "+3 months" +%Y%m%d)

# 시작 날짜부터 종료 날짜까지 각 날짜를 반복
current_date=$start_date
while [[ "$current_date" -lt "$end_date" ]]; do
echo $current_date
current_date=$(date -d "$current_date + 1 day" +%Y%m%d)
done


설명



  • 시작 날짜: start_date=$(date +%Y%m%d)는 시작 날짜를 yyyymmdd 형식으로 초기화합니다.

  • 종료 날짜: end_date=$(date -d "+3 months" +%Y%m%d)는 오늘로부터 3개월 후의 종료 날짜를 계산합니다.

  • 루프: while 루프는 각 날짜를 반복하며 지정된 형식으로 날짜를 출력합니다.


이 스크립트는 날짜 시퀀스를 생성해야 하는 다양한 자동화 작업에 유용합니다. 필요에 따라 추가로 커스터마이즈할 수 있습니다!




이 내용이 블로그 게시물 작성에 도움이 되길 바랍니다! 더 필요한 정보나 도움이 필요하면 언제든지 말씀해 주세요.





오늘의 이야기

Python으로 BLE 장치와 통신하기


BLE 장치와 통신해기 feat Copilot



BLE(Bluetooth Low Energy) 장치와 통신하는 방법을 Python을 사용하여 구현해 보았습니다. 이 글에서는 BLE 장치를 검색하고, 서비스와 특성을 확인하며, 데이터를 주고받는 과정을 단계별로 설명합니다.


1. BLE 장치 검색


먼저, bleak 라이브러리를 사용하여 BLE 장치를 검색합니다. bleak는 Windows, macOS, Linux에서 모두 작동하는 BLE 라이브러리입니다.


설치



pip install bleak


코드


Python
 



import asyncio
from bleak import BleakScanner

async def scan():
devices = await BleakScanner.discover()
for device in devices:
print(device)

asyncio.run(scan())


AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.

이 코드는 BLE 장치를 검색하고, 검색된 장치 목록을 출력합니다.


2. BLE 장치의 서비스 및 특성 확인


검색된 장치의 서비스와 특성을 확인하기 위해 bleak 라이브러리를 사용합니다.


코드


Python
 



import asyncio
from bleak import BleakClient

address = "F6:5B:9F:64:41:37" # BLE 장치의 주소

async def get_services(address):
async with BleakClient(address) as client:
services = client.services
for service in services:
print(f"Service: {service.uuid}")
for characteristic in service.characteristics:
print(f" Characteristic: {characteristic.uuid}")

asyncio.run(get_services(address))


AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.

이 코드는 특정 BLE 장치에 연결하여 모든 서비스와 특성의 UUID를 출력합니다.


3. 데이터 전송 및 수신


BLE 장치와 데이터를 주고받기 위해 bleak 라이브러리를 사용합니다.


코드


Python
 



import asyncio
from bleak import BleakClient

address = "F6:5B:9F:64:41:37"
RX_CHARACTERISTIC_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e" # 데이터 전송
TX_CHARACTERISTIC_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e" # 데이터 수신

async def send_data(client, data):
await client.write_gatt_char(RX_CHARACTERISTIC_UUID, data)
print(f"Sent: {data}")

async def receive_data(client):
def notification_handler(sender, data):
print(f"Received: {data}")

await client.start_notify(TX_CHARACTERISTIC_UUID, notification_handler)
await asyncio.sleep(5) # 데이터 수신 대기 시간
await client.stop_notify(TX_CHARACTERISTIC_UUID)

async def main():
async with BleakClient(address) as client:
if client.is_connected:
print(f"Connected to {address}")

# 데이터 전송
await send_data(client, b'Hello BLE')

# 데이터 수신
await receive_data(client)

asyncio.run(main())


AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.

이 코드는 BLE 장치에 연결하여 데이터를 전송하고 수신하는 방법을 보여줍니다. 수신된 데이터는 notification_handler를 통해 출력됩니다.


4. 수신된 데이터 해석


수신된 데이터는 다음과 같은 형식으로 출력됩니다:



Received: bytearray(b'3639,-276\n')
Received: bytearray(b'3673,-435\n')
...


이 데이터를 해석하려면 장치의 프로토콜 문서나 데이터 형식을 참조해야 합니다. 예를 들어, 숫자 쌍 데이터를 파싱하는 코드는 다음과 같습니다:


Python
 



data = bytearray(b'3639,-276\n')
values = data.decode('utf-8').strip().split(',')
x, y = int(values[0]), int(values[1])
print(f"x: {x}, y: {y}")


AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.

이 코드를 사용하면 수신된 데이터를 적절히 파싱하여 의미 있는 값으로 변환할 수 있습니다.




이 글을 통해 Python을 사용하여 BLE 장치와 통신하는 방법을 이해하고, 실제로 데이터를 주고받는 과정을 구현해 보았습니다. 추가로 궁금한 점이 있거나 도움이 필요하시면 언제든지 댓글로 남겨주세요! 😊





오늘의 이야기

디버그 모드에서 가짜 Bluetooth 스캔 결과 시뮬레이션하기

블루투스 스캔 결과 모방 하기


 
안드로이드 개발 중 Bluetooth 기능을 테스트할 때, 실제 장치가 없거나 테스트 환경을 조작하고 싶을 때가 있습니다. 이 글에서는 no.nordicsemi.android.support.v18.scanner.ScanCallback을 사용하여 디버그 모드에서 가짜 Bluetooth 스캔 결과를 시뮬레이션하는 방법을 소개합니다.

1. Mock 데이터 생성

먼저, ScanResult와 ScanRecord를 포함한 Mock 데이터를 생성합니다.


Kotlin

 


import no.nordicsemi.android.support.v18.scanner.ScanCallback
import no.nordicsemi.android.support.v18.scanner.ScanResult
import android.bluetooth.BluetoothDevice
import android.bluetooth.le.ScanRecord
import java.lang.reflect.Constructor

// Mock BluetoothDevice 생성
fun createMockBluetoothDevice(address: String, name: String): BluetoothDevice {
val constructor = BluetoothDevice::class.java.getDeclaredConstructor(String::class.java)
constructor.isAccessible = true
val device = constructor.newInstance(address)
val nameField = BluetoothDevice::class.java.getDeclaredField("mName")
nameField.isAccessible = true
nameField.set(device, name)
return device
}

// Mock ScanRecord 생성
fun createMockScanRecord(): ScanRecord? {
return try {
val constructor: Constructor<ScanRecord> = ScanRecord::class.java.getDeclaredConstructor(
ByteArray::class.java, // 광고 데이터
ByteArray::class.java, // 스캔 응답 데이터
List::class.java, // 서비스 UUIDs
Int::class.javaPrimitiveType, // 광고 플래그
Int::class.javaPrimitiveType, // TxPowerLevel
String::class.java, // Device Name
Int::class.javaPrimitiveType // Manufacturer Specific Data
)
constructor.isAccessible = true
constructor.newInstance(
byteArrayOf(0x02, 0x01, 0x06), // 광고 데이터
byteArrayOf(0x09, 0x09, 0x4D, 0x6F, 0x63, 0x6B, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65), // 스캔 응답 데이터
listOf(), // 서비스 UUIDs
-1, // 광고 플래그
0, // TxPowerLevel
"Mock Device", // Device Name
0 // Manufacturer Specific Data
)
} catch (e: Exception) {
e.printStackTrace()
null
}
}

// Mock ScanResult 생성
fun createMockScanResult(): ScanResult {
val mockDevice = createMockBluetoothDevice("00:11:22:33:44:55", "Mock Device")
val mockScanRecord = createMockScanRecord()
return ScanResult(mockDevice, mockScanRecord, 0, System.nanoTime())
}


AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.

2. ScanCallback 설정

이제 ScanCallback을 설정하고, Mock 데이터를 사용하여 콜백을 호출합니다.


Kotlin

 


val mockScanResult = createMockScanResult()

val scanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
super.onScanResult(callbackType, mockScanResult)
// 결과 처리
}

override fun onBatchScanResults(results: List<ScanResult>) {
super.onBatchScanResults(listOf(mockScanResult))
// 결과 처리
}

override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
// 오류 처리
}
}

// 디버그 모드에서 Mock 데이터로 콜백 호출
scanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, mockScanResult)


AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.

이 코드를 사용하면 디버그 모드에서 no.nordicsemi.android.support.v18.scanner.ScanCallback을 가짜로 만들어 테스트할 수 있습니다. 이를 통해 실제 장치 없이도 Bluetooth 기능을 테스트하고 디버깅할 수 있습니다.


이 블로그 게시물이 도움이 되길 바랍니다! 추가로 궁금한 점이 있으면 언제든지 물어보세요. 😊


...
하지만 실제 코딩에서는 진척이 없습니다.  읽어 주셔서 감사합니다.





오늘의 이야기


#스하리1000명프로젝트,
한국에서 길을 잃었나요? 한국어를 못하더라도 이 앱을 사용하면 쉽게 돌아다닐 수 있습니다.
귀하의 언어로 말하면 귀하의 언어로 번역, 검색 및 결과가 표시됩니다.
여행자에게 좋습니다! 영어, 일본어, 중국어, 베트남어 등 10개 이상의 언어를 지원합니다.
지금 사용해 보세요!
https://play.google.com/store/apps/details?id=com.billcoreatech.opdgang1127




오늘의 이야기



#스치니1000프로젝트 #재미 #행운기원 #Compose #Firebase

🎯 야 너 토요일마다 로또 확인하냐?
나도 맨날 “혹시나~” 하면서 봤거든 ㅋㅋ

근데 이제는 그냥 안 해
AI한테 맡겼어 🤖✨

그것도 구글 Gemini로다가!

그래서 앱 하나 만들었지
👉 “로또 예상번호 by Gemini” 🎱

AI가 분석해서 번호 딱! 뽑아줌
그냥 보고 참고만 하면 됨

재미로 해도 좋고…
혹시 모르는 거잖아? 😏


https://play.google.com/store/apps/details?id=com.billcorea.gptlotto1127




2026/04/11

오늘의 이야기

JavaScript로 페이지 요소 값 가져오기 및 세션을 통한 값 전달

열코 하세요.



페이지 최상단의 특정 항목 값 알아내기
JavaScript를 사용하여 페이지 최상단에 있는 특정 항목의 값을 알아내는 방법은 매우 간단합니다. document.getElementById 또는 document.querySelector를 사용하여 특정 요소를 선택하고, 해당 요소의 값을 가져올 수 있습니다.

예제 코드:
HTML

<!DOCTYPE html>
<html>
<head>
    <title>Get Element Value</title>
</head>
<body>
    <div id="topElement">This is the top element</div>
    <script>
        // 특정 ID를 가진 요소 선택
        const topElement = document.getElementById('topElement');
        
        // 요소의 텍스트 내용 가져오기
        const elementValue = topElement.innerText;
        
        console.log(elementValue); // "This is the top element" 출력
    </script>
</body>
</html>
AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
위 예제에서는 id가 topElement인 요소를 선택하고, 해당 요소의 텍스트 내용을 innerText 속성을 사용하여 가져옵니다.

또 다른 방법으로는 document.querySelector를 사용할 수도 있습니다:

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Get Element Value</title>
</head>
<body>
    <div class="top-element">This is the top element</div>
    <script>
        // 특정 클래스를 가진 요소 선택
        const topElement = document.querySelector('.top-element');
        
        // 요소의 텍스트 내용 가져오기
        const elementValue = topElement.innerText;
        
        console.log(elementValue); // "This is the top element" 출력
    </script>
</body>
</html>
AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
이 방법은 CSS 선택자를 사용하여 요소를 선택할 수 있어 더욱 유연합니다.

세션을 통해 하위 페이지로 값 전달하기
세션을 통해 하위 페이지로 값을 전달하는 방법은 여러 가지가 있습니다. 여기서는 JavaScript와 HTML을 사용하여 세션 스토리지를 활용하는 방법을 설명하겠습니다.

1. 값 저장하기 (상위 페이지)
먼저, 상위 페이지에서 세션 스토리지에 값을 저장합니다.

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Save to Session Storage</title>
</head>
<body>
    <input type="text" id="inputValue" placeholder="Enter some value">
    <button onclick="saveToSession()">Save</button>

    <script>
        function saveToSession() {
            const inputValue = document.getElementById('inputValue').value;
            sessionStorage.setItem('savedValue', inputValue);
            alert('Value saved to session storage!');
        }
    </script>
</body>
</html>
AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
2. 값 가져오기 (하위 페이지)
하위 페이지에서 세션 스토리지에 저장된 값을 가져옵니다.

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Retrieve from Session Storage</title>
</head>
<body>
    <div id="displayValue"></div>

    <script>
        window.onload = function() {
            const savedValue = sessionStorage.getItem('savedValue');
            document.getElementById('displayValue').innerText = savedValue ? savedValue : 'No value found in session storage.';
        }
    </script>
</body>
</html>
AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
이 예제에서는 상위 페이지에서 입력된 값을 세션 스토리지에 저장하고, 하위 페이지에서 해당 값을 가져와서 표시합니다.

JavaScript로 7일 전 날짜 구하기
JavaScript를 사용하여 7일 전의 날짜를 구하는 방법은 매우 간단합니다. Date 객체와 setDate 메서드를 사용하면 됩니다.

예제 코드:
JavaScript

// 현재 날짜 가져오기
let currentDate = new Date();

// 7일 전 날짜 계산
currentDate.setDate(currentDate.getDate() - 7);

// 결과 출력
console.log(currentDate);
AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
이 코드는 현재 날짜에서 7일을 빼서 7일 전의 날짜를 계산합니다.

이 블로그 게시글이 도움이 되셨길 바랍니다! 추가적인 질문이 있거나 다른 도움이 필요하시면 언제든지 말씀해 주세요. 😊





오늘의 이야기

클라우드 기능 활용한 이메일 발송법, 파이어스토어&파이어베이스-메일 발송

자동 메일링



• 이 블로그 게시물은 클라우드 기술을 사용하여 이메일을 더 쉽게 보낼 수 있는 방법을 설명합니다. 특히 신규 가입자에게 환영 이메일을 보내거나 사용자 지원 요청을 처리하는 시나리오에서 그렇습니다.

• 이메일 전송을 자동화하고 애플리케이션 내 사용자 지원 기능을 향상시키기 위해 클라우드 기능을 사용하는 이점을 강조합니다.

• 게시물은 파이어베이스 프로젝트 설정, 파이어베이스 CLI 설치, 파이어스토어 트리거 이메일 확장 설치 등에 대한 단계별 안내를 제공한다.

• SMTP 연결 URI, Firebase 수집명, 주소에서 기본 설정, SMTP 비밀번호 등 확장에 필요한 필수 구성도 포함합니다.

• 또한 게시물은 연락처 요청을 제출하라는 클라이언트 요청에 의해 트리거된 클라우드 기능에 대한 코드 스니펫을 포함하여 이메일을 보내기 위해 화재 기반 전송 이메일 확장을 활용하는 호출 가능한 클라우드 기능을 작성하는 방법을 보여준다.

• 클라우드 기능이 확장자에 의해 모니터링되는 Firestore 수집 지원_요청에 문서를 추가하여 문서의 내용을 기반으로 이메일 전송을 트리거하는 방법을 설명합니다.

https://blog.canopas.com/how-to-send-emails-using-cloud-functions-firestore-firebase-send-email-ff4702a16fef

How To Send Emails Using Cloud Functions, Firestore & Firebase-Send-Email

A Guide to Cloud Functions, Firestore, and Firebase-Send-Email

blog.canopas.com





오늘의 이야기

Visual SVN에서 변경 이력 및 내역 확인하기 svn 동기화 CMD 창에서 변경 이력 확인 Visual SVN의 변경 이력을 CMD 창에서 확인하려면   svn log   명령어를 사용합니다. 예를 ...