https://school.programmers.co.kr/learn/courses/30/lessons/12901
— 문제 설명
2016년 1월 1일은 금요일입니다. 2016년 a월 b일은 무슨 요일일까요? 두 수 a ,b를 입력받아 2016년 a월 b일이 무슨 요일인지 리턴하는 함수, solution을 완성하세요. 요일의 이름은 일요일부터 토요일까지 각각 SUN,MON,TUE,WED,THU,FRI,SAT
입니다. 예를 들어 a=5, b=24라면 5월 24일은 화요일이므로 문자열 "TUE"를 반환하세요.
— 제한 조건
— 입출력 예
| a | b | result |
|---|---|---|
| 5 | 24 | "TUE" |
— 문제 풀이
import java.time.*;
class Solution {
public String solution(int a, int b) {
LocalDate start = LocalDate.of(2016,1,1);
LocalDate end = LocalDate.of(2016,a,b);
long diff = Duration.between(start.atStartOfDay(),end.atStartOfDay()).toDays();
Week[] days = Week.values();
return days[(5+((int)diff%7))%7].name();
}
public enum Week {
SUN,MON,TUE,WED,THU,FRI,SAT
}
}
https://school.programmers.co.kr/learn/courses/30/lessons/159994
— 문제 설명
코니는 영어 단어가 적힌 카드 뭉치 두 개를 선물로 받았습니다. 코니는 다음과 같은 규칙으로 카드에 적힌 단어들을 사용해 원하는 순서의 단어 배열을 만들 수 있는지 알고 싶습니다.
예를 들어 첫 번째 카드 뭉치에 순서대로 ["i", "drink", "water"], 두 번째 카드 뭉치에 순서대로 ["want", "to"]가 적혀있을 때 ["i", "want", "to", "drink", "water"] 순서의 단어 배열을 만들려고 한다면 첫 번째 카드 뭉치에서 "i"를 사용한 후 두 번째 카드 뭉치에서 "want"와 "to"를 사용하고 첫 번째 카드뭉치에 "drink"와 "water"를 차례대로 사용하면 원하는 순서의 단어 배열을 만들 수 있습니다.
문자열로 이루어진 배열 cards1, cards2와 원하는 단어 배열 goal이 매개변수로 주어질 때, cards1과 cards2에 적힌 단어들로 goal를 만들 있다면 "Yes"를, 만들 수 없다면 "No"를 return하는 solution 함수를 완성해주세요.
— 제한 조건
cards1의 길이, cards2의 길이 ≤ 10cards1[i]의 길이, cards2[i]의 길이 ≤ 10cards1과 cards2에는 서로 다른 단어만 존재합니다.goal의 길이 ≤ cards1의 길이 + cards2의 길이goal[i]의 길이 ≤ 10goal의 원소는 cards1과 cards2의 원소들로만 이루어져 있습니다.cards1, cards2, goal의 문자열들은 모두 알파벳 소문자로만 이루어져 있습니다.— 입출력 예
| cards1 | cards2 | goal | result |
|---|---|---|---|
| ["i", "drink", "water"] | ["want", "to"] | ["i", "want", "to", "drink", "water"] | "Yes" |
| ["i", "water", "drink"] | ["want", "to"] | ["i", "want", "to", "drink", "water"] | "No" |
입출력 예 #1
본문과 같습니다.
입출력 예 #2
cards1에서 "i"를 사용하고 cards2에서 "want"와 "to"를 사용하여 "i want to"까지는 만들 수 있지만 "water"가 "drink"보다 먼저 사용되어야 하기 때문에 해당 문장을 완성시킬 수 없습니다. 따라서 "No"를 반환합니다.
— 문제 풀이
class Solution {
public boolean[] selected1, selected2;
public String solution(String[] cards1, String[] cards2, String[] goal) {
selected1 = new boolean[cards1.length];
selected2 = new boolean[cards2.length];
String[] cards = new String[goal.length];
if(cal(cards1, cards2, goal, cards, 0))return "Yes";
return "No";
}
public boolean cal(String[] cards1, String[] cards2, String[] goal, String[] cards, int cnt){
if(cnt==goal.length) return true;
for(int i=0;i<cards1.length;i++){
if(i>0&&!selected1[i-1]) break;
if(!selected1[i] && goal[cnt].equals(cards1[i])) {
selected1[i] = true;
if(cal(cards1, cards2, goal, cards, cnt+1)) return true;
}
}
for(int i=0;i<cards2.length;i++){
if(i>0&&!selected2[i-1]) break;
if(!selected2[i] && goal[cnt].equals(cards2[i])) {
selected2[i] = true;
if(cal(cards1, cards2, goal, cards, cnt+1)) return true;
}
}
return false;
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}spring:
application:
name: redis
data:
redis:
host: localhost
port: 6379
password: {설정한 password 없으면 X}@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
//Entity 대신 RedisHash
@RedisHash("item")
public class Item implements Serializable {
@Id
private Long id;
private String name;
private String description;
private Integer price;
}public interface ItemRepository extends CrudRepository<Item, Long> {
}@SpringBootTest
public class RedisRepositoryTests {
@Autowired
private ItemRepository itemRepository;
@Test
@DisplayName("Redis 생성 테스트")
public void createTest(){
Item item = Item.builder()
.id(1L)
.name("keyboard")
.description("Very Expensive Keyboard")
.price(1000000)
.build();
itemRepository.save(item);
}
@Test
@DisplayName("Redis 단건 조회 테스트")
public void findOneTest(){
Item item = itemRepository.findById(1L)
.orElseThrow(RuntimeException::new);
System.out.println(item.getDescription());
}
@Test
@DisplayName("Redis 업데이트 테스트")
public void updateTest(){
Item item = itemRepository.findById(1L)
.orElseThrow(RuntimeException::new);
item.setDescription("On Sales!!!");
item = itemRepository.save(item);
System.out.println(item.getDescription());
}
@Test
@DisplayName("Redis 삭제 테스트")
public void deleteTest(){
itemRepository.deleteById(1L);
assertThrows(NoSuchElementException.class, () -> {
Item item = itemRepository.findById(1L).orElseThrow();
});
}
}@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
//Entity 대신 RedisHash
@RedisHash("item")
public class Item implements Serializable {
@Id
private String id;
private String name;
private String description;
private Integer price;
}
public interface ItemRepository extends CrudRepository<Item, String> {
}@Getter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ItemDto implements Serializable {
private String name;
private String description;
private Integer price;
}
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, ItemDto> itemRedisTemplate(
RedisConnectionFactory redisConnectionFactory
){
RedisTemplate<String, ItemDto> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(RedisSerializer.json());
return template;
}
}
@SpringBootTest
public class RedisTemplateTests {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void stringOpsTest(){
//문자열 조작을 위한 클래스
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
ops.set("simplekey", "simplevalue");
System.out.println(ops.get("simplekey"));
// 집합을 조작하기 위한 클래스
SetOperations<String, String> setOps = stringRedisTemplate.opsForSet();
setOps.add("hobbies", "games");
setOps.add("hobbies", "coding", "alchohol", "games");
System.out.println(setOps.size("hobbies"));
stringRedisTemplate.expire("hobbies", 10, TimeUnit.SECONDS);
stringRedisTemplate.delete("simplekey");
}
@Autowired
private RedisTemplate<String, ItemDto> itemRedisTemplate;
@Test
public void itemRedisTemplateTest(){
ValueOperations<String, ItemDto> ops
= itemRedisTemplate.opsForValue();
ops.set("my:keyboard", ItemDto.builder()
.name("Mechanical Keyboard")
.price(250000)
.description("OMG")
.build());
System.out.println(ops.get("my:keyboard"));
}
}
블로그 URL Path 는 /articles/{id}
로그인 여부와 상관없이 새로고침 될때마다 조회수가 하나 증가
INCR articles:id
GET articles:id
# incr articles:1
# get articles:1
블로그 URL Path 는 /articles/{id}
로그인 한 사람들의 계정은 영문으로만 이뤄져 있음
-- 로그인한 사람들이 오늘 조회한 수
sadd articles:2:20240806 alex
scard articles:2:20240806
-- 가장 많은 조회수를 기록한 글
zincrby articles:ranks 1 articles:1
zrange articles:ranks 0 -1 withscores
zrevrange articles:ranks 0 -1 withscores
ItemOrder 클래스를 RedisHash 로 만들고@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@RedisHash("order")
public class Order {
@Id
private String id;
private String item;
private Integer count;
private Long totalPrice;
private String status;
}
public interface OrderRepository extends CrudRepository<Order, String> {
}@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderRepository orderRepository;
public OrderController(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@PostMapping
public Order createOrder(@RequestBody Order request){
return orderRepository.save(request);
}
@GetMapping
public List<Order> getAllOrders(){
List<Order> orders = new ArrayList<>();
orderRepository.findAll()
.forEach(orders::add);
return orders;
}
@PutMapping("/{id}")
Order updateOrder(@PathVariable String id, @RequestBody Order request){
Order order = orderRepository.findById(id)
.orElseThrow(()-> {
return new HttpClientErrorException(HttpStatus.NOT_FOUND, "주문 정보가 없습니다.");
});
order.setItem(request.getItem());
order.setCount(request.getCount());
order.setTotalPrice(request.getTotalPrice());
order.setStatus(request.getStatus());
return orderRepository.save(order);
}
@DeleteMapping("/{id}")
String deleteOrder(@PathVariable String id){
orderRepository.deleteById(id);
return id + " Order is deleted.";
}
}
@Bean
public RedisTemplate<String, Integer> articleTemplate(
RedisConnectionFactory redisConnectionFactory
) {
RedisTemplate<String, Integer> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
return template;
}
@Bean
public RedisTemplate<String, String> articleUserTemplate(
RedisConnectionFactory redisConnectionFactory
) {
RedisTemplate<String, String> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(RedisSerializer.string());
return template;
}@RestController
@RequestMapping("/articles")
public class ArticleController {
private final ValueOperations<String, Integer> ops;
private final ZSetOperations<String, String> zOps;
public ArticleController(RedisTemplate<String, Integer> articleTemplate,
RedisTemplate<String,String> articleUserTemplate) {
ops = articleTemplate.opsForValue();
zOps = articleUserTemplate.opsForZSet();
}
@GetMapping("{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void read(@PathVariable Long id) {
ops.increment("articles:%d".formatted(id));
zOps.incrementScore("articles:rank", "articles:%d".formatted(id), 1);
}
@GetMapping("/rank")
public Set<ZSetOperations.TypedTuple<String>> getRanks(){
return zOps.reverseRangeWithScores("articles:rank", 0, -1);
}
}dev 와 prod 로 분리spring:
profiles:
default: dev # 실행 옵션에 profile 지정이 없으면 dev로 실행
application:
name: auth-service
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
show_sql: true
use_sql_comments: true
highlight_sql: true
server:
port: 19095
service:
jwt:
access-expiration: 3600000
secret-key: "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429080fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1"
spring:
config:
activate:
on-profile: dev
datasource:
url: jdbc:mysql://localhost:3306/msa_exam
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
eureka:
client:
service-url:
defaultZone: http://localhost:19090/eureka/spring:
config:
activate:
on-profile: prod
datasource:
url: jdbc:mysql://{RDS URL}:3306/{RDS DB명}
username: admin
password: # VM Option으로 Password 입력
driver-class-name: com.mysql.cj.jdbc.Driver
eureka:
client:
service-url:
defaultZone: # VM Option으로 eureka 서버 url 입력org.springframework.beans.factory.annotation.Value@Value("${server.port}")
private int serverPort;ResponseEntity.status(HttpStatus.OK)
.header("Server-Port", String.valueOf(serverPort))
.body(res);