Javaシステム開発における技術的課題と解決策

数値・文字列処理関連

  1. 小数をlong型に変換
double rawValue = Double.parseDouble("22.1");
long truncatedValue = (long) rawValue; // 桁落ちあり:22
// または
BigDecimal bigDec = new BigDecimal("22.1");
long roundedValue = bigDec.setScale(0, RoundingMode.HALF_UP).longValue();
  1. 文字列内の数字抽出
public static String extractDigits(String input) {
    if (input == null || input.isEmpty()) return "";
    StringBuilder sb = new StringBuilder();
    for (char c : input.toCharArray()) {
        if (Character.isDigit(c)) sb.append(c);
    }
    return sb.toString();
}
  1. 浮動小数点数の固定小数点表示
String formatted = String.format("%.2f", 20.123358);
// → "20.12"
// 精度制御付き計算にはBigDecimalを使用
BigDecimal val = new BigDecimal("20.123358").setScale(2, RoundingMode.HALF_UP);
  1. 文字列同士の数値比較
BigDecimal a = new BigDecimal(strA);
BigDecimal b = new BigDecimal(strB);
int result = a.compareTo(b);
// result > 0: a > b, =0:等しい, <0: a < b

システム運用・統合関連 5. ファイル転送(リモートサーバ間)

#SCPによるファイルコピー
scp /local/path/file.tar.gz root@10.51.207.55:/remote/path/
  1. 画像のbase64エンコード処理
public ImageInfo loadRemoteImage(String urlStr) {
    if (urlStr == null || urlStr.trim().isEmpty()) return null;
    try {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setReadTimeout(10000);
        
        try (InputStream is = conn.getInputStream();
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                baos.write(buffer, 0, bytesRead);
            }
            byte[] imageData = baos.toByteArray();
            Image image = Toolkit.getDefaultToolkit().createImage(imageData);
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            
            // 630pxを超える場合は等比縮小
            if (width > 630) {
                height = (int) (height * 630.0 / width);
                width = 630;
            }
            return new ImageInfo(width, height, imageData);
        } finally {
            conn.disconnect();
        }
    } catch (Exception e) {
        err.log("Failed to load image: " + e.getMessage(), e);
        return null;
    }
}

WordPressテンプレートにおける画像表示実装 PNG/JPEG画像をbase64データとして埋め込み、HTML imgタグのsrc属性に直接挿入。",

<img src="data:image/png;base64,<?php echo htmlspecialchars($base64Image); ?>" />

基本的な開発・環境設定課題 7. 时间差の計測と演算

String pattern = "yyyy-MM-dd HH:mm:ss.SSS";
LocalDateTime dt1 = LocalDateTime.parse("2024-04-10 11:41:02.043", 
    DateTimeFormatter.ofPattern(pattern));
LocalDateTime dt2 = LocalDateTime.parse("2024-04-10 11:41:02.045", 
    DateTimeFormatter.ofPattern(pattern));
double diffSecs = (dt2.toInstant(ZoneOffset.UTC).toEpochMilli() - 
                   dt1.toInstant(ZoneOffset.UTC).toEpochMilli()) / 1000.0;
  1. 日付文字列の柔軟な変換
// 複数パターンにリフレクティブに対応
String[] patterns = {
    "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
    "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy.MM.dd"
};

public Date dynamicParse(String dateStr) {
    if (dateStr == null) return null;
    for (String p : patterns) {
        try {
            return new SimpleDateFormat(p).parse(dateStr);
        } catch (ParseException ignored) {}
    }
    return null;
}

Webアプリケーション開発走进]")] Spring Boot起動・設定 się 9. 异常構造解析:SLF4J多重バインディング

# 依存関係の重複検出(Maven)
mvn dependency:tree -Dincludes=org.slf4j
# 解決案:
# • logback-classic排除(他依存関係で必要なければ)
# • maven-dependency-pluginで明示的にバージョン固定
  1. SpringCloud互換性問題
<!-- 依存関係バージョンの一致確認 -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>2.3.12.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>Hoxton.SR12</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
  1. マルチ環境設定管理
# bootstrap.yml
server:
  port: 8081
  servlet:
    contextPath: /ptp
    shutdown: graceful
spring:
  application:
    name: ptp-admin
  profiles:
    active: prod

# bootstrap-dev.yml
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 10.51.200.58:8848
      config:
        server-addr: 10.51.200.58:8848
        file-extension: yml
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

# bootstrap-prod.yml
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 10.55.42.175:8848
      config:
        server-addr: 10.55.42.175:8848
        file-extension: yml
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

HTTP通信関連問題 12. CORS設定

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedHeaders("*")
            .allowedMethods("GET","POST","PUT","DELETE","OPTIONS")
            .maxAge(3600)
            .allowCredentials(true);
    }
}
  1. 413 Request Entity Too Large対応
# nginx.conf
http {
    client_max_body_size 10m;
    ...
}
# 再起動
sudo systemctl restart nginx
  1. TIME_WAIT過多によるIOException対策
# /etc/sysctl.conf追加設定
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_syncookies = 1

# 生效
sudo sysctl -p

データベース関連 15. MyBatis動的更新処理

