쪽지발송 성공
Click here
재능넷 이용방법
재능넷 이용방법 동영상편
가입인사 이벤트
판매 수수료 안내
안전거래 TIP
재능인 인증서 발급안내

🌲 지식인의 숲 🌲

🌳 디자인
🌳 음악/영상
🌳 문서작성
🌳 번역/외국어
🌳 프로그램개발
🌳 마케팅/비즈니스
🌳 생활서비스
🌳 철학
🌳 과학
🌳 수학
🌳 역사
해당 지식과 관련있는 인기재능

* 프로그램에 대한 분석과 설계 구현.(OA,FA 등)* 업무 프로세스에 의한 구현.(C/C++, C#​) * 기존의 C/C++, C#, MFC, VB로 이루어진 프로그...

AS규정기본적으로 A/S 는 평생 가능합니다. *. 구매자의 요청으로 수정 및 보완이 필요한 경우 일정 금액의 수고비를 상호 협의하에 요청 할수 있...

  1.엑셀의 기본기능으로 하기 어렵거나 복잡한 내용 VBA로 자동화 2.셀메뉴형태 또는 리본메뉴형태의 프로그램 3.MY-SQ...

30년간 직장 생활을 하고 정년 퇴직을 하였습니다.퇴직 후 재능넷 수행 내용은 쇼핑몰/학원/판매점 등 관리 프로그램 및 데이터 ...

Java Agent와 ByteBuddy를 이용한 런타임 코드 조작

2024-09-25 22:45:52

재능넷
조회수 339 댓글수 0

🚀 Java Agent와 ByteBuddy로 떠나는 코드 조작 여행! 🎢

 

 

안녕하세요, 여러분! 오늘은 정말 흥미진진한 주제로 여러분을 찾아왔어요. 바로 'Java Agent와 ByteBuddy를 이용한 런타임 코드 조작'에 대해 알아볼 거예요. 😎 이게 뭐냐고요? 간단히 말해서, 실행 중인 Java 프로그램의 코드를 마법처럼 바꿀 수 있는 초강력 기술이에요!

여러분, 혹시 프로그램을 실행하다가 "아, 이 부분만 좀 바꿀 수 있다면..."이라고 생각해본 적 있나요? Java Agent와 ByteBuddy를 사용하면 그 꿈을 이룰 수 있어요! 마치 요술봉을 휘두르듯 코드를 변경할 수 있답니다. 🧙‍♂️✨

이 기술은 정말 대단해요. 버그를 수정하거나, 성능을 개선하거나, 심지어 전혀 새로운 기능을 추가할 수도 있죠. 마치 재능넷에서 다양한 재능을 거래하듯이, 우리도 코드의 재능을 마음대로 바꿀 수 있는 거예요!

자, 그럼 이제 본격적으로 Java Agent와 ByteBuddy의 세계로 빠져볼까요? 준비되셨나요? let's go! 🏃‍♂️💨

🧐 Java Agent란 무엇일까요?

Java Agent는 마치 비밀요원처럼 Java 애플리케이션에 잠입해서 코드를 감시하고 수정하는 특별한 프로그램이에요. 어떻게 동작하는지 간단히 살펴볼까요?

Java Agent 동작 원리 Java Agent 클래스 로딩 메서드 실행 코드 분석 코드 변경

Java Agent는 다음과 같은 특징을 가지고 있어요:

  • 👀 감시자: 클래스가 로딩될 때 이를 감지합니다.
  • 🔍 분석가: 로딩된 클래스의 바이트코드를 분석합니다.
  • ✏️ 편집자: 필요한 경우 바이트코드를 수정합니다.
  • 🔄 중개자: 수정된 바이트코드를 JVM에 전달합니다.

Java Agent를 사용하면 프로그램의 동작을 실시간으로 모니터링하고 수정할 수 있어요. 마치 프로그램의 DNA를 실시간으로 조작하는 것과 같죠! 🧬

💡 재능넷 Tip: Java Agent는 프로그래밍 실력을 한 단계 업그레이드시킬 수 있는 강력한 도구예요. 마치 재능넷에서 새로운 재능을 습득하는 것처럼, Java Agent를 마스터하면 여러분의 개발 능력이 크게 향상될 거예요!

🎭 ByteBuddy: 코드 변환의 마법사

ByteBuddy는 Java Agent와 함께 사용되는 강력한 라이브러리예요. 이 녀석은 정말 대단해요! 마치 코드의 마법사처럼 Java 바이트코드를 자유자재로 조작할 수 있게 해주죠. 😮

ByteBuddy의 마법 원본 코드 변환된 코드 ByteBuddy ✨ 마법의 변환 ✨

ByteBuddy를 사용하면 다음과 같은 놀라운 일들을 할 수 있어요:

  • 🏗️ 새로운 클래스 생성: 완전히 새로운 클래스를 동적으로 만들 수 있어요.
  • 🔧 기존 클래스 수정: 이미 존재하는 클래스의 동작을 변경할 수 있죠.
  • 🎨 메서드 재정의: 원하는 대로 메서드의 동작을 바꿀 수 있어요.
  • 🔌 인터셉터 추가: 메서드 호출을 가로채고 추가 동작을 삽입할 수 있죠.

ByteBuddy는 정말 강력하지만, 동시에 사용하기 쉽게 설계되어 있어요. 복잡한 바이트코드 조작을 간단한 API 호출로 할 수 있답니다. 👍

🚨 주의사항: ByteBuddy의 힘은 대단하지만, 큰 힘에는 큰 책임이 따르죠! 코드를 변경할 때는 항상 신중해야 해요. 잘못하면 예상치 못한 버그가 발생할 수 있으니까요. 😱

자, 이제 ByteBuddy의 기본을 알았으니, 실제로 어떻게 사용하는지 살펴볼까요? 🕵️‍♂️

🛠️ Java Agent와 ByteBuddy 시작하기

자, 이제 실제로 Java Agent와 ByteBuddy를 사용해볼 거예요. 준비되셨나요? 차근차근 따라와 보세요! 👣

1. 프로젝트 설정

먼저, Maven이나 Gradle 프로젝트에 ByteBuddy 의존성을 추가해야 해요. Maven을 사용한다면 pom.xml에 다음을 추가하세요:


<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy</artifactId>
    <version>1.12.13</version>
</dependency>
<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy-agent</artifactId>
    <version>1.12.13</version>
</dependency>

2. Java Agent 클래스 만들기

이제 Java Agent 클래스를 만들어볼게요. 이 클래스는 프로그램이 시작될 때 실행되며, ByteBuddy를 사용해 클래스를 변환할 거예요.


import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.instrument.Instrumentation;

public class MyAgent {
    public static void premain(String arguments, Instrumentation instrumentation) {
        new AgentBuilder.Default()
            .type(ElementMatchers.nameEndsWith("TargetClass"))
            .transform((builder, type, classLoader, module) -> 
                builder.method(ElementMatchers.named("targetMethod"))
                       .intercept(MethodDelegation.to(MyInterceptor.class))
            ).installOn(instrumentation);
    }
}

와우! 😲 이 코드가 하는 일을 간단히 설명해드릴게요:

  • 🎯 타겟 설정: "TargetClass"로 끝나는 이름의 클래스를 찾아요.
  • 🔍 메서드 선택: "targetMethod"라는 이름의 메서드를 선택해요.
  • 🔄 인터셉터 설정: 선택한 메서드에 MyInterceptor 클래스의 로직을 적용해요.

3. 인터셉터 만들기

이제 실제로 메서드 호출을 가로채고 새로운 동작을 추가할 인터셉터를 만들어볼게요.


import net.bytebuddy.implementation.bind.annotation.*;

public class MyInterceptor {
    @RuntimeType
    public static Object intercept(@Origin Method method, @AllArguments Object[] args, @SuperCall Callable<?> zuper) throws Throwable {
        System.out.println("Method " + method.getName() + " was called!");
        long start = System.currentTimeMillis();
        try {
            return zuper.call();
        } finally {
            System.out.println("Method execution took " + (System.currentTimeMillis() - start) + " ms.");
        }
    }
}

이 인터셉터는 정말 멋진 일을 해요! 👏

  • 📢 메서드 호출 알림: 메서드가 호출될 때마다 메시지를 출력해요.
  • ⏱️ 실행 시간 측정: 메서드의 실행 시간을 측정하고 출력해요.
  • 🔄 원래 메서드 실행: 원래의 메서드 로직도 그대로 실행해요.

💡 Tip: 이런 방식으로 성능 모니터링, 로깅, 보안 검사 등 다양한 기능을 기존 코드를 변경하지 않고도 추가할 수 있어요!

자, 이제 기본적인 설정은 끝났어요. 다음 단계에서는 이 Agent를 실제로 사용하는 방법을 알아볼게요! 🚀

🏃‍♂️ Java Agent 실행하기

자, 이제 우리가 만든 Java Agent를 실제로 실행해볼 시간이에요! 어떻게 하는지 함께 알아볼까요? 🤔

1. Agent JAR 파일 만들기

먼저, 우리의 Agent 클래스를 JAR 파일로 패키징해야 해요. 이때 MANIFEST.MF 파일에 다음 내용을 추가해야 해요:


Manifest-Version: 1.0
Premain-Class: com.example.MyAgent
Can-Redefine-Classes: true
Can-Retransform-Classes: true

이 MANIFEST 파일은 JVM에게 우리의 Agent 클래스가 어디 있는지, 그리고 어떤 기능을 사용할 수 있는지 알려주는 역할을 해요. 📝

2. 애플리케이션 실행하기

이제 우리의 Agent를 사용해 애플리케이션을 실행할 차례예요! 다음과 같은 명령어를 사용하면 돼요:


java -javaagent:path/to/my-agent.jar -jar my-application.jar

이 명령어는 JVM에게 "Hey, 이 Agent를 사용해서 애플리케이션을 실행해줘!"라고 말하는 거예요. 😉

Java Agent 실행 과정 Java Agent Application 변환 실행

3. 결과 확인하기

자, 이제 애플리케이션이 실행되면서 우리가 설정한 Agent가 동작하기 시작할 거예요. 콘솔 출력을 확인해보세요:


Method targetMethod was called!
... (원래 메서드의 출력)
Method execution took 42 ms.

짜잔! 🎉 우리의 Agent가 성공적으로 동작하고 있어요. 메서드 호출을 감지하고, 실행 시간도 측정했네요!

🚨 주의: Java Agent는 애플리케이션의 동작을 크게 바꿀 수 있어요. 실제 운영 환경에서 사용할 때는 충분한 테스트를 거쳐야 해요!

여기까지 Java Agent와 ByteBuddy를 사용해 런타임에 코드를 조작하는 기본적인 방법을 알아봤어요. 이제 여러분도 코드의 마법사가 된 것 같지 않나요? ✨🧙‍♂️

다음 섹션에서는 더 복잡한 예제와 실제 사용 사례를 살펴볼 거예요. 계속 따라와 주세요! 🚶‍♂️🚶‍♀️

🎭 고급 ByteBuddy 기법

자, 이제 ByteBuddy의 더 강력한 기능들을 살펴볼 시간이에요! 준비되셨나요? 😃

1. 메서드 추가하기

ByteBuddy를 사용하면 기존 클래스에 새로운 메서드를 추가할 수 있어요. 마치 레고 블록을 끼워 맞추듯이요! 🧱


new ByteBuddy()
  .redefine(TargetClass.class)
  .method(named("toString"))
  .intercept(FixedValue.value("Hello, ByteBuddy!"))
  .make()
  .load(TargetClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

이 코드는 TargetClass의 toString() 메서드를 가로채서 항상 "Hello, ByteBuddy!"를 반환하도록 만들어요. 신기하죠? 😲

2. 필드 추가하기

클래스에 새로운 필드를 추가하는 것도 가능해요. 마치 마법처럼 클래스에 새로운 특성을 부여하는 거죠! 🧙‍♂️


new ByteBuddy()
  .redefine(TargetClass.class)
  .defineField("newField", String.class, Visibility.PRIVATE)
  .make()
  .load(TargetClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

이렇게 하면 TargetClass에 "newField"라는 이름의 private String 필드가 추가돼요.

3. 메서드 위임하기

메서드 호출을 다른 클래스로 위임할 수도 있어요. 마치 일을 다른 사람에게 맡기는 것처럼요! 👥


new ByteBuddy()
  .redefine(TargetClass.class)
  .method(named("targetMethod"))
  .intercept(MethodDelegation.to(HelperClass.class))
  .make()
  .load(TargetClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

이 코드는 TargetClass의 targetMethod() 호출을 HelperClass의 메서드로 위임해요.

ByteBuddy 고급 기법 ByteBuddy 메서드 추가 필드 추가 메서드 위임 동적 타입 생성

4. 동적으로 타입 생성하기

ByteBuddy를 사용하면 완전히 새로운 클래스를 동적으로 생성할 수 있어요. 마치 새로운 생명체를 창조하는 것 같죠? 🧬


Class> dynamicType = new ByteBuddy()
  .subclass(Object.class)
  .name("com.example.DynamicClass")
  .defineMethod("dynamicMethod", String.class, Visibility.PUBLIC)
  .intercept(FixedValue.value("Hello from dynamic method!"))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded();

이 코드는 "DynamicClass"라는 이름의 새로운 클래스를 생성하고, "dynamicMethod"라는 메서드를 추가해요.

💡 Tip: 이런 동적 타입 생성은 프록시 객체를 만들거나, 런타임에 새로운 기능을 추가할 때 유용해요. 마치 재능넷에서 새로운 재능을 즉석에서 만들어내는 것처럼요!

와우! 이제 여러분은 ByteBuddy의 고급 기능들을 알게 되었어요. 이 도구들을 사용하면 정말 놀라운 일들을 할 수 있죠. 여러분의 상상력이 곧 한계예요! 🚀✨

다음 섹션에서는 이런 기술들을 실제로 어떻게 활용할 수 있는지 몇 가지 사례를 통해 알아볼게요. 기대되지 않나요? 😉

🌟 실제 사용 사례

자, 이제 우리가 배운 Java Agent와 ByteBuddy를 실제로 어떻게 활용할 수 있는지 몇 가지 흥미로운 사례를 살펴볼게요! 😃

1. 성능 모니터링 🕵️‍♂️

애플리케이션의 성능을 실시간으로 모니터링하고 싶다고 상상해보세요. Java Agent와 ByteBuddy를 사용하면 이런 꿈을 쉽게 이룰 수 있어요!


@RuntimeType
public static Object intercept(@Origin Method method, @SuperCall Callable<?> zuper) throws Throwable {
    long start = System.nanoTime();
    try {
        return zuper.call();
    } finally {
        long duration = System.nanoTime() - start;
        System.out.printf("Method %s took %d ns%n", method.getName(), duration);
    }
}

이 인터셉터를 사용하면 모든 메서드의 실행 시간을 나노초 단위로 측정할 수 있어요. 마치 초고속 카메라로 코드의 움직임을 촬영하는 것 같죠? 📸

2. 로깅 강화 📝

애플리케이션의 로깅을 강화하고 싶으신가요? ByteBuddy를 사용하면 기존 코드를 변경하지 않고도 로깅을 추가할 수 있어요!


@RuntimeType
public static Object intercept(@Origin Method method, @AllArguments Object[] args, @SuperCall Callable<?> zuper) throws Throwable {
    System.out.printf("Entering method %s with arguments %s%n", method.getName(), Arrays.toString(args));
    try {
        Object result = zuper.call();
        System.out.printf("Exiting method %s with result %s%n", method.getName(), result);
        return result;
    } catch (Throwable t) {
        System.out.printf("Method %s threw exception: %s%n", method.getName(), t.getMessage());
        throw t;
    }
}

이 코드를 이 코드를 사용하면 모든 메서드의 진입과 종료, 그리고 예외 발생 상황을 자세히 로깅할 수 있어요. 마치 모든 방에 CCTV를 설치하는 것과 같죠! 📹

3. 보안 검사 🔒

애플리케이션의 보안을 강화하고 싶으신가요? ByteBuddy를 사용하면 중요한 메서드에 보안 검사를 쉽게 추가할 수 있어요.


@RuntimeType
public static Object intercept(@Origin Method method, @SuperCall Callable<?> zuper) throws Throwable {
    if (!SecurityManager.isAuthorized()) {
        throw new SecurityException("Unauthorized access to method " + method.getName());
    }
    return zuper.call();
}

이 코드는 메서드 실행 전에 보안 검사를 수행해요. 마치 건물의 모든 출입구에 보안 요원을 배치하는 것과 같죠! 💂‍♂️

4. 캐싱 구현 🚀

자주 호출되는 메서드의 결과를 캐싱하고 싶으신가요? ByteBuddy를 사용하면 간단히 구현할 수 있어요!


private static Map<String, Object> cache = new ConcurrentHashMap<>();

@RuntimeType
public static Object intercept(@Origin Method method, @AllArguments Object[] args, @SuperCall Callable<?> zuper) throws Throwable {
    String key = method.getName() + Arrays.toString(args);
    if (cache.containsKey(key)) {
        return cache.get(key);
    }
    Object result = zuper.call();
    cache.put(key, result);
    return result;
}

이 코드는 메서드의 결과를 캐시에 저장하고, 동일한 인자로 다시 호출될 때 캐시된 결과를 반환해요. 마치 자주 가는 길에 지름길을 만드는 것과 같죠! 🛣️

Java Agent 활용 사례 Java Agent 성능 모니터링 로깅 강화 보안 검사 캐싱 구현

5. 동적 프록시 생성 🎭

런타임에 동적으로 프록시 객체를 생성하고 싶으신가요? ByteBuddy를 사용하면 쉽게 구현할 수 있어요!


Class<?> proxyClass = new ByteBuddy()
    .subclass(TargetClass.class)
    .method(ElementMatchers.any())
    .intercept(InvocationHandlerAdapter.of((proxy, method, args) -> {
        System.out.println("Before method: " + method.getName());
        Object result = method.invoke(targetObject, args);
        System.out.println("After method: " + method.getName());
        return result;
    }))
    .make()
    .load(TargetClass.class.getClassLoader())
    .getLoaded();

TargetClass proxy = (TargetClass) proxyClass.getDeclaredConstructor().newInstance();

이 코드는 TargetClass의 모든 메서드를 가로채는 프록시 클래스를 동적으로 생성해요. 마치 배우가 다른 사람의 역할을 완벽하게 연기하는 것과 같죠! 🎭

💡 재능넷 Tip: 이런 동적 프록시 기술은 AOP(Aspect-Oriented Programming)를 구현할 때 매우 유용해요. 여러분의 프로그래밍 재능을 한 단계 업그레이드할 수 있는 좋은 기회죠!

자, 여기까지 Java Agent와 ByteBuddy의 실제 활용 사례들을 살펴봤어요. 이 기술들을 사용하면 정말 다양한 일들을 할 수 있죠? 여러분의 상상력이 곧 한계예요! 🚀

이제 여러분은 Java Agent와 ByteBuddy의 강력한 힘을 알게 되었어요. 이 도구들을 활용해 여러분만의 창의적인 솔루션을 만들어보는 건 어떨까요? 새로운 재능을 발견하는 것처럼 흥미진진할 거예요! 😉

🎓 마무리: Java Agent와 ByteBuddy 마스터하기

와우! 정말 긴 여정이었죠? 여러분은 이제 Java Agent와 ByteBuddy의 세계를 탐험했어요. 마치 새로운 대륙을 발견한 탐험가처럼 느껴지지 않나요? 🧭🌎

우리가 함께 배운 내용을 간단히 정리해볼까요?

  1. 🕵️‍♂️ Java Agent: JVM에 장착되어 클래스 로딩 시점에 바이트코드를 조작할 수 있는 강력한 도구
  2. 🧙‍♂️ ByteBuddy: 바이트코드 조작을 쉽고 직관적으로 할 수 있게 해주는 마법 같은 라이브러리
  3. 🛠️ 실제 활용: 성능 모니터링, 로깅 강화, 보안 검사, 캐싱 구현, 동적 프록시 생성 등 다양한 분야에서 활용 가능

이 기술들을 마스터하면, 여러분은 마치 코드의 연금술사가 된 것 같은 느낌을 받을 거예요. 기존 코드를 건드리지 않고도 새로운 기능을 추가하고, 동작을 변경하고, 성능을 개선할 수 있으니까요! 🧪✨

Java Agent와 ByteBuddy 마스터 Java Agent + ByteBuddy 코드 변환의 마법 무한한 가능성

하지만 기억하세요. 큰 힘에는 큰 책임이 따르죠! 😉

🚨 주의사항: Java Agent와 ByteBuddy는 매우 강력한 도구이지만, 잘못 사용하면 예상치 못한 버그나 성능 저하를 일으킬 수 있어요. 항상 충분한 테스트와 주의가 필요해요!

여러분, 이제 Java Agent와 ByteBuddy라는 새로운 재능을 얻었어요. 마치 재능넷에서 새로운 기술을 배운 것처럼요! 🎓 이 재능을 어떻게 활용하실 건가요? 성능 최적화? 보안 강화? 아니면 완전히 새로운 프레임워크 개발? 가능성은 무한해요!

코딩의 세계는 끊임없이 진화하고 있어요. Java Agent와 ByteBuddy는 그 진화의 최전선에 있는 도구들이죠. 이 도구들을 마스터함으로써, 여러분은 그 진화의 주역이 될 수 있어요. 🦸‍♂️🦸‍♀️

자, 이제 여러분만의 코드 마법을 펼칠 시간이에요. 여러분의 상상력과 창의력으로 Java의 새로운 장을 열어보세요. 코딩의 즐거움과 함께 멋진 모험이 여러분을 기다리고 있을 거예요! 🚀🌟

행운을 빕니다, 코드의 마법사들이여! 다음에 또 다른 흥미진진한 주제로 만나요! 👋😊

관련 키워드

  • Java Agent
  • ByteBuddy
  • 런타임 코드 조작
  • 바이트코드 조작
  • 동적 프록시
  • 성능 모니터링
  • 로깅 강화
  • 보안 검사
  • 캐싱 구현
  • AOP

지식의 가치와 지적 재산권 보호

자유 결제 서비스

'지식인의 숲'은 "이용자 자유 결제 서비스"를 통해 지식의 가치를 공유합니다. 콘텐츠를 경험하신 후, 아래 안내에 따라 자유롭게 결제해 주세요.

자유 결제 : 국민은행 420401-04-167940 (주)재능넷
결제금액: 귀하가 받은 가치만큼 자유롭게 결정해 주세요
결제기간: 기한 없이 언제든 편한 시기에 결제 가능합니다

지적 재산권 보호 고지

  1. 저작권 및 소유권: 본 컨텐츠는 재능넷의 독점 AI 기술로 생성되었으며, 대한민국 저작권법 및 국제 저작권 협약에 의해 보호됩니다.
  2. AI 생성 컨텐츠의 법적 지위: 본 AI 생성 컨텐츠는 재능넷의 지적 창작물로 인정되며, 관련 법규에 따라 저작권 보호를 받습니다.
  3. 사용 제한: 재능넷의 명시적 서면 동의 없이 본 컨텐츠를 복제, 수정, 배포, 또는 상업적으로 활용하는 행위는 엄격히 금지됩니다.
  4. 데이터 수집 금지: 본 컨텐츠에 대한 무단 스크래핑, 크롤링, 및 자동화된 데이터 수집은 법적 제재의 대상이 됩니다.
  5. AI 학습 제한: 재능넷의 AI 생성 컨텐츠를 타 AI 모델 학습에 무단 사용하는 행위는 금지되며, 이는 지적 재산권 침해로 간주됩니다.

재능넷은 최신 AI 기술과 법률에 기반하여 자사의 지적 재산권을 적극적으로 보호하며,
무단 사용 및 침해 행위에 대해 법적 대응을 할 권리를 보유합니다.

© 2024 재능넷 | All rights reserved.

댓글 작성
0/2000

댓글 0개

해당 지식과 관련있는 인기재능

개인용도의 프로그램이나 소규모 프로그램을 합리적인 가격으로 제작해드립니다.개발 아이디어가 있으시다면 부담 갖지 마시고 문의해주세요. ...

안녕하세요!!!고객님이 상상하시는 작업물 그 이상을 작업해 드리려 노력합니다.저는 작업물을 완성하여 고객님에게 보내드리는 것으로 거래 완료...

#### 결재 먼저 하지 마시고 쪽지 먼저 주세요. ######## 결재 먼저 하지 마시고 쪽지 먼저 주세요. ####안녕하세요. C/C++/MFC/C#/Python 프...

땡큐엑셀-신차장기렌트카 비교견적기 엑셀 프로그램신차장기렌트 가격비교 비교견적 엑셀 프로그램을 통해 제휴사의 월렌트료및 잔가를 한번의 클...

📚 생성된 총 지식 7,792 개

  • (주)재능넷 | 대표 : 강정수 | 경기도 수원시 영통구 봉영로 1612, 7층 710-09 호 (영통동) | 사업자등록번호 : 131-86-65451
    통신판매업신고 : 2018-수원영통-0307 | 직업정보제공사업 신고번호 : 중부청 2013-4호 | jaenung@jaenung.net

    (주)재능넷의 사전 서면 동의 없이 재능넷사이트의 일체의 정보, 콘텐츠 및 UI등을 상업적 목적으로 전재, 전송, 스크래핑 등 무단 사용할 수 없습니다.
    (주)재능넷은 통신판매중개자로서 재능넷의 거래당사자가 아니며, 판매자가 등록한 상품정보 및 거래에 대해 재능넷은 일체 책임을 지지 않습니다.

    Copyright © 2024 재능넷 Inc. All rights reserved.
ICT Innovation 대상
미래창조과학부장관 표창
서울특별시
공유기업 지정
한국데이터베이스진흥원
콘텐츠 제공서비스 품질인증
대한민국 중소 중견기업
혁신대상 중소기업청장상
인터넷에코어워드
일자리창출 분야 대상
웹어워드코리아
인터넷 서비스분야 우수상
정보통신산업진흥원장
정부유공 표창장
미래창조과학부
ICT지원사업 선정
기술혁신
벤처기업 확인
기술개발
기업부설 연구소 인정
마이크로소프트
BizsPark 스타트업
대한민국 미래경영대상
재능마켓 부문 수상
대한민국 중소기업인 대회
중소기업중앙회장 표창
국회 중소벤처기업위원회
위원장 표창