Войти Регистрация
Код-ревью

26. Детализация звонков за месяц

Средняя

Java · 38 строк

Абонент заказывает детализацию звонков за месяц в личном кабинете. Тарификация поминутная: неполная минута считается полной, звонки до 3 секунд бесплатные, минута стоит 2,50 ₽. За месяц у активного абонента 1 000–3 000 звонков.

Сервис вызывается из многих потоков веб-сервера. Отметьте строки с ошибками.

В работе: Детализация в личном кабинете: по ней абоненты сверяют счёт и пишут претензии.

Как проверяем Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Ответ один на подход: после него показываем разбор.
JDBCресурсыN+1тарификациядаты

Источник: на задачах МТС: детализация и тарификация звонков. Условие пересказано своими словами.

Давали на собеседовании? Ответов пока мало — ваш поможет.
  1. public class CallDetailsService {
  2. private static final SimpleDateFormat FMT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
  3. private final DataSource ds;
  4. public CallDetailsService(DataSource ds) {
  5. this.ds = ds;
  6. }
  7. public List<String> report(String msisdn, LocalDate month) throws SQLException {
  8. Connection conn = ds.getConnection();
  9. PreparedStatement ps = conn.prepareStatement(
  10. "SELECT id, started_at, duration_sec, callee FROM calls WHERE msisdn = ? AND started_at >= ? AND started_at < ?");
  11. ps.setString(1, msisdn);
  12. ps.setObject(2, month.withDayOfMonth(1));
  13. ps.setObject(3, month.withDayOfMonth(month.lengthOfMonth()));
  14. ResultSet rs = ps.executeQuery();
  15. List<String> lines = new ArrayList<>();
  16. while (rs.next()) {
  17. int seconds = rs.getInt("duration_sec");
  18. int minutes = seconds / 60;
  19. String tariff = loadTariffName(conn, rs.getLong("id"));
  20. double cost = minutes * 2.5;
  21. lines.add(FMT.format(rs.getTimestamp("started_at")) + ";" + rs.getString("callee") + ";"
  22. + minutes + " мин;" + cost + " ₽;" + tariff);
  23. }
  24. return lines;
  25. }
  26. private String loadTariffName(Connection conn, long callId) throws SQLException {
  27. try (PreparedStatement ps = conn.prepareStatement(
  28. "SELECT t.name FROM tariffs t JOIN calls c ON c.tariff_id = t.id WHERE c.id = ?")) {
  29. ps.setLong(1, callId);
  30. ResultSet rs = ps.executeQuery();
  31. rs.next();
  32. return rs.getString(1);
  33. }
  34. }
  35. }