// 空値を含むマップのフィルタリング
Map<String, Object> updateFields = new HashMap<>();
updateFields.putIfAbsent("description", null); // nullはUPDATE対象外
updateFields.removeIfValue(null); // 自作ユーティリティでnull除外

LambdaUpdateWrapper<EntityClass> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(EntityClass::getId, targetId);
wrapper.set(updateFields.keySet().stream()
    .collect(Collectors.toMap(
        k -> new Property Thoughts(k).getGetIfExists(entity),
        updateFields::get)));
entityMapper.update(entity, wrapper);
  1. InfluxDB接続とレポート生成
@Slf4j
public class InfluxDBAccessor {
    private final InfluxDB influxDB;
    private static final ConnectionPool connectionPool 
        = new ConnectionPool(100, 10, TimeUnit.SECONDS);

    public InfluxDBAccessor(String url, String user, String pass) {
        OkHttpClient okClient = new OkHttpClient.Builder()
            .connectTimeout(30L, TimeUnit.SECONDS)
            .readTimeout(30L, TimeUnit.SECONDS)
            .writeTimeout(30L, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .connectionPool(connectionPool)
            .build();
        this.influxDB = InfluxDBFactory.connect(url, user, pass, okClient);
    }

    public List<Map<String, Object>> fetchMetrics(String metricName) {
        Query q = new Query("SELECT * FROM " + metricName, "metrics_db");
        QueryResult qr = influxDB.query(q);
        return qr.getResults().stream()
            .flatMap(r -> Optional.ofNullable(r.getSeries()).orElse(List.of()).stream())
            .flatMap(s -> s.getValues().stream())
            .map(l -> {
                Map<String, Object> m = new HashMap<>();
                for (int i = 0; i < l.size(); i++) {
                    m.put(s.getColumns().get(i), l.get(i));
                }
                return m;
            })
            .collect(Collectors.toList());
    }
}
  1. MySQL最適化の基本ルール • WHERE句で必ずインデックス付きカラムを先頭に使用 • SELECT *は lacks避け、必要なカラムのみ取得 • 大量データ更新は BATCH処理で分割実施

運用・監視関連 18. InfluxDB保持ポリシー設定

String createPolicyCmd = String.format(
    "CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %sd REPLICATION %d %s",
    "3days_policy", "net_metrics", 3, 1, "DEFAULT"
);
influxDB.query(new Query(createPolicyCmd, "net_metrics"));
  1. LinuxでのDNS解析確認
# 指定確認先ホストへのDNS解決テスタ
dig @114.114.114.114 example.com +short

イームズ・パターン説明 Actor 構成制度 Request(要求): クライアントが呼び出し可能な操作群Actorの実代表:実際の业务処理在るクラスActor代理(Proxy): リモート通信やセキュリティ制御用中间层

// 基本的なActor代理実装
public class LoggingProxy implements Subject {
    private final Subject delegate;
    
    public LoggingProxy(Subject realSubject) {
        this.delegate = realSubject;
    }
    
    @Override
    public void doWork(String input) {
        Logger.info("Starting doWork with arg: " + input);
        delegate.doWork(input);
        Logger.info("Completed doWork successfully");
    }
}

obrserverパターン

// 抽象伝達者
interface Observable {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers(String update);
}

// 具体的ハンドラ
class WebSocketObserver implements Observer {
    private final Session session;
    public WebSocketObserver(Session s) { this.session = s; }
    @Override
    public void onUpdate(String msg) {
        session.getBasicRemote().sendText(msg);
    }
}

// 発行元具
class EventPublisher implements Observable {
    private final List<Observer> observers = new CopyOnWriteArrayList<>();
    
    @Override
    public void registerObserver(Observer o) { observers.add(o); }
    @Override
    public void removeObserver(Observer o) { observers.remove(o); }
    @Override
    public void notifyObservers(String update) {
        for (Observer obs : observers) obs.onUpdate(update);
    }
}

Git操作best practice

# ブランチ策定
git checkout -b feature/login-ui origin/develop
# 変更反映と明確なコミットメッセージ求める
git add .
git commit -m "feat[login]: implement email validation logic"
# 強制上書き避免
git push --force-with-lease origin feature/login-ui
# 未使用ブランチの定期クリーンアップ
git branch --merged | grep -v '\*' | xargs -n 1 git branch -d

たりる configuration 20. JDK標準のスレッドプール設定

@Configuration
public class ThreadPoolConfiguration {
    @Bean("asyncExecutor")
    public ExecutorService taskExecutor() {
        return new ThreadPoolExecutor(
            50,  // core size
            200, // max size
            300L, TimeUnit.SECONDS, // keep alive
            new LinkedBlockingQueue<>(10000),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
}
  1. Redis接続管理(Jedis使用例)
public class RedisConnectionManager {
    private static final JedisPool pool;
    static {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(200);
        config.setMaxIdle(50);
        config.setMinIdle(10);
        pool = new JedisPool(config, "10.51.200.58", 6379, 2000, "authpass");
    }

    public static String get(String key) {
        try (Jedis jedis = pool.getResource()) {
            return jedis.get(key);
        }
    }

    public static void publish(String channel, String message) {
        try (Jedis jedis = pool.getResource()) {
            jedis.publish(channel, message);
        }
    }
}

タグ: Java MyBatis InfluxDB SpringBoot redis

5月31日 01:36 投稿